From b88be3ea1b475b1a656298b98708026388eaf2af Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 28 Oct 2026 02:54:55 +0100 Subject: move keepalive and firewall to paths --- src/transport/identity.rs | 59 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'src/transport/identity.rs') diff --git a/src/transport/identity.rs b/src/transport/identity.rs index 5857fb0..153dacc 100644 --- a/src/transport/identity.rs +++ b/src/transport/identity.rs @@ -37,7 +37,8 @@ use tracing::{debug, info}; use crate::identity::{self, NodeKey}; use crate::locks::MutexExt; -use crate::transport::paths::{PathHandler, Paths, scheme_of}; +use crate::transport::firewall::Firewall; +use crate::transport::paths::{Gate, PathHandler, Paths, scheme_of}; use crate::transport::stats::{IdentityCounts, IdentityStats, TransportStats}; use crate::transport::traffic::Traffic; use crate::transport::{ @@ -96,6 +97,8 @@ pub(crate) struct IdentityTransport { struct Shared { paths: Arc, + /// The debug firewall, by node ID; paths applies it (`Gate`). + firewall: Option>, key: Arc, node_id: String, /// WHO and ME are counted here, under the address (`traffic`). @@ -208,27 +211,54 @@ impl Book { impl IdentityTransport { /// Over `transport`, whose addresses have `config.scheme`, and `config.more`. + /// `firewall`: the debug firewall, if any, which paths applies by address. pub(crate) fn new( transport: Arc, config: IdentityConfig, traffic: Arc, + firewall: Option>, ) -> Self { let node_id = config.key.id(); - let paths = Arc::new(Paths::new( - std::iter::once((config.scheme, transport)) - .chain(config.more) - .collect(), - Some(Arc::clone(&traffic)), - )); - Self { - shared: Arc::new(Shared { - paths, + let shared = Arc::new_cyclic(|shared: &std::sync::Weak| { + let gate: std::sync::Weak = shared.clone(); + Shared { + paths: Arc::new(Paths::new( + std::iter::once((config.scheme, transport)) + .chain(config.more) + .collect(), + Some(Arc::clone(&traffic)), + firewall.is_some().then_some(gate), + )), + firewall, key: config.key, node_id, traffic, book: Mutex::default(), - }), - } + } + }); + Self { shared } + } +} + +/// The firewall's rules are by node ID: an address is blocked if the node proven at it +/// is. Addresses no node proved itself at aren't (nothing could name them). +impl Gate for Shared { + fn blocks_inbound(&self, address: &str) -> bool { + self.blocks(address, Firewall::blocks_inbound) + } + + fn blocks_outbound(&self, address: &str) -> bool { + self.blocks(address, Firewall::blocks_outbound) + } +} + +impl Shared { + fn blocks(&self, address: &str, rule: fn(&Firewall, &str) -> bool) -> bool { + let Some(firewall) = &self.firewall else { + return false; + }; + let node = self.lock().at.get(address).map(|(node, _)| node.clone()); + node.is_some_and(|node| rule(firewall, &node)) } } @@ -461,6 +491,11 @@ impl Transport for IdentityTransport { }) } + /// The paths layer answers them (`Paths::receive`). + fn answers_pings(&self) -> bool { + true + } + /// The identity layer's, and each transport's. fn stats(&self) -> TransportStats { let mut stats = self.shared.paths.stats(); -- cgit v1.3.1