Johnathan Corgan
ab7a4bac29
Logging level overhaul: reduce verbosity at info and debug levels
...
Per-packet happy-path events (UDP send/receive, TUN I/O, MMP report
processing, TreeAnnounce/FilterAnnounce sent, RTT samples) moved from
debug to trace. Periodic maintenance and retry scheduling moved from
info to debug. Session state changes (established, initiated, torn
down) and transport stop promoted from debug to info. MMP report send
failures demoted from warn to debug (normal under churn).
2026-02-19 04:15:08 +00:00
Johnathan Corgan
04d9fd625d
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.
2026-02-19 03:15:05 +00:00
Johnathan Corgan
d8cb4d407e
FLP wire format revision and MMP link-layer measurement protocol
...
## FLP Wire Format Revision
Replace the 1-byte discriminator with a structured wire format:
- 4-byte common prefix (ver+phase, flags, payload_len) and 16-byte
established frame header with AEAD AAD binding
- 5-byte encrypted inner header (4-byte session-relative timestamp +
1-byte message type) on all link messages
- Phase-based packet dispatch replacing discriminator-based dispatch
- SessionDatagram reassigned from type 0x40 to 0x00; add SenderReport
(0x01) and ReceiverReport (0x02) message types for MMP
- SessionDatagram: rename hop_limit to ttl, add path_mtu field (u16 LE)
with min(datagram.path_mtu, transport.mtu()) at forwarding
- Updated handshake packets (msg1: 87->90 bytes, msg2: 42->45 bytes)
- FIPS_OVERHEAD updated from 135 to 144 bytes
## MMP Link-Layer Measurement Protocol
Add the Metrics Measurement Protocol for link quality measurement
between FIPS peers. Measures RTT, loss, jitter, throughput, OWD trend,
and ETX from periodic sender/receiver reports exchanged over established
links.
Module layout:
- mmp/algorithms.rs: JitterEstimator, SrttEstimator, DualEwma, OwdTrend,
SpinBit, ETX computation
- mmp/report.rs: SenderReport (48B) and ReceiverReport (68B) wire format
- mmp/sender.rs: per-peer TX counters and interval tracking
- mmp/receiver.rs: per-peer RX counters, jitter, loss, gap tracking
- mmp/metrics.rs: derived metrics from report processing (SRTT, goodput_bps)
- mmp/mod.rs: MmpMode (Full/Lightweight/Minimal), MmpConfig, MmpPeerState
- node/handlers/mmp.rs: report dispatch, timer-driven generation, operator
logging (periodic + teardown)
Integration: per-frame TX/RX hooks in encrypted message handling, report
dispatch from link message router, timer-driven generation from tick
handler, and periodic operator logging with throughput formatting.
Three operating modes: Full (sender + receiver reports, spin bit, CE echo),
Lightweight (receiver reports only), Minimal (spin bit + CE echo only).
## Design Documentation
Updated FLP sections across all design documents to match the implemented
wire format, including revised overhead calculations and numeric values.
568 tests pass, clippy clean.
2026-02-18 21:54:21 +00:00
Origami74 and Johnathan Corgan
d3477a7c0f
Add explicit counter to DataPacket for out-of-order decryption
...
Session-layer encryption used an implicit nonce counter with no counter
on the wire, requiring packets to arrive in exact order. Under bulk
transfer load (e.g., SCP), UDP packet loss or reordering permanently
desynchronized sender/receiver counters, causing all subsequent
decryption to fail with no recovery.
Add an 8-byte counter field to the DataPacket wire format and switch
from implicit-counter decrypt() to decrypt_with_replay_check() which
uses the explicit wire counter plus a 2048-packet sliding replay
window — the same pattern already used at the link layer.
Wire format: msg_type(1) + flags(1) + counter(8) + payload_len(2) = 12
bytes (was 4). FIPS_OVERHEAD updated 127 → 135 bytes accordingly.
2026-02-17 00:33:01 +00:00
Origami74 and Johnathan Corgan
852f561fa0
feat: implement ICMP Packet Too Big and TCP MSS clamping for MTU handling
...
Add dual-approach MTU handling to prevent TCP connections from hanging
when packets exceed the transport MTU after FIPS encapsulation.
ICMPv6 Packet Too Big:
- Generate RFC 4443 PTB messages for oversized packets at TUN outbound
- Inject back via TUN for local delivery to the application
- Per-source rate limiting (100ms interval, 10s entry expiry)
- MTU check in handle_tun_outbound before session encapsulation
TCP MSS Clamping:
- Intercept SYN packets in run_tun_reader() (outbound)
- Intercept SYN-ACK packets in TunWriter (inbound)
- Clamp MSS option to fit within effective MTU (transport - 127 overhead)
- Recalculate TCP checksum after modification
Code organization:
- ICMP, TCP MSS, and rate limiter modules in upper/ alongside existing
protocol-specific packet handling (dns.rs, tun.rs)
- Shared FIPS_OVERHEAD constant (127 bytes) and effective_ipv6_mtu()
function in upper/icmp.rs
- Node::effective_ipv6_mtu() delegates to the shared function
- run_tun_reader() accepts actual transport MTU from config
Example config corrections:
- UDP transport MTU set to 1472 across all configs (correct max UDP
payload for standard Ethernet: 1500 - 20 IPv4 - 8 UDP)
- Startup logging of effective MTU and max MSS values
2026-02-16 21:33:21 +00:00
Johnathan Corgan
930f139787
Split cache.rs and config.rs into directory modules, create utils/
...
Module reorganization for three large single-file modules:
cache.rs (792 lines) split into cache/ directory:
- cache/mod.rs: CacheError, CacheStats, re-exports
- cache/entry.rs: CacheEntry with TTL/LRU tracking
- cache/coord_cache.rs: CoordCache (address-to-coordinate mappings)
- cache/route_cache.rs: RouteCache + CachedCoords (discovery routes)
- Added 22 new tests filling coverage gaps across all submodules
config.rs (1318 lines) split into config/ directory:
- config/mod.rs: ConfigError, IdentityConfig, Config struct with file
loading/merge logic, all 24 integration tests
- config/node.rs: NodeConfig + 9 subsection structs (Limits, RateLimit,
Retry, Cache, Discovery, Tree, Bloom, Session, Buffers)
- config/transport.rs: TransportInstances<T>, TransportsConfig, UdpConfig
- config/peer.rs: ConnectPolicy, PeerAddress, PeerConfig
DnsConfig and TunConfig moved to upper/config.rs to co-locate with the
upper layer components they configure (TUN interface, DNS responder).
index.rs moved to utils/index.rs as cross-cutting infrastructure that
serves both node and peer layers.
2026-02-15 17:56:32 +00:00
Johnathan Corgan
d71e48b0f2
Module reorganization, identity test coverage, design doc corrections
...
Module reorganization:
- Split identity.rs (930 lines) into identity/ directory module:
mod.rs, node_addr.rs, address.rs, peer.rs, local.rs, auth.rs,
encoding.rs, tests.rs — following established bloom/, tree/, noise/
pattern
- Group TUN, DNS, and ICMPv6 into upper/ module as the IPv6 adaptation
layer: move tun.rs, icmp.rs, node/dns.rs into upper/
Identity test coverage (28 new tests, 52 total):
- Encoding error paths: invalid npub/nsec length, bad hex input
- NodeAddr: Debug, Display, as_slice, AsRef, Hash
- FipsAddress: from_slice, From trait, Debug, Display, Eq+Hash
- PeerIdentity: from_pubkey_full, pubkey_full parity paths, Debug
- Identity: keypair, pubkey_full, Debug
- AuthChallenge: from_bytes
Design doc corrections (fips-software-architecture.md):
- Identity struct: npub+nsec fields → keypair: Keypair with accessors
- Node struct: TunInterface → TunState, Transport → TransportHandle,
Peer → PeerSlot
- Peer section: monolithic Peer → two-phase PeerSlot (PeerConnection +
ActivePeer) with HandshakeState/ConnectivityState
- ActivePeer: npub → identity: PeerIdentity, ancestry Vec → Option,
declaration/inbound_filter wrapped in Option
- BloomState: add 4 missing fields, fix update_debounce type
- DiscoveredPeer: field name and type corrections
2026-02-15 17:11:58 +00:00