diff options
| author | tv <tv@krebsco.de> | 2026-10-28 02:54:55 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-28 02:54:55 +0100 |
| commit | b88be3ea1b475b1a656298b98708026388eaf2af (patch) | |
| tree | 9ffb3c42800c348ae4d67d1d9a43daa608c2269d /src/transport/identity.rs | |
| parent | 24327be7e09c20a9820eac61ba3ac60fb7bdb424 (diff) | |
move keepalive and firewall to paths
Diffstat (limited to 'src/transport/identity.rs')
| -rw-r--r-- | src/transport/identity.rs | 59 |
1 files changed, 47 insertions, 12 deletions
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<Paths>, + /// The debug firewall, by node ID; paths applies it (`Gate`). + firewall: Option<Arc<Firewall>>, key: Arc<NodeKey>, 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<dyn Transport>, config: IdentityConfig, traffic: Arc<Traffic>, + firewall: Option<Arc<Firewall>>, ) -> 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<Shared>| { + let gate: std::sync::Weak<dyn Gate> = 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(); |
