summaryrefslogtreecommitdiffstats
path: root/src/transport/identity.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-28 02:54:55 +0100
committertv <tv@krebsco.de>2026-10-28 02:54:55 +0100
commitb88be3ea1b475b1a656298b98708026388eaf2af (patch)
tree9ffb3c42800c348ae4d67d1d9a43daa608c2269d /src/transport/identity.rs
parent24327be7e09c20a9820eac61ba3ac60fb7bdb424 (diff)
move keepalive and firewall to paths
Diffstat (limited to 'src/transport/identity.rs')
-rw-r--r--src/transport/identity.rs59
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();