Skip to main content

ConfluxSet

Struct ConfluxSet 

Source
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: TunnelId

The 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: UniqId

The 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: V1Nonce

The nonce associated with the circuits from this set.

§desired_ux: V1DesiredUx

The 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: bool

Whether we have selected our initial primary leg, if this is a multipath conflux set.

Implementations§

Source§

impl ConfluxSet

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub(super) fn leg(&self, leg_id: UniqId) -> Option<&Circuit>

Return a reference to the leg of this conflux set with the given id.

Source

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.

Source

pub(super) fn len(&self) -> usize

Return the number of legs in this conflux set.

Source

pub(super) fn is_empty(&self) -> bool

Return whether this conflux set is empty.

Source

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
  • leg is 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.

Source

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.

Source

fn max_last_seq_recv(&self) -> Option<u64>

Return the maximum relative last_seq_recv across all circuits.

Source

fn max_last_seq_sent(&self) -> Option<u64>

Return the maximum relative last_seq_sent across all circuits.

Source

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.

Source

fn circuits(&self) -> impl Iterator<Item = &Circuit>

Return an iterator of all circuits in the conflux set.

Source

pub(super) fn tunnel_activity(&self) -> TunnelActivity

Return the most active TunnelActivity for any leg of this ConfluxSet.

Source

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.

Source

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.

Source

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.

Source

fn should_update_primary_leg(&mut self) -> bool

Whether it’s time to select a new primary leg.

Source

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.

Source

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.

Source

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.

Source

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.

Source

fn should_skip_join_point(&self) -> Result<bool, Bug>

Returns whether next_circ_event should avoid polling the join point streams entirely.

Source

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.

Source

pub(super) fn primary_join_point(&self) -> Option<(UniqId, HopNum)>

The join point on the current primary leg.

Source

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.

Source

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.

See Circuit::send_relay_cell.

Send a LINK cell down each unlinked leg.

Source

pub(super) fn num_unlinked(&self) -> usize

Get the number of unlinked or non-conflux legs.

Source

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.

Source

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.

Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts 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>

Converts 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)

Converts &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)

Converts &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
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows 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
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows 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
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> PossiblyOption<T> for T

Source§

fn to_option(self) -> Option<T>

Convert this object into an Option<T>
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .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
where Self: BorrowMut<B>, B: ?Sized,

Calls .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
where Self: AsRef<R>, R: ?Sized,

Calls .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
where Self: AsMut<R>, R: ?Sized,

Calls .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
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more