Skip to main content

ExpiryManager

Struct ExpiryManager 

Source
pub struct ExpiryManager { /* private fields */ }
Expand description

Tracks expired peers and the local-to-control clock delta, and mutates peers to reflect expiry.

Go ipnlocal.expiryManager. One instance per node, owned by whatever holds the peer set (here: ts_runtime’s peer tracker), and driven from the netmap stream.

Implementations§

Source§

impl ExpiryManager

Source

pub fn new() -> Self

A manager with no known expired peers and no clock correction.

Source

pub fn on_control_time( &mut self, control_time: DateTime<Utc>, local_now: DateTime<Utc>, ) -> TimeDelta

Record a MapResponse.ControlTime — Go onControlTime.

Stores the delta between control’s clock and local_now when it exceeds MIN_CLOCK_DELTA_SECS in either direction, and clears it back to zero when it does not (control and this node agree; a previously-recorded skew has been corrected). Returns the delta now in effect.

Source

pub fn clock_delta(&self) -> TimeDelta

The stored local-to-control clock offset (Go clockDelta). Zero when control’s clock is within MIN_CLOCK_DELTA_SECS of this node’s, or before any ControlTime has arrived.

Source

pub fn control_now(&self, local_now: DateTime<Utc>) -> DateTime<Utc>

Control’s estimated current time — Go LocalBackend.ControlNow: local_now shifted by the stored clock_delta. Every expiry comparison is made against this, not against the raw local clock.

Source

pub fn flag_expired_peer( &mut self, peer: &Node, local_now: DateTime<Utc>, ) -> Option<FlaggedPeer>

Apply the expiry pass to one peer — the body of Go’s flagExpiredPeers loop.

Returns the rewritten peer when it had to be changed, and None when nothing changed — so a caller walking a large peer set clones only the handful of peers it has to re-install and re-publish. FlaggedPeer::first_transition separates “this peer just expired” from “this peer was already expired and control restated it unflagged”, which is the difference between a log line and a silent rewrite.

On expiry the peer is flagged, never dropped: expired is set, its underlay endpoints and home DERP are cleared (control does the same for expired nodes), and its node key is broken with ts_keys::node_public_with_bad_old_prefix so nothing can handshake with it. Keeping the row is the point — a caller that tries to reach the peer can then answer PEER_KEY_EXPIRED instead of “no such peer”.

Skipped, returning None:

  • a peer with no expiry at all (node_key_expiry is None — a tagged node; Go’s zero KeyExpiry), and a peer whose expiry is still in the future. Either way the peer is not expired, so the pristine key, endpoints and home DERP a previous pass memoized are put back (see the manager’s own docs) and the memo dropped, exactly where Go does its delete(em.previouslyExpired, ...).
  • a peer already marked Node::expired — by control, or by an earlier pass. Re-flagging would repeat the log and the invalidation on every netmap.
  • every peer, when the delta-adjusted clock is before flag_expired_peers_epoch.
Source

pub fn next_peer_expiry<'a>( &self, peers: impl IntoIterator<Item = &'a Node>, self_node: Option<&Node>, local_now: DateTime<Utc>, ) -> Option<DateTime<Utc>>

The soonest future key expiry across peers and self_node — Go nextPeerExpiry.

The result is in local time (the caller’s clock), so next - local_now is directly the delay to arm a timer for; see EXPIRY_TIMER_SLACK_SECS for the slack upstream adds on top. None when nothing is due to expire, i.e. every peer is tagged (no expiry), already expired, or already past its expiry without having been flagged.

Two guards, both upstream’s:

  • the delta-adjusted clock must not precede flag_expired_peers_epoch, else None.
  • the answer is never before local_now. A local clock running fast relative to control would otherwise produce a negative delay and a timer that fires immediately in a loop; in that case the answer is floored at local_now + CLOCK_SKEW_EXPIRY_FLOOR_SECS.

Trait Implementations§

Source§

impl Clone for ExpiryManager

Source§

fn clone(&self) -> ExpiryManager

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ExpiryManager

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ExpiryManager

Source§

fn default() -> ExpiryManager

Returns the “default value” for a type. Read more

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<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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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