pub(crate) struct GuardMgrInner {Show 14 fields
pub(crate) last_primary_retry_time: Instant,
pub(crate) guards: GuardSets,
pub(crate) filter: GuardFilter,
pub(crate) params: GuardParams,
pub(crate) ctrl: UnboundedSender<Msg>,
pub(crate) pending: HashMap<RequestId, PendingRequest>,
pub(crate) waiting: Vec<PendingRequest>,
pub(crate) fallbacks: FallbackState,
pub(crate) storage: DynStorageHandle<GuardSets>,
pub(crate) send_skew: Sender<Option<SkewEstimate>>,
pub(crate) recv_skew: ClockSkewEvents,
pub(crate) netdir_provider: Option<Weak<dyn NetDirProvider>>,
pub(crate) bridge_desc_provider: Option<Weak<dyn BridgeDescProvider>>,
pub(crate) configured_bridges: Option<Arc<[BridgeConfig]>>,
}
Expand description
Fields§
§last_primary_retry_time: Instant
Last time when marked all of our primary guards as retriable.
We keep track of this time so that we can rate-limit these attempts.
guards: GuardSets
Persistent guard manager state.
This object remembers one or more persistent set of guards that we can use, along with their relative priorities and statuses.
filter: GuardFilter
The current filter that we’re using to decide which guards are supported.
params: GuardParams
Configuration values derived from the consensus parameters.
This is updated whenever the consensus parameters change.
ctrl: UnboundedSender<Msg>
A mpsc channel, used to tell the task running in
daemon::report_status_events
about a new event to monitor.
This uses an UnboundedSender
so that we don’t have to await
while sending the message, which in turn allows the GuardMgr
API to be simpler. The risk, however, is that there’s no
backpressure in the event that the task running
daemon::report_status_events
fails to read from this
channel.
pending: HashMap<RequestId, PendingRequest>
Information about guards that we’ve given out, but where we have not yet heard whether the guard was successful.
Upon leaning whether the guard was successful, the pending
requests in this map may be either moved to waiting
, or
discarded.
There can be multiple pending requests corresponding to the same guard.
waiting: Vec<PendingRequest>
A list of pending requests for which we have heard that the guard was successful, but we have not yet decided whether the circuit may be used.
There can be multiple waiting requests corresponding to the same guard.
fallbacks: FallbackState
A list of fallback directories used to access the directory system when no other directory information is yet known.
storage: DynStorageHandle<GuardSets>
Location in which to store persistent state.
send_skew: Sender<Option<SkewEstimate>>
A sender object to publish changes in our estimated clock skew.
recv_skew: ClockSkewEvents
A receiver object to hand out to observers who want to know about changes in our estimated clock skew.
netdir_provider: Option<Weak<dyn NetDirProvider>>
A netdir provider that we can use for adding new guards when insufficient guards are available.
This has to be an Option so it can be initialized from None: at the time a GuardMgr is created, there is no NetDirProvider for it to use.
bridge_desc_provider: Option<Weak<dyn BridgeDescProvider>>
bridge-client
only.A netdir provider that we can use for discovering bridge descriptors.
This has to be an Option so it can be initialized from None: at the time a GuardMgr is created, there is no BridgeDescProvider for it to use.
configured_bridges: Option<Arc<[BridgeConfig]>>
bridge-client
only.A list of the bridges that we are configured to use, or “None” if we are not configured to use bridges.
Implementations§
Source§impl GuardMgrInner
impl GuardMgrInner
Sourcepub(crate) fn timely_netdir(&self) -> Option<Arc<NetDir>>
pub(crate) fn timely_netdir(&self) -> Option<Arc<NetDir>>
Look up the latest NetDir
(if there is one) from our
NetDirProvider
(if we have one).
Sourcepub(crate) fn latest_bridge_desc_list(&self) -> Option<Arc<BridgeDescList>>
Available on crate feature bridge-client
only.
pub(crate) fn latest_bridge_desc_list(&self) -> Option<Arc<BridgeDescList>>
bridge-client
only.Look up the latest BridgeDescList
(if there
is one) from our BridgeDescProvider
(if
we have one).
Sourcepub(crate) fn with_opt_netdir<F, T>(&mut self, func: F) -> T
pub(crate) fn with_opt_netdir<F, T>(&mut self, func: F) -> T
Run a function that takes &mut self
and an optional NetDir.
We try to use the netdir from our NetDirProvider
(if we have one).
Therefore, although its parameters are suitable for every
GuardSet
, its contents might not be. For those, call
with_opt_universe
instead.
Sourcepub(crate) fn latest_bridge_set(&self) -> Option<BridgeSet>
Available on crate feature bridge-client
only.
pub(crate) fn latest_bridge_set(&self) -> Option<BridgeSet>
bridge-client
only.Return the latest BridgeSet
based on our BridgeDescProvider
and our
configured bridges.
Returns None
if we are not configured to use bridges.
Sourcepub(crate) fn with_opt_universe<F, T>(&mut self, func: F) -> T
pub(crate) fn with_opt_universe<F, T>(&mut self, func: F) -> T
Run a function that takes &mut self
and an optional UniverseRef
.
We try to get a universe from the appropriate source for the current active guard set.
Sourcepub(crate) fn update(&mut self, wallclock: SystemTime, now: Instant)
pub(crate) fn update(&mut self, wallclock: SystemTime, now: Instant)
Update the status of all guards in the active set, based on the passage of time, our configuration, and the relevant Universe for our active set.
Sourcepub(crate) fn replace_bridge_config(
&mut self,
new_config: &impl GuardMgrConfig,
wallclock: SystemTime,
now: Instant,
) -> Result<RetireCircuits, GuardMgrConfigError>
Available on crate feature bridge-client
only.
pub(crate) fn replace_bridge_config( &mut self, new_config: &impl GuardMgrConfig, wallclock: SystemTime, now: Instant, ) -> Result<RetireCircuits, GuardMgrConfigError>
bridge-client
only.Replace our bridge configuration with the one from new_config
.
Sourcepub(crate) fn update_active_set_params_and_filter(
&mut self,
netdir: Option<&NetDir>,
)
pub(crate) fn update_active_set_params_and_filter( &mut self, netdir: Option<&NetDir>, )
Update our parameters, our selection (based on network parameters and configuration), and make sure the active GuardSet has the right configuration itself.
We should call this whenever the NetDir’s parameters change, or whenever our filter changes. We do not need to call it for new elements arriving in our Universe, since those do not affect anything here.
We should also call this whenever a new GuardSet becomes active for any reason other than just having called this function.
(This function is only invoked from update
, which should be called
under the above circumstances.)
Sourcepub(crate) fn update_guardset_internal<U: Universe>(
params: &GuardParams,
now: SystemTime,
universe_type: UniverseType,
active_guards: &mut GuardSet,
universe: Option<&U>,
) -> ExtendedStatus
pub(crate) fn update_guardset_internal<U: Universe>( params: &GuardParams, now: SystemTime, universe_type: UniverseType, active_guards: &mut GuardSet, universe: Option<&U>, ) -> ExtendedStatus
Update the status of every guard in active_guards
, and expand it as
needed.
This function doesn’t take &self
, to make sure that we are only
affecting a single GuardSet
, and to avoid confusing the borrow
checker.
We should call this whenever the contents of the universe have changed.
We should also call this whenever a new GuardSet becomes active.
Sourcepub(crate) fn update_desired_descriptors(&mut self, now: Instant)
Available on crate feature bridge-client
only.
pub(crate) fn update_desired_descriptors(&mut self, now: Instant)
bridge-client
only.If using bridges, tell the BridgeDescProvider which descriptors we want. We need to check this after we select our primary guards.
Sourcepub(crate) fn replace_guards_with(
&mut self,
new_guards: GuardSets,
wallclock: SystemTime,
now: Instant,
)
pub(crate) fn replace_guards_with( &mut self, new_guards: GuardSets, wallclock: SystemTime, now: Instant, )
Replace the active guard state with new_state
, preserving
non-persistent state for any guards that are retained.
Sourcepub(crate) fn select_guard_set_based_on_filter(&mut self, netdir: &NetDir)
pub(crate) fn select_guard_set_based_on_filter(&mut self, netdir: &NetDir)
Update which guard set is active based on the current filter and the provided netdir.
After calling this function, the new guard set’s filter may be
out-of-date: be sure to call set_filter
as appropriate.
Sourcepub(crate) fn maybe_retry_primary_guards(&mut self, now: Instant)
pub(crate) fn maybe_retry_primary_guards(&mut self, now: Instant)
Mark all of our primary guards as retriable, if we haven’t done
so since long enough before now
.
We want to call this function whenever a guard attempt succeeds, if the internet seemed to be down when the guard attempt was first launched.
Sourcepub(crate) fn set_filter(
&mut self,
filter: GuardFilter,
wallclock: SystemTime,
now: Instant,
)
pub(crate) fn set_filter( &mut self, filter: GuardFilter, wallclock: SystemTime, now: Instant, )
Replace the current GuardFilter with filter
.
Sourcepub(crate) fn handle_msg(
&mut self,
request_id: RequestId,
status: GuardStatus,
skew: Option<ClockSkew>,
runtime: &impl SleepProvider,
)
pub(crate) fn handle_msg( &mut self, request_id: RequestId, status: GuardStatus, skew: Option<ClockSkew>, runtime: &impl SleepProvider, )
Called when the circuit manager reports (via GuardMonitor
) that
a guard succeeded or failed.
Changes the guard’s status as appropriate, and updates the pending request as needed.
Sourcepub(crate) fn record_external_success<T>(
&mut self,
identity: &T,
external_activity: ExternalActivity,
now: SystemTime,
)where
T: HasRelayIds + ?Sized,
pub(crate) fn record_external_success<T>(
&mut self,
identity: &T,
external_activity: ExternalActivity,
now: SystemTime,
)where
T: HasRelayIds + ?Sized,
Helper to implement GuardMgr::note_external_success()
.
(This has to be a separate function so that we can borrow params while
we have mut self
borrowed.)
Sourcepub(crate) fn skew_observations(&self) -> impl Iterator<Item = &SkewObservation>
pub(crate) fn skew_observations(&self) -> impl Iterator<Item = &SkewObservation>
Return an iterator over all of the clock skew observations we’ve made for guards or fallbacks.
Sourcepub(crate) fn update_skew(&mut self, now: Instant)
pub(crate) fn update_skew(&mut self, now: Instant)
Recalculate our estimated clock skew, and publish it to anybody who cares.
Sourcepub(crate) fn guard_usability_status(
&self,
pending: &PendingRequest,
now: Instant,
) -> Option<bool>
pub(crate) fn guard_usability_status( &self, pending: &PendingRequest, now: Instant, ) -> Option<bool>
If the circuit built because of a given PendingRequest
may
now be used (or discarded), return Some(true)
or
Some(false)
respectively.
Return None if we can’t yet give an answer about whether such a circuit is usable.
Sourcepub(crate) fn expire_and_answer_pending_requests(&mut self, now: Instant)
pub(crate) fn expire_and_answer_pending_requests(&mut self, now: Instant)
For requests that have been “waiting” for an answer for too long, expire them and tell the circuit manager that their circuits are unusable.
Sourcepub(crate) fn lookup_ids<T>(&self, identity: &T) -> Vec<FirstHopId>where
T: HasRelayIds + ?Sized,
pub(crate) fn lookup_ids<T>(&self, identity: &T) -> Vec<FirstHopId>where
T: HasRelayIds + ?Sized,
Return every currently extant FirstHopId for a guard or fallback directory matching (or possibly matching) the provided keys.
An identity is possibly matching if it contains some of the IDs in the provided identity, and it has no contradictory identities, but it does not necessarily contain all of those identities.
§TODO
This function should probably not exist; it’s only used so that dirmgr can report successes or failures, since by the time it observes them it doesn’t know whether its circuit came from a guard or a fallback. To solve that, we’ll need CircMgr to record and report which one it was using, which will take some more plumbing.
TODO relay: we will have to make the change above when we implement relays; otherwise, it would be possible for an attacker to exploit it to mislead us about our guard status.
Sourcepub(crate) fn run_periodic_events(
&mut self,
wallclock: SystemTime,
now: Instant,
) -> Duration
pub(crate) fn run_periodic_events( &mut self, wallclock: SystemTime, now: Instant, ) -> Duration
Run any periodic events that update guard status, and return a duration after which periodic events should next be run.
Sourcepub(crate) fn select_guard_with_expand(
&mut self,
usage: &GuardUsage,
now: Instant,
wallclock: SystemTime,
) -> Result<(ListKind, FirstHop), PickGuardError>
pub(crate) fn select_guard_with_expand( &mut self, usage: &GuardUsage, now: Instant, wallclock: SystemTime, ) -> Result<(ListKind, FirstHop), PickGuardError>
Try to select a guard, expanding the sample if the first attempt fails.
Sourcepub(crate) fn select_guard_once(
&self,
usage: &GuardUsage,
now: Instant,
) -> Result<(ListKind, FirstHop), PickGuardError>
pub(crate) fn select_guard_once( &self, usage: &GuardUsage, now: Instant, ) -> Result<(ListKind, FirstHop), PickGuardError>
Helper: try to pick a single guard, without retrying on failure.
Sourcepub(crate) fn select_fallback(
&self,
now: Instant,
) -> Result<(ListKind, FirstHop), PickGuardError>
pub(crate) fn select_fallback( &self, now: Instant, ) -> Result<(ListKind, FirstHop), PickGuardError>
Helper: Select a fallback directory.
Called when we have no guard information to use. Return values are as
for GuardMgr::select_guard()
Auto Trait Implementations§
impl !Freeze for GuardMgrInner
impl !RefUnwindSafe for GuardMgrInner
impl Send for GuardMgrInner
impl Sync for GuardMgrInner
impl Unpin for GuardMgrInner
impl !UnwindSafe for GuardMgrInner
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§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
§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>
, which can then be
downcast
into Box<dyn 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>
, which 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> DowncastSend for T
impl<T> DowncastSend for T
§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.