pub(super) struct ConfluxSet {
tunnel_id: TunnelId,
legs: SmallVec<[Circuit; 16]>,
mutable: Arc<TunnelMutableState>,
primary_id: UniqId,
join_point: Option<JoinPoint>,
nonce: V1Nonce,
desired_ux: V1DesiredUx,
last_seq_delivered: Arc<AtomicU64>,
selected_init_primary: bool,
}Expand description
A set with one or more circuits.
§Conflux set life cycle
Conflux sets are created by the reactor using ConfluxSet::new.
Every ConfluxSet starts out as a single-path set consisting of a single 0-length circuit.
After constructing a ConfluxSet, the reactor will proceed to extend its (only) circuit.
At this point, the ConfluxSet will be a single-path set with a single n-length circuit.
The reactor can then turn the ConfluxSet into a multi-path set
(a multi-path set is a conflux set that contains more than 1 circuit).
This is done using ConfluxSet::add_legs, in response to a CtrlMsg sent
by the reactor user (also referred to as the “conflux handshake initiator”).
After that, the conflux set is said to be a multi-path set with multiple N-length circuits.
Circuits can be removed from the set using ConfluxSet::remove.
The lifetime of a ConfluxSet is tied to the lifetime of the reactor.
When the reactor is dropped, its underlying ConfluxSet is dropped too.
This can happen on an explicit shutdown request, or if a fatal error occurs.
Conversely, the ConfluxSet can also trigger a reactor shutdown.
For example, if after being instructed to remove a circuit from the set
using ConfluxSet::remove, the set is completely depleted,
the ConfluxSet will return a ReactorError::Shutdown error,
which will cause the reactor to shut down.
Fields§
§tunnel_id: TunnelIdThe unique identifier of the tunnel this conflux set belongs to.
Used for setting the internal TunnelId of Circuits
that gets used for logging purposes.
legs: SmallVec<[Circuit; 16]>The circuits in this conflux set.
mutable: Arc<TunnelMutableState>Tunnel state, shared with ClientCirc.
Contains the MutableState of each circuit in the set.
primary_id: UniqIdThe unique identifier of the primary leg
join_point: Option<JoinPoint>The join point of the set, if this is a multi-path set.
Initially the conflux set starts out as a single-path set with no join point.
When it is converted to a multipath set using add_legs,
the join point is initialized to the last hop in the tunnel.
nonce: V1NonceThe nonce associated with the circuits from this set.
desired_ux: V1DesiredUxThe desired UX
last_seq_delivered: Arc<AtomicU64>The absolute sequence number of the last cell delivered to a stream.
A clone of this is shared with each ConfluxMsgHandler created.
When a message is received on a circuit leg, the ConfluxMsgHandler
of the leg compares the (leg-local) sequence number of the message
with this sequence number to determine whether the message is in-order.
If the message is in-order, the ConfluxMsgHandler instructs the circuit
to deliver it to its corresponding stream.
If the message is out-of-order, the ConfluxMsgHandler instructs the circuit
to instruct the reactor to buffer the message.
selected_init_primary: boolWhether we have selected our initial primary leg, if this is a multipath conflux set.
Implementations§
Source§impl ConfluxSet
impl ConfluxSet
Sourcepub(super) fn new(
tunnel_id: TunnelId,
circuit_leg: Circuit,
) -> (Self, Arc<TunnelMutableState>)
pub(super) fn new( tunnel_id: TunnelId, circuit_leg: Circuit, ) -> (Self, Arc<TunnelMutableState>)
Create a new conflux set, consisting of a single leg.
Returns the newly created set and a reference to its TunnelMutableState.
Sourcepub(super) fn take_single_leg(&mut self) -> Result<Circuit, Bug>
pub(super) fn take_single_leg(&mut self) -> Result<Circuit, Bug>
Remove and return the only leg of this conflux set.
Returns an error if there is more than one leg in the set, or if called before any circuit legs are available.
Calling this function will empty the ConfluxSet.
Sourcepub(super) fn single_leg(&self) -> Result<&Circuit, NotSingleLegError>
pub(super) fn single_leg(&self) -> Result<&Circuit, NotSingleLegError>
Return a reference to the only leg of this conflux set, along with the leg’s ID.
Returns an error if there is more than one leg in the set, or if called before any circuit legs are available.
Sourcepub(super) fn single_leg_mut(
&mut self,
) -> Result<&mut Circuit, NotSingleLegError>
pub(super) fn single_leg_mut( &mut self, ) -> Result<&mut Circuit, NotSingleLegError>
Return a mutable reference to the only leg of this conflux set, along with the leg’s ID.
Returns an error if there is more than one leg in the set, or if called before any circuit legs are available.
Sourcepub(super) fn primary_leg_mut(&mut self) -> Result<&mut Circuit, Bug>
pub(super) fn primary_leg_mut(&mut self) -> Result<&mut Circuit, Bug>
Return the primary leg of this conflux set.
Returns an error if called before any circuit legs are available.
Sourcepub(super) fn leg(&self, leg_id: UniqId) -> Option<&Circuit>
pub(super) fn leg(&self, leg_id: UniqId) -> Option<&Circuit>
Return a reference to the leg of this conflux set with the given id.
Sourcepub(super) fn leg_mut(&mut self, leg_id: UniqId) -> Option<&mut Circuit>
pub(super) fn leg_mut(&mut self, leg_id: UniqId) -> Option<&mut Circuit>
Return a mutable reference to the leg of this conflux set with the given id.
Sourcepub(super) fn remove(&mut self, leg: UniqId) -> Result<Circuit, ReactorError>
pub(super) fn remove(&mut self, leg: UniqId) -> Result<Circuit, ReactorError>
Remove the specified leg from this conflux set.
Returns an error if the given leg doesn’t exist in the set.
Returns an error instructing the reactor to perform a clean shutdown
(ReactorError::Shutdown), tearing down the entire ConfluxSet, if
- the set is depleted (empty) after removing the specified leg
legis currently the sending (primary) leg of this set- the closed leg had the highest non-zero last_seq_recv/sent
- the closed leg had some in-progress data (inflight > cc_sendme_inc)
We do not yet support resumption. See 2.4.3. Closing circuits in prop329.
Sourcefn remove_conflux(&self, circ: Circuit) -> Result<Circuit, ReactorError>
fn remove_conflux(&self, circ: Circuit) -> Result<Circuit, ReactorError>
Handle the removal of a circuit, returning an error if the reactor needs to shut down.
Sourcefn max_last_seq_recv(&self) -> Option<u64>
fn max_last_seq_recv(&self) -> Option<u64>
Return the maximum relative last_seq_recv across all circuits.
Sourcefn max_last_seq_sent(&self) -> Option<u64>
fn max_last_seq_sent(&self) -> Option<u64>
Return the maximum relative last_seq_sent across all circuits.
Sourcefn join_point_hop<'c>(&self, circ: &'c Circuit) -> Result<&'c CircHop, Bug>
fn join_point_hop<'c>(&self, circ: &'c Circuit) -> Result<&'c CircHop, Bug>
Get the CircHop of the join point on the specified circ,
returning an error if this is a single path conflux set.
Sourcefn circuits(&self) -> impl Iterator<Item = &Circuit>
fn circuits(&self) -> impl Iterator<Item = &Circuit>
Return an iterator of all circuits in the conflux set.
Sourcepub(super) fn tunnel_activity(&self) -> TunnelActivity
pub(super) fn tunnel_activity(&self) -> TunnelActivity
Return the most active TunnelActivity for any leg of this ConfluxSet.
Sourcepub(super) fn add_legs(
&mut self,
legs: Vec<Circuit>,
runtime: &DynTimeProvider,
) -> Result<(), Bug>
pub(super) fn add_legs( &mut self, legs: Vec<Circuit>, runtime: &DynTimeProvider, ) -> Result<(), Bug>
Add legs to the this conflux set.
Returns an error if any of the legs is invalid.
A leg is considered valid if
- the circuit has the same length as all the other circuits in the set
- its last hop is equal to the designated join point
- the circuit has no streams attached to any of its hops
- the circuit is not already part of a conflux set
Note: the circuits will not begin linking until
link_circuits is called.
IMPORTANT: this function does not prevent the construction of conflux sets where the circuit legs share guard or middle relays. It is the responsibility of the caller to enforce the following invariant from prop354:
“If building a conflux leg: Reject any circuits that have the same Guard as the other conflux “leg(s) in the current conflux set, EXCEPT when one of the primary Guards is also the chosen “Exit of this conflux set (in which case, re-use the non-Exit Guard).”
This is because at this level we don’t actually know which relays are the guards, so we can’t know if the join point happens to be one of the Guard + Exit relays.
Sourcefn cwnd_params(&self) -> Result<CongestionWindowParams, Bug>
fn cwnd_params(&self) -> Result<CongestionWindowParams, Bug>
Get the CongestionWindowParams of the join point
on the first leg.
Returns an error if the congestion control algorithm doesn’t have a congestion control window object, or if the conflux set is empty, or the joint point hop does not exist.
Sourcepub(super) fn maybe_update_primary_leg(
&mut self,
) -> Result<Option<SendRelayCell>>
pub(super) fn maybe_update_primary_leg( &mut self, ) -> Result<Option<SendRelayCell>>
Try to update the primary leg based on the configured desired UX, if needed.
Returns the SWITCH cell to send on the primary leg, if we switched primary leg.
Sourcefn should_update_primary_leg(&mut self) -> bool
fn should_update_primary_leg(&mut self) -> bool
Whether it’s time to select a new primary leg.
Sourcefn select_primary_leg(&self) -> Result<Option<UniqId>, Bug>
fn select_primary_leg(&self) -> Result<Option<UniqId>, Bug>
Return the best leg according to the configured desired UX.
Returns None if no suitable leg was found.
Sourcefn maybe_select_init_primary(&mut self)
fn maybe_select_init_primary(&mut self)
Try to choose an initial primary leg, if we have an initial RTT measurement for at least one of the legs.
Sourcefn select_primary_leg_min_rtt(
&self,
check_can_send: bool,
) -> Result<Option<UniqId>, Bug>
fn select_primary_leg_min_rtt( &self, check_can_send: bool, ) -> Result<Option<UniqId>, Bug>
Return the leg with the best (lowest) RTT.
If check_can_send is true, selects the lowest RTT leg that is ready to send.
Returns None if no suitable leg was found.
Sourcefn is_join_point_blocked_on_cc(
join_hop: HopNum,
circuit: &Circuit,
) -> Result<bool, Bug>
fn is_join_point_blocked_on_cc( join_hop: HopNum, circuit: &Circuit, ) -> Result<bool, Bug>
Returns true if our conflux join point is blocked on congestion control
on the specified circuit.
Returns false if the join point is not blocked on cc,
or if this is a single-path set.
Returns an error if this is a multipath tunnel, but the joint point hop doesn’t exist on the specified circuit.
Sourcefn should_skip_join_point(&self) -> Result<bool, Bug>
fn should_skip_join_point(&self) -> Result<bool, Bug>
Returns whether next_circ_event
should avoid polling the join point streams entirely.
Sourcepub(super) async fn next_circ_event(
&mut self,
runtime: &DynTimeProvider,
) -> Result<SmallVec<[CircuitEvent; 32]>, Error>
pub(super) async fn next_circ_event( &mut self, runtime: &DynTimeProvider, ) -> Result<SmallVec<[CircuitEvent; 32]>, Error>
Returns the next ready CircuitEvent,
obtained from processing the incoming/outgoing messages on all the circuits in this set.
Will return an error if there are no circuits in this set, or other internal errors occur.
This is cancellation-safe.
Sourcepub(super) fn primary_join_point(&self) -> Option<(UniqId, HopNum)>
pub(super) fn primary_join_point(&self) -> Option<(UniqId, HopNum)>
The join point on the current primary leg.
Sourcepub(super) fn uses_stream_sendme(
&self,
leg: UniqId,
hop: HopNum,
) -> Option<bool>
pub(super) fn uses_stream_sendme( &self, leg: UniqId, hop: HopNum, ) -> Option<bool>
Does congestion control use stream SENDMEs for the given hop?
Returns None if either the leg or hop don’t exist.
Sourcepub(super) async fn send_relay_cell_on_leg(
&mut self,
msg: SendRelayCell,
leg: Option<UniqId>,
) -> Result<()>
pub(super) async fn send_relay_cell_on_leg( &mut self, msg: SendRelayCell, leg: Option<UniqId>, ) -> Result<()>
Encode msg, encrypt it, and send it to the ’hop’th hop.
Sourcepub(super) async fn link_circuits(
&mut self,
runtime: &DynTimeProvider,
) -> Result<()>
pub(super) async fn link_circuits( &mut self, runtime: &DynTimeProvider, ) -> Result<()>
Send a LINK cell down each unlinked leg.
Sourcepub(super) fn num_unlinked(&self) -> usize
pub(super) fn num_unlinked(&self) -> usize
Get the number of unlinked or non-conflux legs.
Sourcepub(super) fn is_seqno_in_order(&self, seq_recv: u64) -> bool
pub(super) fn is_seqno_in_order(&self, seq_recv: u64) -> bool
Check if the specified sequence number is the sequence number of the next message we’re expecting to handle.
Sourcefn remove_unchecked(&mut self, circ_id: UniqId) -> Result<Circuit, Bug>
fn remove_unchecked(&mut self, circ_id: UniqId) -> Result<Circuit, Bug>
Remove the circuit leg with the specified UniqId from this conflux set.
Unlike ConfluxSet::remove, this function does not check
if the removal of the leg ought to trigger a reactor shutdown.
Returns an error if the leg doesn’t exit in the conflux set.
Sourcepub(super) async fn run_padding_event(
&mut self,
circ_id: UniqId,
padding_event: PaddingEvent,
) -> Result<()>
pub(super) async fn run_padding_event( &mut self, circ_id: UniqId, padding_event: PaddingEvent, ) -> Result<()>
Perform some circuit-padding-based event on the specified circuit.
Auto Trait Implementations§
impl Freeze for ConfluxSet
impl !RefUnwindSafe for ConfluxSet
impl Send for ConfluxSet
impl !Sync for ConfluxSet
impl Unpin for ConfluxSet
impl UnsafeUnpin for ConfluxSet
impl !UnwindSafe for ConfluxSet
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> PossiblyOption<T> for T
impl<T> PossiblyOption<T> for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.