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>
impl<B: AbstractCircBuilder + 'static, R: Runtime> AbstractCircMgr<B, R>
sourcepub(crate) fn new(builder: B, runtime: R, circuit_timing: CircuitTiming) -> Self
pub(crate) fn new(builder: B, runtime: R, circuit_timing: CircuitTiming) -> Self
Construct a new AbstractCircMgr.
sourcepub(crate) fn update_network_parameters(&self, p: &NetParameters)
pub(crate) fn update_network_parameters(&self, p: &NetParameters)
Reconfigure this manager using the latest set of network parameters.
sourcepub(crate) fn circuit_timing(&self) -> Arc<CircuitTiming>
pub(crate) fn circuit_timing(&self) -> Arc<CircuitTiming>
Return this manager’s CircuitTiming
.
sourcepub(crate) fn set_circuit_timing(&self, new_config: CircuitTiming)
pub(crate) fn set_circuit_timing(&self, new_config: CircuitTiming)
Return this manager’s CircuitTiming
.
sourcepub(crate) async fn get_or_launch(
self: &Arc<Self>,
usage: &<B::Spec as AbstractSpec>::Usage,
dir: DirInfo<'_>
) -> Result<(Arc<B::Circ>, CircProvenance)>
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.
sourcepub(crate) async fn ensure_circuit(
self: &Arc<Self>,
usage: &<B::Spec as AbstractSpec>::Usage,
dir: DirInfo<'_>
) -> Result<()>
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.
sourcefn prepare_action(
&self,
usage: &<B::Spec as AbstractSpec>::Usage,
dir: DirInfo<'_>,
restrict_circ: bool
) -> Result<Action<B>>
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
.
sourceasync fn take_action(
self: Arc<Self>,
act: Action<B>,
usage: &<B::Spec as AbstractSpec>::Usage
) -> Result<(Arc<B::Circ>, CircProvenance), RetryError<Box<Error>>>
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.
sourcefn plan_by_usage(
&self,
dir: DirInfo<'_>,
usage: &<B::Spec as AbstractSpec>::Usage
) -> Result<(Arc<PendingEntry<B>>, CircBuildPlan<B>)>
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.
sourcepub(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>>>>
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.
sourcefn spawn_launch(
self: Arc<Self>,
usage: &<B::Spec as AbstractSpec>::Usage,
plan: CircBuildPlan<B>
) -> Shared<Receiver<Result<<<B as AbstractCircBuilder>::Circ as AbstractCirc>::Id>>>
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.
sourceasync 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>)
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.
sourcepub(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.
pub(crate) async fn launch_unmanaged( &self, usage: &<B::Spec as AbstractSpec>::Usage, dir: DirInfo<'_> ) -> Result<(<B as AbstractCircBuilder>::Spec, Arc<B::Circ>)>
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.
sourcepub(crate) fn take_circ(
&self,
id: &<B::Circ as AbstractCirc>::Id
) -> Option<Arc<B::Circ>>
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.
sourcepub(crate) fn retire_all_circuits(&self)
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.
sourcepub(crate) fn expire_circs(&self, now: Instant)
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.
sourcepub(crate) fn expire_circ(
&self,
circ_id: &<B::Circ as AbstractCirc>::Id,
now: Instant
)
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
.
sourcepub(crate) fn n_circs(&self) -> usize
pub(crate) fn n_circs(&self) -> usize
Return the number of open circuits held by this circuit manager.
sourcepub(crate) fn peek_runtime(&self) -> &R
pub(crate) fn peek_runtime(&self) -> &R
Get a reference to this manager’s runtime.
sourcepub(crate) fn peek_builder(&self) -> &B
pub(crate) fn peek_builder(&self) -> &B
Get a reference to this manager’s builder.
sourcefn pick_use_duration(&self) -> Duration
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>where
B: RefUnwindSafe,
R: RefUnwindSafe,
impl<B, R> Send for AbstractCircMgr<B, R>
impl<B, R> Sync for AbstractCircMgr<B, R>
impl<B, R> Unpin for AbstractCircMgr<B, R>where
B: Unpin,
R: Unpin,
<<B as AbstractCircBuilder>::Circ as AbstractCirc>::Id: Unpin,
<B as AbstractCircBuilder>::Spec: Unpin,
impl<B, R> UnwindSafe for AbstractCircMgr<B, R>where
B: UnwindSafe,
R: UnwindSafe,
Blanket Implementations§
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
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§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>
. 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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
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.§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.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§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.§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.§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.§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.§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.§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.§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.§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.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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 more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§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 more§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 more§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
§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
§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.§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.§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.§impl<T> Tap for T
impl<T> Tap for T
§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 more§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 more§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 more§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 more§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 more§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 more§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.§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.§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.§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.§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.§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.§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.