feat(core): exit-node forwarding over NyUnicast - #122
Conversation
Adds explicit exit-node forwarding as a new node-to-node packet type on top of polyamide TC, reworking the earlier exit-only encapsulation in response to maintainer review on encodeous#121: - binary NodeIdBin (uint16) replaces variable-length node id strings in the on-the-wire header. The mapping is rebuilt deterministically from CentralCfg on every apply so all peers agree. - the dataplane filter reads an atomic ExitFilterSnapshot pointer instead of touching n.LocalCfg / n.CentralCfg / RouterState. The snapshot is rebuilt on the dispatch goroutine on config apply and on every route mutation, and bundles the per-node next-hop table so the filter performs a single atomic.Load per packet. - the wire format is documented in core/nylon_unicast.go as a generic NyUnicast envelope (fixed 6-byte header, subtype/hop_limit/dst/src), leaving room for future node-targeted subtypes (state query, config push) without re-inventing the encoding. LocalCfg gains AdvertiseExitNode and ExitNode; the corresponding NylonOptions overrides are wired through entrypoint.go. ComputeSysRouteTable adds 0.0.0.0/0 when ExitNode is set and excludes the default-local ranges (loopback, link-local, multicast) so they never tunnel. Tests: - state: NodeIdBin map determinism, zero reserved. - core: header round-trip, source-ownership rule, sys route table. - e2e (tagged): three-node client/relay/exit topology with ExitEncap/ExitTransit/ExitDecap traces. Refs encodeous#121
|
Thanks for the PR! I will review this over the weekend. :) Edit: I might not get to it this weekend... :( |
|
Sorry for the long delay, work has been very busy for me, and it might take another month or two to get to this PR... |
108fbd3 to
29f0dfc
Compare
|
Hi, I just got to reading this PR. I think the implementation looks sound, but I have one main concern regarding how you want to use NyUnicast. Your main application of this is in #121, where we want to be able to configure an exit node for egress. Using NyUnicast, we can indeed ensure that packets from client c -> exit node e is routed correctly. However, this is not the case for returning packets from exit node e -> client c. I can see two ways of solving this:
Lmk what you think. |
|
I am planning to implement this feature in the next major version |
Adds explicit exit-node forwarding as a new node-to-node packet type on top of polyamide TC, reworking the earlier exit-only encapsulation in response to maintainer review on #121:
binary NodeIdBin (uint16) replaces variable-length node id strings in the on-the-wire header. The mapping is rebuilt deterministically from CentralCfg on every apply so all peers agree.
the dataplane filter reads an atomic ExitFilterSnapshot pointer instead of touching n.LocalCfg / n.CentralCfg / RouterState. The snapshot is rebuilt on the dispatch goroutine on config apply and on every route mutation, and bundles the per-node next-hop table so the filter performs a single atomic.Load per packet.
the wire format is documented in core/nylon_unicast.go as a generic NyUnicast envelope (fixed 6-byte header, subtype/hop_limit/dst/src), leaving room for future node-targeted subtypes (state query, config push) without re-inventing the encoding.
LocalCfg gains AdvertiseExitNode and ExitNode; the corresponding NylonOptions overrides are wired through entrypoint.go. ComputeSysRouteTable adds 0.0.0.0/0 when ExitNode is set and excludes the default-local ranges (loopback, link-local, multicast) so they never tunnel.
Tests:
Refs #121