mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 08:14:42 +00:00
FSP wire format revision and session-layer MMP implementation
FSP wire format revision (TASK-2026-0007): Introduce the FIPS Session Protocol (FSP) wire format with a 4-byte common prefix [ver_phase:1][flags:1][payload_len:2 LE] replacing the old 1-byte msg_type dispatch. All session messages share this prefix with phase-based dispatch (Established, Setup, Ack, Unencrypted). - New session_wire.rs: FSP constants, header types, parse/build helpers - SessionMessageType enum: DataPacket (0x10), SenderReport (0x11), ReceiverReport (0x12), PathMtuNotification (0x13) - FspFlags (CP/K/U) and FspInnerFlags (SP) for flag management - SessionSenderReport, SessionReceiverReport, PathMtuNotification message structs with encode/decode - FSP send pipeline: 12-byte header as AAD, 6-byte inner header (timestamp + msg_type + inner_flags), encrypt_with_aad() - FSP receive pipeline: parse header, extract cleartext coords (CP), AEAD decrypt with AAD, strip inner header, msg_type dispatch - Forwarding: transit nodes parse cleartext coords without decryption - Removed DataPacket struct and associated types - SessionEntry: session_start_ms, mark_established(), session_timestamp() - FIPS_OVERHEAD: 144 → 150 bytes (+6 for FSP inner header) - Design docs updated for new wire format Session-layer MMP implementation (TASK-2026-0008): Implement complete session-layer MMP reusing the link-layer algorithm modules (SenderState, ReceiverState, MmpMetrics, SpinBitState) with independent configuration and higher report interval clamps. - SessionMmpConfig: separate config section (node.session_mmp.*) - MmpSessionState: session-specific wrapper with PathMtuState tracking - Session-layer constants (500ms-10s report intervals, 1s cold start) - Parameterized interval methods (new_with_cold_start, update_report_interval_with_bounds) on SenderState/ReceiverState - Bidirectional From conversions between link/session report types - SessionEntry: mmp and is_initiator fields, initialized on Established - send_session_msg() for reports/notifications - Per-message RX recording with spin bit state tracking - Handlers for SenderReport, ReceiverReport, PathMtuNotification - path_mtu threaded from SessionDatagram envelope through to handlers - check_session_mmp_reports() tick handler with collect-then-send pattern - Periodic and teardown operator logging for session metrics - PathMtuState: destination observes incoming MTU on all session messages, source seeded from outbound transport MTU, decrease-immediate / increase-requires-3-consecutive rules Link-layer MMP fix: - Stop feeding spin bit RTT samples into SRTT estimator; inter-frame timing in the mesh is irregular, inflating spin-bit RTT by variable processing delays; timestamp-echo provides accurate RTT 29 files changed, 602 tests pass, 0 clippy warnings.
This commit is contained in:
+53
-1
@@ -4,6 +4,8 @@
|
||||
//! Sessions are established via SessionSetup/SessionAck handshake
|
||||
//! messages carried inside SessionDatagram envelopes through the mesh.
|
||||
|
||||
use crate::config::SessionMmpConfig;
|
||||
use crate::mmp::MmpSessionState;
|
||||
use crate::noise::{HandshakeState, NoiseSession};
|
||||
use crate::NodeAddr;
|
||||
use secp256k1::PublicKey;
|
||||
@@ -54,10 +56,19 @@ pub(crate) struct SessionEntry {
|
||||
created_at: u64,
|
||||
/// Last activity timestamp (Unix milliseconds).
|
||||
last_activity: u64,
|
||||
/// Remaining DataPackets that should include COORDS_PRESENT.
|
||||
/// When the session transitioned to Established (Unix milliseconds).
|
||||
/// Used to compute session-relative timestamps for the FSP inner header.
|
||||
/// Set to 0 until the session is established.
|
||||
session_start_ms: u64,
|
||||
/// Remaining data packets that should include COORDS_PRESENT.
|
||||
/// Initialized from config when session becomes Established;
|
||||
/// reset on CoordsRequired receipt.
|
||||
coords_warmup_remaining: u8,
|
||||
/// Whether this node initiated the Noise IK handshake.
|
||||
/// Used for spin bit role assignment in session-layer MMP.
|
||||
is_initiator: bool,
|
||||
/// Session-layer MMP state. Initialized on Established transition.
|
||||
mmp: Option<MmpSessionState>,
|
||||
}
|
||||
|
||||
impl SessionEntry {
|
||||
@@ -67,6 +78,7 @@ impl SessionEntry {
|
||||
remote_pubkey: PublicKey,
|
||||
state: EndToEndState,
|
||||
now_ms: u64,
|
||||
is_initiator: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
remote_addr,
|
||||
@@ -74,7 +86,10 @@ impl SessionEntry {
|
||||
state: Some(state),
|
||||
created_at: now_ms,
|
||||
last_activity: now_ms,
|
||||
session_start_ms: 0,
|
||||
coords_warmup_remaining: 0,
|
||||
is_initiator,
|
||||
mmp: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,4 +147,41 @@ impl SessionEntry {
|
||||
pub(crate) fn set_coords_warmup_remaining(&mut self, value: u8) {
|
||||
self.coords_warmup_remaining = value;
|
||||
}
|
||||
|
||||
/// Mark the session as started (transition to Established).
|
||||
///
|
||||
/// Records the current time as the session start for computing
|
||||
/// session-relative timestamps in the FSP inner header.
|
||||
pub(crate) fn mark_established(&mut self, now_ms: u64) {
|
||||
self.session_start_ms = now_ms;
|
||||
}
|
||||
|
||||
/// Compute a session-relative timestamp for the FSP inner header.
|
||||
///
|
||||
/// Returns `(now_ms - session_start_ms)` truncated to u32.
|
||||
/// Wraps naturally at ~49.7 days, which is fine for relative timing.
|
||||
pub(crate) fn session_timestamp(&self, now_ms: u64) -> u32 {
|
||||
now_ms.wrapping_sub(self.session_start_ms) as u32
|
||||
}
|
||||
|
||||
/// Whether this node initiated the Noise IK handshake.
|
||||
#[cfg_attr(not(test), allow(dead_code))]
|
||||
pub(crate) fn is_initiator(&self) -> bool {
|
||||
self.is_initiator
|
||||
}
|
||||
|
||||
/// Get a reference to the session-layer MMP state, if initialized.
|
||||
pub(crate) fn mmp(&self) -> Option<&MmpSessionState> {
|
||||
self.mmp.as_ref()
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the session-layer MMP state, if initialized.
|
||||
pub(crate) fn mmp_mut(&mut self) -> Option<&mut MmpSessionState> {
|
||||
self.mmp.as_mut()
|
||||
}
|
||||
|
||||
/// Initialize session-layer MMP state (called on Established transition).
|
||||
pub(crate) fn init_mmp(&mut self, config: &SessionMmpConfig) {
|
||||
self.mmp = Some(MmpSessionState::new(config, self.is_initiator));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user