Struct tor_circmgr::mgr::AbstractCircMgr

source ·
pub(crate) struct AbstractCircMgr<B: AbstractCircBuilder, R: Runtime> {
    builder: B,
    runtime: R,
    circs: Mutex<CircList<B>>,
    circuit_timing: MutCfg<CircuitTiming>,
    unused_timing: Mutex<UnusedTimings>,
}
Expand description

Abstract implementation for circuit management.

The algorithm provided here is fairly simple. In its simplest form:

When somebody asks for a circuit for a given operation: if we find one open already, we return it. If we find in-progress circuits that would meet our needs, we wait for one to finish (or for all to fail). And otherwise, we launch one or more circuits to meet the request’s needs.

If this process fails, then we retry it, up to a timeout or a numerical limit.

If a circuit not previously considered for a given request finishes before the request is satisfied, and if the circuit would satisfy the request, we try to give that circuit as an answer to that request even if it was not one of the circuits that request was waiting for.

Fields§

§builder: B

Builder used to construct circuits.

§runtime: R

An asynchronous runtime to use for launching tasks and checking timeouts.

§circs: Mutex<CircList<B>>

A CircList to manage our list of circuits, requests, and pending circuits.

§circuit_timing: MutCfg<CircuitTiming>

Configured information about when to expire circuits and requests.

§unused_timing: Mutex<UnusedTimings>

Minimum lifetime of an unused circuit.

Derived from the network parameters.

Implementations§

source§

impl<B: AbstractCircBuilder + 'static, R: Runtime> AbstractCircMgr<B, R>

source

pub(crate) fn new(builder: B, runtime: R, circuit_timing: CircuitTiming) -> Self

Construct a new AbstractCircMgr.

source

pub(crate) fn update_network_parameters(&self, p: &NetParameters)

Reconfigure this manager using the latest set of network parameters.

source

pub(crate) fn circuit_timing(&self) -> Arc<CircuitTiming>

Return this manager’s CircuitTiming.

source

pub(crate) fn set_circuit_timing(&self, new_config: CircuitTiming)

Return this manager’s CircuitTiming.

source

pub(crate) async fn get_or_launch( self: &Arc<Self>, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_> ) -> Result<(Arc<B::Circ>, CircProvenance)>

Return a circuit suitable for use with a given usage, creating that circuit if necessary, and restricting it under the assumption that it will be used for that spec.

This is the primary entry point for AbstractCircMgr.

source

pub(crate) async fn ensure_circuit( self: &Arc<Self>, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_> ) -> Result<()>

Make sure a circuit exists, without actually asking for it.

Make sure that there is a circuit (built or in-progress) that could be used for usage, and launch one or more circuits in a background task if there is not.

source

fn prepare_action( &self, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_>, restrict_circ: bool ) -> Result<Action<B>>

Choose which action we should take in order to provide a circuit for a given usage.

If restrict_circ is true, we restrict the spec of any circ we decide to use to mark that it is being used for usage.

source

async fn take_action( self: Arc<Self>, act: Action<B>, usage: &<B::Spec as AbstractSpec>::Usage ) -> Result<(Arc<B::Circ>, CircProvenance), RetryError<Box<Error>>>

Execute an action returned by pick-action, and return the resulting circuit or error.

source

fn plan_by_usage( &self, dir: DirInfo<'_>, usage: &<B::Spec as AbstractSpec>::Usage ) -> Result<(Arc<PendingEntry<B>>, CircBuildPlan<B>)>

Given a directory and usage, compute the necessary objects to build a circuit: A PendingEntry to keep track of the in-process circuit, and a CircBuildPlan that we’ll give to the thread that will build the circuit.

The caller should probably add the resulting PendingEntry to self.circs.

This is an internal function that we call when we’re pretty sure we want to build a circuit.

source

pub(crate) fn launch_by_usage( self: &Arc<Self>, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_> ) -> Result<Shared<Receiver<Result<<<B as AbstractCircBuilder>::Circ as AbstractCirc>::Id>>>>

Launch a managed circuit for a target usage, without checking whether one already exists or is pending.

Return a listener that will be informed when the circuit is done.

source

fn spawn_launch( self: Arc<Self>, usage: &<B::Spec as AbstractSpec>::Usage, plan: CircBuildPlan<B> ) -> Shared<Receiver<Result<<<B as AbstractCircBuilder>::Circ as AbstractCirc>::Id>>>

Spawn a background task to launch a circuit, and report its status.

The usage argument is the usage from the original request that made us build this circuit.

source

async fn do_launch( self: Arc<Self>, plan: <B as AbstractCircBuilder>::Plan, pending: Arc<PendingEntry<B>> ) -> (Option<<B as AbstractCircBuilder>::Spec>, Result<<<B as AbstractCircBuilder>::Circ as AbstractCirc>::Id>)

Run in the background to launch a circuit. Return a 2-tuple of the new circuit spec and the outcome that should be sent to the initiator.

source

pub(crate) async fn launch_unmanaged( &self, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_> ) -> Result<(<B as AbstractCircBuilder>::Spec, Arc<B::Circ>)>

Available on crate feature hs-common only.

Plan and launch a new circuit to a given target, bypassing our managed pool of circuits.

This method will always return a new circuit, and never return a circuit that this CircMgr gives out for anything else.

The new circuit will participate in the guard and timeout apparatus as appropriate, no retry attempt will be made if the circuit fails.

source

pub(crate) fn take_circ( &self, id: &<B::Circ as AbstractCirc>::Id ) -> Option<Arc<B::Circ>>

Remove the circuit with a given id from this manager.

After this function is called, that circuit will no longer be handed out to any future requests.

Return None if we have no circuit with the given ID.

source

pub(crate) fn retire_all_circuits(&self)

Remove all open and pending circuits and from this manager, to ensure they can’t be given out for any more requests.

Calling retire_all_circuits ensures that any circuit request that gets an answer after this method runs will receive a circuit that was launched after this method runs.

We call this method this when our configuration changes in such a way that we want to make sure that any new (or pending) requests will receive circuits that are built using the new configuration.

source

pub(crate) fn expire_circs(&self, now: Instant)

Expire circuits according to the rules in config and the current time now.

Expired circuits will not be automatically closed, but they will no longer be given out for new circuits.

source

pub(crate) fn expire_circ( &self, circ_id: &<B::Circ as AbstractCirc>::Id, now: Instant )

Consider expiring the circuit with given circuit id, according to the rules in config and the current time now.

source

pub(crate) fn n_circs(&self) -> usize

Return the number of open circuits held by this circuit manager.

source

pub(crate) fn peek_runtime(&self) -> &R

Get a reference to this manager’s runtime.

source

pub(crate) fn peek_builder(&self) -> &B

Get a reference to this manager’s builder.

source

fn pick_use_duration(&self) -> Duration

Pick a duration by when a new circuit should expire from now if it has not yet been used

Auto Trait Implementations§

§

impl<B, R> !Freeze for AbstractCircMgr<B, R>

§

impl<B, R> RefUnwindSafe for AbstractCircMgr<B, R>

§

impl<B, R> Send for AbstractCircMgr<B, R>

§

impl<B, R> Sync for AbstractCircMgr<B, R>

§

impl<B, R> Unpin for AbstractCircMgr<B, R>

§

impl<B, R> UnwindSafe for AbstractCircMgr<B, R>
where B: UnwindSafe, R: UnwindSafe,

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

impl<T> Conv for T

§

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

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

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

§

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

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
§

impl<T> FmtForward for T

§

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.

§

impl<T> Instrument for T

§

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

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

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
§

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

§

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
§

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
§

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
§

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
§

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
§

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.
§

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.
§

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.
§

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> Same for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

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

Immutable access to a value. Read more
§

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

Mutable access to a value. Read more
§

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
§

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
§

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
§

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
§

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
§

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
§

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

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

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

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

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.
§

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.
§

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.
§

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.
§

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.
§

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.
§

impl<T> TryConv for T

§

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

§

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

§

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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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