Reach a peer through one that can reach both
Two members of a mesh could both reach a third and not each other, and that pair was simply lost to one another: a packet for a peer with no data link was counted undeliverable and dropped. Now it goes through a member that has both. What travels is not routes. Each agent says only which peers *it* has a live link with — first-hand, over the control plane, one hop, never a claim about somebody else's reachability — and everybody computes their own way through from that. The choice is local and deterministic (the lowest endpoint id among the peers that have a link to the destination), so there is nothing to agree, nothing to elect, and two agents may well route each direction differently. It is soft state: repeated while it holds, expired when it stops, so a relay that disappears stops being chosen without anybody revoking anything. The one in the middle carries bytes it cannot read. A datagram is wrapped with the peer it is for, and unwrapped on the other side into the link for the peer it came *from* — which matters, because a packet attributed to the carrier would be dropped as coming from an address the carrier does not hold. The tunnel stays end to end, and the relayed datagram goes link in, link out: it never reaches the middle's interface, so no routing, forwarding or firewall setting of that host is involved. One hop, so a loop cannot form without counting anything. A protocol is handed one link per peer that now outlives the paths under it. A direct link that dies, a hop that changes, a direct link that comes back: none of it tears down a tunnel any more, and the size a protocol may use does not change with the path. Where there was never a direct link at all, the link exists anyway as long as a hop does, so a peer reachable only through somebody still gets a tunnel. The data ALPN is `tsunagi/data/2`: every datagram now carries a tag saying whether it is direct, for somebody else, or from somebody else. The local control protocol is 13, for the relay counters — what this device carried for others is their traffic on its uplink, and that should not be invisible. `status` says `via <peer>` on a path through somebody. Fairness between the peers a relay carries for is deliberately not here yet: the queues are bounded and the counters are what a limit would be built on. Tested with fake links for the mechanics, and end to end with three real agents — two that cannot reach each other directly, a real WireGuard packet crossing through the middle. The one arrangement a single host cannot produce by itself is a pair that cannot see each other, so that is a `testing`-only switch on the agent config and exists in no release build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,16 @@ keeping the WireGuard identity, shutdown removing every interface, a forged
|
||||
overlay claim being rejected, and the core carrying the payload without
|
||||
interpreting it.
|
||||
|
||||
`crates/tsunagi/src/dataplane/relay.rs` has its own tests for the way
|
||||
through a peer in the middle: the wrapping and what a malformed one does, a
|
||||
direct path being preferred over a hop, the middle passing a datagram on
|
||||
without being handed it, what arrives through somebody reaching the peer it
|
||||
came from rather than the one that carried it, a link outliving the paths
|
||||
under it, and the datagram size not changing when the path does.
|
||||
`tests/wireguard.rs` proves it end to end — two agents that can each reach a
|
||||
third and not each other, with a real WireGuard packet crossing through the
|
||||
middle.
|
||||
|
||||
Unit tests in `crates/tsunagi/src/state/` cover the signed record model directly: tampering
|
||||
with any field breaks verification, a newer version wins while an older one
|
||||
never rolls back, two authors claiming one address resolve the same way no
|
||||
|
||||
Reference in New Issue
Block a user