From f9b457d329dc3a727dab3be534d12d5f1dc824f4 Mon Sep 17 00:00:00 2001 From: DeFiDude <59237470+DeFiDude@users.noreply.github.com> Date: Sun, 26 Jul 2026 02:11:21 -0600 Subject: [PATCH] transport: reject foreign IFAC ingress --- crates/rns-transport/src/actor/inbound.rs | 8 +++++++- crates/rns-transport/src/actor/mod.rs | 23 +++++++++++++++++++++++ crates/rns-transport/src/constants.rs | 6 ++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/crates/rns-transport/src/actor/inbound.rs b/crates/rns-transport/src/actor/inbound.rs index d9f24c1..651d49e 100644 --- a/crates/rns-transport/src/actor/inbound.rs +++ b/crates/rns-transport/src/actor/inbound.rs @@ -28,6 +28,12 @@ impl TransportActor { return; } } + } else if crate::ifac::has_ifac_flag(&packet.raw) { + trace!( + interface_id = packet.interface_id, + "IFAC packet received on clear interface, dropping packet" + ); + return; } else { packet.raw.clone() } @@ -736,7 +742,7 @@ impl TransportActor { return; } - tracing::info!( + tracing::debug!( dest = %hex::encode(header.destination_hash), is_local = self.local_destinations.contains(&header.destination_hash), has_channel = self.destination_channels.contains_key(&header.destination_hash), diff --git a/crates/rns-transport/src/actor/mod.rs b/crates/rns-transport/src/actor/mod.rs index d0496f2..080fa36 100644 --- a/crates/rns-transport/src/actor/mod.rs +++ b/crates/rns-transport/src/actor/mod.rs @@ -3879,6 +3879,29 @@ mod tests { assert!(!actor.path_table.has_path(&dest_hash)); } + #[test] + fn test_clear_interface_rejects_ifac_flag_before_packet_accounting() { + let (mut actor, _tx) = TransportActor::new(); + let (entry, _rx) = make_test_interface("clear_in"); + actor.interfaces.insert(1, entry); + + let (raw, _dest_hash) = make_valid_announce("test.ifac_on_clear", 0); + let mut raw = raw.to_vec(); + raw[0] |= 0x80; + + actor.on_inbound(InboundPacket { + raw: Bytes::from(raw), + interface_id: 1, + rssi: None, + snr: None, + q: None, + }); + + assert!(actor.packet_hashlist.is_empty()); + assert!(actor.packet_metrics.is_empty()); + assert!(actor.path_table.is_empty()); + } + #[test] fn test_announce_retransmit() { let (mut actor, _tx) = TransportActor::new(); diff --git a/crates/rns-transport/src/constants.rs b/crates/rns-transport/src/constants.rs index c6f8399..879a965 100644 --- a/crates/rns-transport/src/constants.rs +++ b/crates/rns-transport/src/constants.rs @@ -68,8 +68,10 @@ pub const PATH_REQUEST_RG: f64 = 1.5; /// Minimum interval between path requests (seconds). pub const PATH_REQUEST_MI: f64 = 20.0; -/// Maximum packet hashes before rotation. Set to 2M with rotation at -/// `maxsize/2` so effective history matches Python's 1M-no-rotation window. +/// Maximum packet hashes retained across both generations. +/// +/// Python retains roughly one million hashes. Rust deliberately retains up +/// to two million for a longer bounded replay window; see RNS-D0056. pub const HASHLIST_MAXSIZE: usize = 2_000_000; /// Job loop period (250ms).