Files
fips/src/node/session.rs
T
Johnathan Corgan b8a1f322c2 Module reorganization and clippy cleanup
Move single-consumer modules into node/:
- rate_limit.rs, wire.rs, dns.rs — exclusively used by node subsystem
- Reduces top-level lib.rs from 16 to 13 modules

Split large files into focused subdirectories:
- noise.rs (1475 lines) → noise/{mod, handshake, session, replay, tests}.rs
- tree.rs (1479 lines) → tree/{mod, coordinate, declaration, state, tests}.rs
- bloom.rs (849 lines) → bloom/{mod, filter, state, tests}.rs
- All public APIs re-exported from mod.rs, no external import changes

Remove unused rate_limit defaults:
- HANDSHAKE_TIMEOUT_SECS, MAX_PENDING_INBOUND constants
- Default constructor eliminated in favor of with_params() taking config values

Fix all clippy warnings across codebase:
- Remove .clone() on Copy types, collapse nested ifs, replace match-return-None
  with ?, remove/gate unused code, fix loop indexing, remove unnecessary casts
- Box large PeerSlot enum variants to reduce size disparity
- cargo clippy --all-targets now reports zero warnings
2026-02-15 15:07:42 +00:00

121 lines
3.7 KiB
Rust

//! End-to-end session state.
//!
//! Tracks Noise IK sessions between this node and remote endpoints.
//! Sessions are established via SessionSetup/SessionAck handshake
//! messages carried inside SessionDatagram envelopes through the mesh.
use crate::noise::{HandshakeState, NoiseSession};
use crate::NodeAddr;
use secp256k1::PublicKey;
/// State machine for an end-to-end session.
pub(crate) enum EndToEndState {
/// We initiated: sent SessionSetup with Noise IK msg1, awaiting SessionAck.
Initiating(HandshakeState),
/// We are responding: received msg1, sent SessionAck with msg2.
Responding(HandshakeState),
/// Handshake complete, NoiseSession available for encrypt/decrypt.
Established(NoiseSession),
}
impl EndToEndState {
/// Check if the session is established and ready for data.
pub(crate) fn is_established(&self) -> bool {
matches!(self, EndToEndState::Established(_))
}
/// Check if we are the initiator (waiting for ack).
pub(crate) fn is_initiating(&self) -> bool {
matches!(self, EndToEndState::Initiating(_))
}
/// Check if we are the responder (sent ack, waiting for data).
pub(crate) fn is_responding(&self) -> bool {
matches!(self, EndToEndState::Responding(_))
}
}
/// A single end-to-end session with a remote node.
///
/// The state is wrapped in `Option` to allow taking ownership of the
/// handshake state during transitions without placeholder values.
/// The state is `None` only transiently during handler processing.
pub(crate) struct SessionEntry {
/// Remote node's address (session table key).
#[allow(dead_code)]
remote_addr: NodeAddr,
/// Remote node's static public key (for Noise IK).
#[allow(dead_code)]
remote_pubkey: PublicKey,
/// Current session state. `None` only during state transitions.
state: Option<EndToEndState>,
/// When the session was created (Unix milliseconds).
#[cfg_attr(not(test), allow(dead_code))]
created_at: u64,
/// Last activity timestamp (Unix milliseconds).
last_activity: u64,
}
impl SessionEntry {
/// Create a new session entry.
pub(crate) fn new(
remote_addr: NodeAddr,
remote_pubkey: PublicKey,
state: EndToEndState,
now_ms: u64,
) -> Self {
Self {
remote_addr,
remote_pubkey,
state: Some(state),
created_at: now_ms,
last_activity: now_ms,
}
}
/// Get the current session state.
pub(crate) fn state(&self) -> &EndToEndState {
self.state.as_ref().expect("session state taken but not restored")
}
/// Get mutable access to the session state.
pub(crate) fn state_mut(&mut self) -> &mut EndToEndState {
self.state.as_mut().expect("session state taken but not restored")
}
/// Replace the session state.
pub(crate) fn set_state(&mut self, state: EndToEndState) {
self.state = Some(state);
}
/// Take the state out, leaving `None`.
///
/// The caller must call `set_state()` to restore a valid state,
/// or discard the entry entirely.
pub(crate) fn take_state(&mut self) -> Option<EndToEndState> {
self.state.take()
}
/// Update the last activity timestamp.
pub(crate) fn touch(&mut self, now_ms: u64) {
self.last_activity = now_ms;
}
/// Check if the session is established.
pub(crate) fn is_established(&self) -> bool {
self.state.as_ref().is_some_and(|s| s.is_established())
}
/// Get creation time.
#[cfg(test)]
pub(crate) fn created_at(&self) -> u64 {
self.created_at
}
/// Get last activity time.
#[cfg(test)]
pub(crate) fn last_activity(&self) -> u64 {
self.last_activity
}
}