mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-10 00:26:59 +00:00
Production hardening: unwrap safety, 14 new tests, diagnostics
Harden unwrap() calls in handler hot paths (handshake, encrypted, rekey, session handlers) with proper error propagation. Add 14 tests: profile rejection (6), MMP forward-compat (4), discovery min_mtu pruning (3), XX duplicate msg1 dedup (1). Add NodeProfile Display impl with structured tracing for profile mismatch logging. Expose bloom compression diagnostics (total_compressed_bytes, total_raw_bytes) in control socket. Add module documentation for XX identity timing, profile decision tree, and bloom codec strategy.
This commit is contained in:
@@ -13,6 +13,25 @@
|
||||
//! Bytes 10+: TLV entries, each:
|
||||
//! [field_num:2 LE][length:2 LE][value:N]
|
||||
//! ```
|
||||
//!
|
||||
//! ## Node Profile Decision Tree
|
||||
//!
|
||||
//! Profiles are self-declared (bits 0-2 of the feature bitfield):
|
||||
//!
|
||||
//! - **Full** (0): Full routing. Combines bloom filters from children,
|
||||
//! forwards transit traffic, participates in spanning tree.
|
||||
//! - **NonRouting** (1): Tree participation but no transit forwarding.
|
||||
//! Receives bloom filters (one-way: F→N) but does not send them.
|
||||
//! The full peer inserts N's identity via `leaf_dependents`.
|
||||
//! - **Leaf** (2): Single upstream peer, no tree/bloom/transit.
|
||||
//! Full peer inserts L's identity via `leaf_dependents`.
|
||||
//!
|
||||
//! **Link pairing rule**: at least one side must be Full. Invalid
|
||||
//! pairings (N↔N, N↔L, L↔L) are rejected during FMP negotiation.
|
||||
//!
|
||||
//! **Routing implications**: `forward_lookup_request()` only considers
|
||||
//! Full peers as transit. `peer_inbound_filters()` excludes non-Full
|
||||
//! peers from bloom filter merging.
|
||||
|
||||
use super::ProtocolError;
|
||||
|
||||
@@ -58,6 +77,16 @@ pub enum NodeProfile {
|
||||
Leaf = 2,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for NodeProfile {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Full => write!(f, "full"),
|
||||
Self::NonRouting => write!(f, "non-routing"),
|
||||
Self::Leaf => write!(f, "leaf"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for NodeProfile {
|
||||
type Error = ProtocolError;
|
||||
|
||||
@@ -274,7 +303,7 @@ impl NegotiationPayload {
|
||||
pub fn validate_profiles(ours: NodeProfile, theirs: NodeProfile) -> Result<(), ProtocolError> {
|
||||
if ours != NodeProfile::Full && theirs != NodeProfile::Full {
|
||||
return Err(ProtocolError::Malformed(format!(
|
||||
"invalid profile pairing: {:?} <-> {:?} (at least one must be Full)",
|
||||
"invalid profile pairing: {} <-> {} (at least one must be full)",
|
||||
ours, theirs
|
||||
)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user