pub(crate) struct AbstractTunnelMgr<B: AbstractTunnelBuilder<R>, R: Runtime> {
builder: B,
runtime: R,
tunnels: Mutex<TunnelList<B, R>>,
circuit_timing: MutCfg<CircuitTiming>,
unused_timing: Mutex<UnusedTimings>,
}Expand description
Abstract implementation for tunnel management.
The algorithm provided here is fairly simple. In its simplest form:
When somebody asks for a tunnel for a given operation: if we find one open already, we return it. If we find in-progress tunnels that would meet our needs, we wait for one to finish (or for all to fail). And otherwise, we launch one or more tunnels to meet the request’s needs.
If this process fails, then we retry it, up to a timeout or a numerical limit.
If a tunnel not previously considered for a given request finishes before the request is satisfied, and if the tunnel would satisfy the request, we try to give that tunnel as an answer to that request even if it was not one of the tunnels that request was waiting for.
Fields§
§builder: BBuilder used to construct tunnels.
runtime: RAn asynchronous runtime to use for launching tasks and checking timeouts.
tunnels: Mutex<TunnelList<B, R>>A CircList to manage our list of tunnels, requests, and pending tunnels.
circuit_timing: MutCfg<CircuitTiming>Configured information about when to expire tunnels and requests.
unused_timing: Mutex<UnusedTimings>Minimum lifetime of an unused tunnel.
Derived from the network parameters.
Implementations§
Source§impl<B: AbstractTunnelBuilder<R> + 'static, R: Runtime> AbstractTunnelMgr<B, R>
impl<B: AbstractTunnelBuilder<R> + 'static, R: Runtime> AbstractTunnelMgr<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 AbstractTunnelMgr.
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: &TargetTunnelUsage,
dir: DirInfo<'_>,
) -> Result<(Arc<B::Tunnel>, TunnelProvenance)>
pub(crate) async fn get_or_launch( self: &Arc<Self>, usage: &TargetTunnelUsage, dir: DirInfo<'_>, ) -> Result<(Arc<B::Tunnel>, TunnelProvenance)>
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 AbstractTunnelMgr.
Sourcefn prepare_action(
&self,
usage: &TargetTunnelUsage,
dir: DirInfo<'_>,
restrict_circ: bool,
) -> Result<Action<B, R>>
fn prepare_action( &self, usage: &TargetTunnelUsage, dir: DirInfo<'_>, restrict_circ: bool, ) -> Result<Action<B, R>>
Choose which action we should take in order to provide a tunnel
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, R>,
usage: &TargetTunnelUsage,
) -> Result<(Arc<B::Tunnel>, TunnelProvenance), RetryError<Box<Error>>>
async fn take_action( self: Arc<Self>, act: Action<B, R>, usage: &TargetTunnelUsage, ) -> Result<(Arc<B::Tunnel>, TunnelProvenance), RetryError<Box<Error>>>
Execute an action returned by pick-action, and return the resulting tunnel or error.
Sourcefn plan_by_usage(
&self,
dir: DirInfo<'_>,
usage: &TargetTunnelUsage,
) -> Result<(Arc<PendingEntry<B, R>>, TunnelBuildPlan<B, R>)>
fn plan_by_usage( &self, dir: DirInfo<'_>, usage: &TargetTunnelUsage, ) -> Result<(Arc<PendingEntry<B, R>>, TunnelBuildPlan<B, R>)>
Given a directory and usage, compute the necessary objects to
build a tunnel: A PendingEntry to keep track of the in-process
tunnel, and a TunnelBuildPlan that we’ll give to the thread
that will build the tunnel.
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 tunnel.
Sourcepub(crate) fn launch_by_usage(
self: &Arc<Self>,
usage: &TargetTunnelUsage,
dir: DirInfo<'_>,
) -> Result<Shared<Receiver<Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>>>>
pub(crate) fn launch_by_usage( self: &Arc<Self>, usage: &TargetTunnelUsage, dir: DirInfo<'_>, ) -> Result<Shared<Receiver<Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>>>>
Launch a managed tunnel for a target usage, without checking whether one already exists or is pending.
Return a listener that will be informed when the tunnel is done.
Sourcefn spawn_launch(
self: Arc<Self>,
usage: &TargetTunnelUsage,
plan: TunnelBuildPlan<B, R>,
) -> Shared<Receiver<Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>>>
fn spawn_launch( self: Arc<Self>, usage: &TargetTunnelUsage, plan: TunnelBuildPlan<B, R>, ) -> Shared<Receiver<Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>>>
Spawn a background task to launch a tunnel, and report its status.
The usage argument is the usage from the original request that made
us build this tunnel.
Sourceasync fn do_launch(
self: Arc<Self>,
plan: <B as AbstractTunnelBuilder<R>>::Plan,
pending: Arc<PendingEntry<B, R>>,
) -> (Option<SupportedTunnelUsage>, Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>)
async fn do_launch( self: Arc<Self>, plan: <B as AbstractTunnelBuilder<R>>::Plan, pending: Arc<PendingEntry<B, R>>, ) -> (Option<SupportedTunnelUsage>, Result<<<B as AbstractTunnelBuilder<R>>::Tunnel as AbstractTunnel>::Id>)
Run in the background to launch a tunnel. Return a 2-tuple of the new tunnel spec and the outcome that should be sent to the initiator.
Sourcefn expiration_params(&self) -> ExpirationParameters
fn expiration_params(&self) -> ExpirationParameters
Return the currently configured expiration parameters.
Sourcepub(crate) async fn launch_unmanaged(
&self,
usage: &TargetTunnelUsage,
dir: DirInfo<'_>,
) -> Result<(SupportedTunnelUsage, B::Tunnel)>
pub(crate) async fn launch_unmanaged( &self, usage: &TargetTunnelUsage, dir: DirInfo<'_>, ) -> Result<(SupportedTunnelUsage, B::Tunnel)>
Plan and launch a new tunnel to a given target, bypassing our managed pool of tunnels.
This method will always return a new tunnel, and never return a tunnel that this CircMgr gives out for anything else.
The new tunnel will participate in the guard and timeout apparatus as appropriate, no retry attempt will be made if the tunnel fails.
Sourcepub(crate) fn take_tunnel(
&self,
id: &<B::Tunnel as AbstractTunnel>::Id,
) -> Option<Arc<B::Tunnel>>
pub(crate) fn take_tunnel( &self, id: &<B::Tunnel as AbstractTunnel>::Id, ) -> Option<Arc<B::Tunnel>>
Remove the tunnel with a given id from this manager.
After this function is called, that tunnel will no longer be handed out to any future requests.
Return None if we have no tunnel with the given ID.
Sourcepub(crate) fn retire_all_tunnels(&self)
pub(crate) fn retire_all_tunnels(&self)
Remove all open and pending tunnels and from this manager, to ensure they can’t be given out for any more requests.
Calling retire_all_tunnels ensures that any tunnel request that gets
an answer after this method runs will receive a tunnel 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 tunnels that are built using the new configuration.
Sourcepub(crate) async fn expire_tunnels(&self, now: Instant) -> Option<Instant>
pub(crate) async fn expire_tunnels(&self, now: Instant) -> Option<Instant>
Expire tunnels according to the rules in config and the
current time now.
Expired tunnels will not be automatically closed, but they will no longer be given out for new tunnels.
Return the earliest time at which any current tunnel will expire.
Sourcepub(crate) async fn consider_expiring_tunnel(
&self,
tun_id: &<B::Tunnel as AbstractTunnel>::Id,
now: Instant,
) -> Result<Option<Instant>>
pub(crate) async fn consider_expiring_tunnel( &self, tun_id: &<B::Tunnel as AbstractTunnel>::Id, now: Instant, ) -> Result<Option<Instant>>
Consider expiring the tunnel with given tunnel id,
according to the rules in config and the current time now.
Returns None if the circuit is expired; otherwise returns the next time at which the circuit may expire.
Sourcepub(crate) fn n_tunnels(&self) -> usize
pub(crate) fn n_tunnels(&self) -> usize
Return the number of open tunnels held by this tunnel 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 tunnel should expire from now if it has not yet been used
Auto Trait Implementations§
impl<B, R> !Freeze for AbstractTunnelMgr<B, R>
impl<B, R> RefUnwindSafe for AbstractTunnelMgr<B, R>where
B: RefUnwindSafe,
R: RefUnwindSafe,
impl<B, R> Send for AbstractTunnelMgr<B, R>
impl<B, R> Sync for AbstractTunnelMgr<B, R>
impl<B, R> Unpin for AbstractTunnelMgr<B, R>
impl<B, R> UnsafeUnpin for AbstractTunnelMgr<B, R>where
B: UnsafeUnpin,
R: UnsafeUnpin,
impl<B, R> UnwindSafe for AbstractTunnelMgr<B, R>where
B: UnwindSafe,
R: UnwindSafe,
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> DowncastSync for T
impl<T> DowncastSync 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.