pub struct ActivePeer { /* private fields */ }Expand description
A fully authenticated remote FIPS node.
Created only after successful Noise KK handshake. The identity is cryptographically verified at this point.
Note: ActivePeer intentionally does not implement Clone because it contains NoiseSession, which cannot be safely cloned (cloning would risk nonce reuse, a catastrophic security failure).
Implementations§
Source§impl ActivePeer
impl ActivePeer
Sourcepub fn new(
identity: PeerIdentity,
link_id: LinkId,
authenticated_at: u64,
) -> Self
pub fn new( identity: PeerIdentity, link_id: LinkId, authenticated_at: u64, ) -> Self
Create a new active peer from verified identity.
Called after successful authentication handshake.
For peers with Noise sessions, use with_session instead.
Sourcepub fn with_stats(
identity: PeerIdentity,
link_id: LinkId,
authenticated_at: u64,
link_stats: LinkStats,
) -> Self
pub fn with_stats( identity: PeerIdentity, link_id: LinkId, authenticated_at: u64, link_stats: LinkStats, ) -> Self
Create from verified identity with existing link stats.
Used when promoting from PeerConnection, preserving handshake stats.
For peers with Noise sessions, use with_session instead.
Sourcepub fn with_session(
identity: PeerIdentity,
link_id: LinkId,
authenticated_at: u64,
noise_session: NoiseSession,
our_index: SessionIndex,
their_index: SessionIndex,
transport_id: TransportId,
current_addr: TransportAddr,
link_stats: LinkStats,
is_initiator: bool,
mmp_config: &MmpConfig,
remote_epoch: Option<[u8; 8]>,
) -> Self
pub fn with_session( identity: PeerIdentity, link_id: LinkId, authenticated_at: u64, noise_session: NoiseSession, our_index: SessionIndex, their_index: SessionIndex, transport_id: TransportId, current_addr: TransportAddr, link_stats: LinkStats, is_initiator: bool, mmp_config: &MmpConfig, remote_epoch: Option<[u8; 8]>, ) -> Self
Create from verified identity with Noise session and index tracking.
This is the primary constructor for the wire protocol path. The NoiseSession provides encryption/decryption and replay protection.
Sourcepub fn identity(&self) -> &PeerIdentity
pub fn identity(&self) -> &PeerIdentity
Get the peer’s verified identity.
Sourcepub fn address(&self) -> &FipsAddress
pub fn address(&self) -> &FipsAddress
Get the peer’s FIPS address.
Sourcepub fn pubkey(&self) -> XOnlyPublicKey
pub fn pubkey(&self) -> XOnlyPublicKey
Get the peer’s public key.
Sourcepub fn connectivity(&self) -> ConnectivityState
pub fn connectivity(&self) -> ConnectivityState
Get the connectivity state.
Sourcepub fn is_healthy(&self) -> bool
pub fn is_healthy(&self) -> bool
Check if peer is fully healthy.
Sourcepub fn is_disconnected(&self) -> bool
pub fn is_disconnected(&self) -> bool
Check if peer is disconnected.
Sourcepub fn has_session(&self) -> bool
pub fn has_session(&self) -> bool
Check if this peer has a Noise session.
Sourcepub fn noise_session(&self) -> Option<&NoiseSession>
pub fn noise_session(&self) -> Option<&NoiseSession>
Get the Noise session, if present.
Sourcepub fn noise_session_mut(&mut self) -> Option<&mut NoiseSession>
pub fn noise_session_mut(&mut self) -> Option<&mut NoiseSession>
Get mutable access to the Noise session.
Sourcepub fn our_index(&self) -> Option<SessionIndex>
pub fn our_index(&self) -> Option<SessionIndex>
Get our session index (they use this to send TO us).
Sourcepub fn their_index(&self) -> Option<SessionIndex>
pub fn their_index(&self) -> Option<SessionIndex>
Get their session index (we use this to send TO them).
Sourcepub fn set_their_index(&mut self, index: SessionIndex)
pub fn set_their_index(&mut self, index: SessionIndex)
Update their session index (used during cross-connection resolution when the losing node keeps its inbound session but needs the peer’s outbound index).
Sourcepub fn replace_session(
&mut self,
new_session: NoiseSession,
new_our_index: SessionIndex,
new_their_index: SessionIndex,
) -> Option<SessionIndex>
pub fn replace_session( &mut self, new_session: NoiseSession, new_our_index: SessionIndex, new_their_index: SessionIndex, ) -> Option<SessionIndex>
Replace the Noise session and indices during cross-connection resolution.
When both nodes simultaneously initiate, each promotes its inbound handshake first. When the peer’s msg2 arrives, we learn the correct session — the outbound handshake that pairs with the peer’s inbound. This replaces the entire session so both nodes use matching keys.
Returns the old our_index so the caller can update peers_by_index. Also resets the replay suppression counter since the session changed.
Sourcepub fn transport_id(&self) -> Option<TransportId>
pub fn transport_id(&self) -> Option<TransportId>
Get the transport ID for this peer.
Sourcepub fn current_addr(&self) -> Option<&TransportAddr>
pub fn current_addr(&self) -> Option<&TransportAddr>
Get the current transport address.
Sourcepub fn set_current_addr(
&mut self,
transport_id: TransportId,
addr: &TransportAddr,
) -> bool
pub fn set_current_addr( &mut self, transport_id: TransportId, addr: &TransportAddr, ) -> bool
Update the current address (for roaming support).
Called when we receive a valid authenticated packet from a new address.
Short-circuits when neither the transport_id nor the TransportAddr
bytes changed — at multi-Gbps the same peer’s source 4-tuple is
stable per session and the overwhelming majority of inbound
packets hit this fast path. Saves both the redundant
Option::take + Vec drop on the cached side and the caller’s
.clone() allocation on the input side: the caller can pass
&TransportAddr and we only .to_owned() when storing.
Returns true iff the stored (transport_id, current_addr) pair
actually changed. The caller uses this signal to invalidate
derived caches whose validity is bound to the peer’s 5-tuple —
in particular the Linux per-peer connect()-ed UDP socket,
which is pinned to one kernel route + neighbour entry and goes
stale the moment the peer roams. (Clearing it here would force
&mut self users into the wrong shape: the policy of when to
rebuild the connected socket lives on Node, not on the peer
state. Returning a bool keeps that policy where it belongs.)
Sourcepub fn set_handshake_msg2(&mut self, msg2: Vec<u8>)
pub fn set_handshake_msg2(&mut self, msg2: Vec<u8>)
Store wire-format msg2 for resend on duplicate msg1.
Sourcepub fn handshake_msg2(&self) -> Option<&[u8]>
pub fn handshake_msg2(&self) -> Option<&[u8]>
Get stored msg2 bytes for resend.
Sourcepub fn clear_handshake_msg2(&mut self)
pub fn clear_handshake_msg2(&mut self)
Clear stored msg2 (no longer needed after handshake window).
Sourcepub fn increment_replay_suppressed(&mut self) -> u32
pub fn increment_replay_suppressed(&mut self) -> u32
Increment replay suppression counter. Returns the new count.
Sourcepub fn reset_replay_suppressed(&mut self) -> u32
pub fn reset_replay_suppressed(&mut self) -> u32
Reset replay suppression counter, returning previous count.
Sourcepub fn replay_suppressed_count(&self) -> u32
pub fn replay_suppressed_count(&self) -> u32
Current replay suppression count.
Sourcepub fn increment_decrypt_failures(&mut self) -> u32
pub fn increment_decrypt_failures(&mut self) -> u32
Increment consecutive decryption failure counter, returning new count.
Sourcepub fn reset_decrypt_failures(&mut self)
pub fn reset_decrypt_failures(&mut self)
Reset consecutive decryption failure counter.
Sourcepub fn consecutive_decrypt_failures(&self) -> u32
pub fn consecutive_decrypt_failures(&self) -> u32
Current consecutive decryption failure count.
Sourcepub fn remote_epoch(&self) -> Option<[u8; 8]>
pub fn remote_epoch(&self) -> Option<[u8; 8]>
Get the remote peer’s startup epoch (from handshake).
Sourcepub fn coords(&self) -> Option<&TreeCoordinate>
pub fn coords(&self) -> Option<&TreeCoordinate>
Get the peer’s tree coordinates, if known.
Sourcepub fn declaration(&self) -> Option<&ParentDeclaration>
pub fn declaration(&self) -> Option<&ParentDeclaration>
Get the peer’s parent declaration, if known.
Sourcepub fn has_tree_position(&self) -> bool
pub fn has_tree_position(&self) -> bool
Check if this peer has a known tree position.
Sourcepub fn inbound_filter(&self) -> Option<&BloomFilter>
pub fn inbound_filter(&self) -> Option<&BloomFilter>
Get the peer’s inbound filter, if known.
Sourcepub fn filter_sequence(&self) -> u64
pub fn filter_sequence(&self) -> u64
Get the filter sequence number.
Sourcepub fn filter_is_stale(
&self,
current_time_ms: u64,
stale_threshold_ms: u64,
) -> bool
pub fn filter_is_stale( &self, current_time_ms: u64, stale_threshold_ms: u64, ) -> bool
Check if this peer’s filter is stale.
Sourcepub fn may_reach(&self, node_addr: &NodeAddr) -> bool
pub fn may_reach(&self, node_addr: &NodeAddr) -> bool
Check if a destination might be reachable through this peer.
Sourcepub fn needs_filter_update(&self) -> bool
pub fn needs_filter_update(&self) -> bool
Check if we need to send this peer a filter update.
Sourcepub fn link_stats(&self) -> &LinkStats
pub fn link_stats(&self) -> &LinkStats
Get link statistics.
Sourcepub fn link_stats_mut(&mut self) -> &mut LinkStats
pub fn link_stats_mut(&mut self) -> &mut LinkStats
Get mutable link statistics.
Sourcepub fn mmp(&self) -> Option<&MmpPeerState>
pub fn mmp(&self) -> Option<&MmpPeerState>
Get MMP state (None for legacy peers without sessions).
Sourcepub fn mmp_mut(&mut self) -> Option<&mut MmpPeerState>
pub fn mmp_mut(&mut self) -> Option<&mut MmpPeerState>
Get mutable MMP state.
Sourcepub fn link_cost(&self) -> f64
pub fn link_cost(&self) -> f64
Link cost for routing decisions.
Returns a scalar cost where lower is better (1.0 = ideal).
Computed as RTT-weighted ETX: etx * (1.0 + srtt_ms / 100.0).
Returns 1.0 (optimistic default) when MMP metrics are not yet available, matching depth-only parent selection behavior.
Sourcepub fn authenticated_at(&self) -> u64
pub fn authenticated_at(&self) -> u64
When this peer was authenticated.
Sourcepub fn connection_duration(&self, current_time_ms: u64) -> u64
pub fn connection_duration(&self, current_time_ms: u64) -> u64
Connection duration since authentication.
Sourcepub fn session_elapsed_ms(&self) -> u32
pub fn session_elapsed_ms(&self) -> u32
Session-relative elapsed time in milliseconds (for inner header timestamp).
Returns milliseconds since session establishment, truncated to u32. Wraps at ~49.7 days which is acceptable for session-relative timing.
Sourcepub fn session_start(&self) -> Instant
pub fn session_start(&self) -> Instant
When this peer’s session started (for link-dead fallback timing).
Sourcepub fn last_heartbeat_sent(&self) -> Option<Instant>
pub fn last_heartbeat_sent(&self) -> Option<Instant>
When we last sent a heartbeat to this peer.
Sourcepub fn mark_heartbeat_sent(&mut self, now: Instant)
pub fn mark_heartbeat_sent(&mut self, now: Instant)
Record that we sent a heartbeat.
Sourcepub fn mark_stale(&mut self)
pub fn mark_stale(&mut self)
Mark peer as stale (no recent traffic).
Sourcepub fn mark_reconnecting(&mut self)
pub fn mark_reconnecting(&mut self)
Mark peer as reconnecting.
Sourcepub fn mark_disconnected(&mut self)
pub fn mark_disconnected(&mut self)
Mark peer as disconnected.
Sourcepub fn mark_connected(&mut self, current_time_ms: u64)
pub fn mark_connected(&mut self, current_time_ms: u64)
Mark peer as connected (e.g., after successful reconnect).
Sourcepub fn set_link_id(&mut self, link_id: LinkId)
pub fn set_link_id(&mut self, link_id: LinkId)
Update the link ID (e.g., on reconnect).
Sourcepub fn update_tree_position(
&mut self,
declaration: ParentDeclaration,
ancestry: TreeCoordinate,
current_time_ms: u64,
)
pub fn update_tree_position( &mut self, declaration: ParentDeclaration, ancestry: TreeCoordinate, current_time_ms: u64, )
Update peer’s tree position.
Sourcepub fn clear_tree_position(&mut self)
pub fn clear_tree_position(&mut self)
Clear peer’s tree position.
Sourcepub fn set_tree_announce_min_interval_ms(&mut self, ms: u64)
pub fn set_tree_announce_min_interval_ms(&mut self, ms: u64)
Set the minimum interval between TreeAnnounce messages (milliseconds).
Sourcepub fn last_tree_announce_sent_ms(&self) -> u64
pub fn last_tree_announce_sent_ms(&self) -> u64
Get the last tree announce send timestamp (for carrying across reconnection).
Sourcepub fn set_last_tree_announce_sent_ms(&mut self, ms: u64)
pub fn set_last_tree_announce_sent_ms(&mut self, ms: u64)
Set the last tree announce send timestamp (to preserve rate limit across reconnection).
Sourcepub fn can_send_tree_announce(&self, now_ms: u64) -> bool
pub fn can_send_tree_announce(&self, now_ms: u64) -> bool
Check if we can send a TreeAnnounce now (rate limiting).
Sourcepub fn record_tree_announce_sent(&mut self, now_ms: u64)
pub fn record_tree_announce_sent(&mut self, now_ms: u64)
Record that we sent a TreeAnnounce to this peer.
Sourcepub fn mark_tree_announce_pending(&mut self)
pub fn mark_tree_announce_pending(&mut self)
Mark that a tree announce is pending (deferred due to rate limit).
Sourcepub fn has_pending_tree_announce(&self) -> bool
pub fn has_pending_tree_announce(&self) -> bool
Check if a deferred tree announce is waiting to be sent.
Sourcepub fn update_filter(
&mut self,
filter: BloomFilter,
sequence: u64,
current_time_ms: u64,
)
pub fn update_filter( &mut self, filter: BloomFilter, sequence: u64, current_time_ms: u64, )
Update peer’s inbound filter.
Sourcepub fn clear_filter(&mut self)
pub fn clear_filter(&mut self)
Clear peer’s inbound filter.
Sourcepub fn mark_filter_update_needed(&mut self)
pub fn mark_filter_update_needed(&mut self)
Mark that we need to send this peer a filter update.
Sourcepub fn clear_filter_update_needed(&mut self)
pub fn clear_filter_update_needed(&mut self)
Clear the pending filter update flag.
Sourcepub fn session_established_at(&self) -> Instant
pub fn session_established_at(&self) -> Instant
When the current Noise session was established.
Sourcepub fn rekey_jitter_secs(&self) -> i64
pub fn rekey_jitter_secs(&self) -> i64
Per-session symmetric rekey-timer jitter offset (seconds).
Sourcepub fn current_k_bit(&self) -> bool
pub fn current_k_bit(&self) -> bool
Current K-bit epoch value.
Sourcepub fn rekey_in_progress(&self) -> bool
pub fn rekey_in_progress(&self) -> bool
Whether a rekey is currently in progress.
Sourcepub fn set_rekey_in_progress(&mut self)
pub fn set_rekey_in_progress(&mut self)
Mark that a rekey has been initiated.
Sourcepub fn is_rekey_dampened(&self, dampening_secs: u64) -> bool
pub fn is_rekey_dampened(&self, dampening_secs: u64) -> bool
Check if rekey initiation is dampened (peer recently sent us msg1).
Sourcepub fn record_peer_rekey(&mut self)
pub fn record_peer_rekey(&mut self)
Record that the peer initiated a rekey (for dampening).
Sourcepub fn pending_our_index(&self) -> Option<SessionIndex>
pub fn pending_our_index(&self) -> Option<SessionIndex>
Get the pending new session’s our_index.
Sourcepub fn pending_their_index(&self) -> Option<SessionIndex>
pub fn pending_their_index(&self) -> Option<SessionIndex>
Get the pending new session’s their_index.
Sourcepub fn previous_our_index(&self) -> Option<SessionIndex>
pub fn previous_our_index(&self) -> Option<SessionIndex>
Get the previous session’s our_index (during drain).
Sourcepub fn previous_session(&self) -> Option<&NoiseSession>
pub fn previous_session(&self) -> Option<&NoiseSession>
Get the previous session for decryption fallback.
Sourcepub fn previous_session_mut(&mut self) -> Option<&mut NoiseSession>
pub fn previous_session_mut(&mut self) -> Option<&mut NoiseSession>
Get mutable access to the previous session for decryption.
Sourcepub fn pending_new_session(&self) -> Option<&NoiseSession>
pub fn pending_new_session(&self) -> Option<&NoiseSession>
Get the pending new session (completed rekey, not yet cut over).
Sourcepub fn set_pending_session(
&mut self,
session: NoiseSession,
our_index: SessionIndex,
their_index: SessionIndex,
)
pub fn set_pending_session( &mut self, session: NoiseSession, our_index: SessionIndex, their_index: SessionIndex, )
Store a completed rekey session and its indices.
Called when the rekey handshake completes. The session is held as pending until the initiator flips the K-bit on the next outbound packet.
Sourcepub fn cutover_to_new_session(&mut self) -> Option<SessionIndex>
pub fn cutover_to_new_session(&mut self) -> Option<SessionIndex>
Cut over to the pending new session (initiator side).
Moves current session to previous (for drain), promotes pending to current, flips the K-bit. Returns the old our_index that should remain in peers_by_index during the drain window.
Sourcepub fn handle_peer_kbit_flip(&mut self) -> Option<SessionIndex>
pub fn handle_peer_kbit_flip(&mut self) -> Option<SessionIndex>
Handle receiving a K-bit flip from the peer (responder side).
Promotes pending_new_session to current, demotes current to previous. Returns the old our_index for drain tracking.
Sourcepub fn drain_expired(&self, drain_secs: u64) -> bool
pub fn drain_expired(&self, drain_secs: u64) -> bool
Check if the drain window has expired.
Sourcepub fn is_draining(&self) -> bool
pub fn is_draining(&self) -> bool
Whether a drain is in progress.
Sourcepub fn complete_drain(&mut self) -> Option<SessionIndex>
pub fn complete_drain(&mut self) -> Option<SessionIndex>
Complete the drain: drop previous session and free its index.
Returns the previous our_index so the caller can remove it from peers_by_index and free it from the IndexAllocator.
Sourcepub fn abandon_rekey(&mut self) -> Option<SessionIndex>
pub fn abandon_rekey(&mut self) -> Option<SessionIndex>
Abandon an in-progress rekey.
Returns the rekey our_index so the caller can free it. Also clears any pending session state if the handshake was completed but not yet cut over.
Sourcepub fn set_rekey_state(
&mut self,
handshake: NoiseHandshakeState,
our_index: SessionIndex,
wire_msg1: Vec<u8>,
next_resend_ms: u64,
)
pub fn set_rekey_state( &mut self, handshake: NoiseHandshakeState, our_index: SessionIndex, wire_msg1: Vec<u8>, next_resend_ms: u64, )
Store rekey handshake state after sending msg1.
Sourcepub fn rekey_our_index(&self) -> Option<SessionIndex>
pub fn rekey_our_index(&self) -> Option<SessionIndex>
Get the rekey our_index (for msg2 dispatch lookup).
Sourcepub fn complete_rekey_msg2(
&mut self,
msg2_bytes: &[u8],
) -> Result<NoiseSession, NoiseError>
pub fn complete_rekey_msg2( &mut self, msg2_bytes: &[u8], ) -> Result<NoiseSession, NoiseError>
Complete the rekey by processing msg2 (initiator side).
Takes the stored handshake state, reads msg2, and returns the completed NoiseSession. Clears the handshake-related fields but leaves rekey_our_index for set_pending_session to use.
Sourcepub fn needs_msg1_resend(&self, now_ms: u64) -> bool
pub fn needs_msg1_resend(&self, now_ms: u64) -> bool
Check if msg1 needs resending.
Sourcepub fn rekey_msg1(&self) -> Option<&[u8]>
pub fn rekey_msg1(&self) -> Option<&[u8]>
Get msg1 bytes for resend (without consuming).
Sourcepub fn set_msg1_next_resend(&mut self, next_ms: u64)
pub fn set_msg1_next_resend(&mut self, next_ms: u64)
Update next resend timestamp.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ActivePeer
impl !RefUnwindSafe for ActivePeer
impl Send for ActivePeer
impl Sync for ActivePeer
impl Unpin for ActivePeer
impl UnsafeUnpin for ActivePeer
impl !UnwindSafe for ActivePeer
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
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 more