mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 00:04:54 +00:00
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
121 lines
3.7 KiB
Rust
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
|
|
}
|
|
}
|