Skip to main content

tor_proto/
circuit.rs

1//! Circuit-related types and helpers.
2//!
3//! This code is shared between the client and relay implementations.
4
5pub(crate) mod cell_sender;
6pub(crate) mod celltypes;
7pub(crate) mod circ_sender;
8pub(crate) mod circhop;
9pub(crate) mod create;
10pub(crate) mod padding;
11pub(crate) mod reactor;
12pub(crate) mod syncview;
13pub(crate) mod unique_id;
14
15pub use crate::memquota::StreamAccount;
16pub use syncview::CircHopSyncView;
17pub use unique_id::UniqId;
18
19use crate::ccparams::CongestionControlParams;
20use crate::stream::flow_ctrl::params::FlowCtrlParameters;
21
22pub(crate) use circ_sender::{CircuitRxReceiver, CircuitRxSender};
23
24/// Estimated upper bound for the likely number of hops.
25pub(crate) const HOPS: usize = 6;
26
27/// Description of the network's current rules for building circuits.
28///
29/// This type describes rules derived from the consensus,
30/// and possibly amended by our own configuration.
31///
32/// Typically, this type created once for an entire circuit,
33/// and any special per-hop information is derived
34/// from each hop as a CircTarget.
35/// Note however that callers _may_ provide different `CircParameters`
36/// for different hops within a circuit if they have some reason to do so,
37/// so we do not enforce that every hop in a circuit has the same `CircParameters`.
38#[non_exhaustive]
39#[derive(Clone, Debug)]
40pub struct CircParameters {
41    /// Whether we should include ed25519 identities when we send
42    /// EXTEND2 cells.
43    pub extend_by_ed25519_id: bool,
44    /// Congestion control parameters for this circuit.
45    pub ccontrol: CongestionControlParams,
46
47    /// Flow control parameters to use for all streams on this circuit.
48    // While flow control is a stream property and not a circuit property,
49    // and it may seem better to pass the flow control parameters to for example `begin_stream()`,
50    // it's included in [`CircParameters`] for the following reasons:
51    //
52    // - When endpoints (exits + hs) receive new stream requests, they need the flow control
53    //   parameters immediately. It would be easy to pass flow control parameters when creating a
54    //   stream, but it's not as easy to get flow control parameters when receiving a new stream
55    //   request, unless those parameters are already available to the circuit (like
56    //   `CircParameters` are).
57    // - It's unclear if new streams on existing circuits should switch to new flow control
58    //   parameters if the consensus changes. This behaviour doesn't appear to be specified. It
59    //   might also leak information to the circuit's endpoint about when we downloaded new
60    //   directory documents. So it seems best to stick with the same flow control parameters for
61    //   the lifetime of the circuit.
62    // - It doesn't belong in [`StreamParameters`] as `StreamParameters` is a set of preferences
63    //   with defaults, and consensus parameters aren't preferences and don't have defaults.
64    //   (Technically they have defaults, but `StreamParameters` isn't the place to set them.)
65    pub flow_ctrl: FlowCtrlParameters,
66
67    /// Maximum number of permitted incoming relay cells for each hop.
68    ///
69    /// If we would receive more relay cells than this from a single hop,
70    /// we close the circuit with [`ExcessInboundCells`](crate::Error::ExcessInboundCells).
71    ///
72    /// If this value is None, then there is no limit to the number of inbound cells.
73    ///
74    /// Known limitation: If this value if `u32::MAX`,
75    /// then a limit of `u32::MAX - 1` is enforced.
76    pub n_incoming_cells_permitted: Option<u32>,
77
78    /// Maximum number of permitted outgoing relay cells for each hop.
79    ///
80    /// If we would try to send more relay cells than this from a single hop,
81    /// we close the circuit with [`ExcessOutboundCells`](crate::Error::ExcessOutboundCells).
82    /// It is the circuit-user's responsibility to make sure that this does not happen.
83    ///
84    /// This setting is used to ensure that we do not violate a limit
85    /// imposed by `n_incoming_cells_permitted`
86    /// on the other side of a circuit.
87    ///
88    /// If this value is None, then there is no limit to the number of outbound cells.
89    ///
90    /// Known limitation: If this value if `u32::MAX`,
91    /// then a limit of `u32::MAX - 1` is enforced.
92    pub n_outgoing_cells_permitted: Option<u32>,
93}
94
95tor_protover::subprotocol_restricted_set! {
96    /// The enabled/disabled status of subprotocols that are allowed to be requested through a
97    /// subprotocol request during a circuit handshake.
98    ///
99    /// The allowed subprotocols are defined in:
100    /// <https://spec.torproject.org/tor-spec/create-created-cells.html#subproto-request>
101    #[derive(Copy, Clone, Debug, Default)]
102    pub(crate) struct HandshakeSubprotocols {
103        RELAY_CRYPT_CGO,
104    }
105}
106
107#[cfg(test)]
108pub(crate) mod test {
109    #[cfg(feature = "relay")]
110    use crate::relay::{CircNetParameters, CongestionControlNetParams};
111
112    pub(crate) use super::circ_sender::test::fake_mpsc;
113
114    /// Return a new [`CircNetParameters`] using default values for unit tests. They are based on
115    /// consensus defaults but should not be considered to be accurate from the one used on the
116    /// production network.
117    #[cfg(feature = "relay")]
118    pub(crate) fn new_circ_net_params() -> CircNetParameters {
119        CircNetParameters {
120            cc: CongestionControlNetParams::defaults_for_tests(),
121        }
122    }
123}