Implement fast userspace multihop mesh routing

Replace the one-intermediate-peer relay with protocol-scoped connectivity
graphs and precomputed shortest-path/ECMP forwarding snapshots. Independent
transport readers forward opaque transit frames without a plugin or TUN
round trip. Carry source, destination, a bounded hop limit and stable flow
tags; preserve end-to-end WireGuard links across topology changes.

Classify IP flows before encryption and preserve their tags through the
WireGuard pending queue. Add offline four-agent path-change coverage, loop
and isolation tests, and an opt-in release forwarding microbenchmark. Bump
control/data ALPNs while preserving persistent network identities and state.

Also include the pending Windows Mainline idle-timeout fix and its regression
test, using a reproducible vendored dependency patch.

Validation: fmt, workspace Clippy with warnings denied, and 307 release tests
passed. Two pre-existing Windows SQLite wipe failures were excluded; public
DHT and the manual benchmark remain ignored by default. The forwarding
microbenchmark measured 103 ns (64 B) and 202 ns (1280 B) per transit packet,
excluding encryption and socket I/O.
This commit is contained in:
ab committed 2026-09-22 18:08:26 +03:00
1 parent d1a0eca723
commit b4f3e57c8d
50 files changed
+11073 -857

No files matched your search

+142
View File
@@ -0,0 +1,142 @@
//! Struct and implementation of the Node entry in the Kademlia routing table
use std::{
fmt::{self, Debug, Formatter},
net::SocketAddrV4,
sync::Arc,
time::{Duration, Instant},
};
use crate::common::Id;
/// The age of a node's last_seen time before it is considered stale and removed from a full bucket
/// on inserting a new node.
pub const STALE_TIME: Duration = Duration::from_secs(15 * 60);
const MIN_PING_BACKOFF_INTERVAL: Duration = Duration::from_secs(10);
pub const TOKEN_ROTATE_INTERVAL: Duration = Duration::from_secs(60 * 5);
#[derive(PartialEq)]
pub(crate) struct NodeInner {
pub(crate) id: Id,
pub(crate) address: SocketAddrV4,
pub(crate) token: Option<Box<[u8]>>,
pub(crate) last_seen: Instant,
}
impl NodeInner {
pub fn random() -> Self {
Self {
id: Id::random(),
address: SocketAddrV4::new(0.into(), 0),
token: None,
last_seen: Instant::now(),
}
}
}
#[derive(Clone, PartialEq)]
/// Node entry in Kademlia routing table
pub struct Node(pub(crate) Arc<NodeInner>);
impl Debug for Node {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Node")
.field("id", &self.0.id)
.field("address", &self.0.address)
.field("last_seen", &self.0.last_seen.elapsed().as_secs())
.finish()
}
}
impl Node {
/// Creates a new Node from an id and socket address.
pub fn new(id: Id, address: SocketAddrV4) -> Node {
Node(Arc::new(NodeInner {
id,
address,
token: None,
last_seen: Instant::now(),
}))
}
pub(crate) fn new_with_token(id: Id, address: SocketAddrV4, token: Box<[u8]>) -> Self {
Node(Arc::new(NodeInner {
id,
address,
token: Some(token),
last_seen: Instant::now(),
}))
}
/// Creates a node with random Id for testing purposes.
pub fn random() -> Node {
Node(Arc::new(NodeInner::random()))
}
/// Create a node that is unique per `i` as it has a random Id and sets IP and port to `i`
#[cfg(test)]
pub fn unique(i: usize) -> Node {
Node::new(Id::random(), SocketAddrV4::new((i as u32).into(), i as u16))
}
// === Getters ===
/// Returns the id of this node
pub fn id(&self) -> &Id {
&self.0.id
}
/// Returns the address of this node
pub fn address(&self) -> SocketAddrV4 {
self.0.address
}
/// Returns the token we received from this node if any.
pub fn token(&self) -> Option<Box<[u8]>> {
self.0.token.clone()
}
/// Node is last seen more than a threshold ago.
pub fn is_stale(&self) -> bool {
self.0.last_seen.elapsed() > STALE_TIME
}
/// Node's token was received 5 minutes ago or less
pub fn valid_token(&self) -> bool {
self.0.last_seen.elapsed() <= TOKEN_ROTATE_INTERVAL
}
pub(crate) fn should_ping(&self) -> bool {
self.0.last_seen.elapsed() > MIN_PING_BACKOFF_INTERVAL
}
/// Returns true if both nodes have the same ip and port
pub fn same_address(&self, other: &Self) -> bool {
self.0.address == other.0.address
}
/// Returns true if both nodes have the same ip
pub fn same_ip(&self, other: &Self) -> bool {
self.0.address.ip() == other.0.address.ip()
}
/// Node [Id] is valid for its IP address.
///
/// Check [BEP_0042](https://www.bittorrent.org/beps/bep_0042.html).
pub fn is_secure(&self) -> bool {
self.0.id.is_valid_for_ip(*self.0.address.ip())
}
/// Returns true if Any of the existing nodes:
/// - Have the same IP as this node, And:
/// = The existing nodes is Not secure.
/// = The existing nodes is secure And shares the same first 21 bits.
///
/// Effectively, allows only One non-secure node or Eight secure nodes from the same IP, in the routing table or ClosestNodes.
pub(crate) fn already_exists(&self, nodes: &[Self]) -> bool {
nodes.iter().any(|existing| {
self.same_ip(existing)
&& (!existing.is_secure()
|| self.id().first_21_bits() == existing.id().first_21_bits())
})
}
}