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