Install broadcast route and firewall allowance on the host while broadcast is on
LAN discovery (CS 1.6 and similar) only worked after two manual steps on every host: route 255.255.255.255 through the TUN, and allow inbound traffic on it. Without the route the game's limited broadcast leaves via the physical adapter and never reaches the overlay; without the firewall allowance the server's unicast reply (from a different address than the one the request went to, so never matched by conntrack) is dropped before the game's socket. Verified by hand on Linux: with both in place the server answered A2S_INFO over the overlay. The system level (not a plugin) now installs exactly those two things for the interface it owns, and removes them when broadcast is turned off, the network is left or stopped, or the agent exits. Design: - New boundary overlay::hostrules (BroadcastHostRules: idempotent apply/clear, with Linux, Windows, Mock and Unsupported implementations). TunFactory gains host_rules(); ManagedTunFactory::with_host_rules wires it in the CLI. - Interface::sync_broadcast_rules reconciles the host against the routing table (RoutingTable::broadcast_host_target) and is called after address sync, on live `network broadcast on/off`, on network deactivation and by remove(). Failure is contained: the outcome is kept and logged, never fatal. - One interface carries several networks but the host has one 255.255.255.255 route, so the source is the lowest NetworkId among broadcast-enabled networks with an address (documented in docs/broadcast.md). - Linux: the route is added on the existing netlink thread (preferred source = overlay address, replace semantics). The firewall rule is `iptables -I INPUT -i <if> -p udp -s <overlay range>` tagged with a comment `tsunagi:<if>`; it is UDP-only and range-limited on purpose so TCP services stay unexposed. iptables is located in fixed system directories, never via PATH; stale tagged rules (e.g. from a crash) are replaced. A missing iptables leaves the route in place and is reported. rp_filter is not touched. - Windows: PowerShell (absolute path) New-NetRoute metric 1 and a tagged inbound UDP Defender rule scoped to the interface alias and overlay range. - status shows a `broadcast rules` row (ok, or which half failed and why). IPC control protocol bumped 14 -> 15 because OverlayReport gained a field. - AGENTS.md records the narrow exception to "never touch routing/firewall". Compatibility: restart the agent after upgrading (control protocol 15). No wire or schema change. Checks run (Linux only): cargo fmt --check, cargo clippy --locked --workspace --all-targets -D warnings, cargo test --locked --workspace --all-targets, all passing. Tests use a mock host and a scripted iptables; no OS setting is changed. NOT done: the Windows code was never compiled for or run on Windows (cross-compiling failed for lack of a C toolchain), only its script building is unit-tested; the real netlink route and iptables calls were not exercised against a live kernel in the suite; CS 1.6 was not launched from this change.
This commit is contained in:
1 parent
d2778f0b5a
commit
533921059a
18 files changed
+1834
-23
No files matched your search
+38
-4
@@ -61,13 +61,47 @@ routers cannot inspect another pair's encrypted IP payload.
|
||||
|
||||
## Host behavior and verification
|
||||
|
||||
The game must send discovery through the Tsunagi interface. Traffic bound to a
|
||||
physical adapter never reaches this TUN, and this feature does not capture it.
|
||||
A game's discovery packet only reaches Tsunagi if the operating system sends it
|
||||
through the Tsunagi interface, and its reply only reaches the game if the host
|
||||
firewall admits it. While a network has broadcast on, the agent installs
|
||||
exactly two things for the interface it owns, and removes them when broadcast
|
||||
is turned off, the network is left or stopped, or the agent exits:
|
||||
|
||||
- **Route** `255.255.255.255/32` through the overlay interface, with the
|
||||
overlay address as its source (Linux: netlink, `ip route add 255.255.255.255/32
|
||||
dev tsun0 src <overlay-ip>`; Windows: `New-NetRoute`, metric 1, active store).
|
||||
Limited broadcasts from every program then go to the overlay and not to the
|
||||
physical LAN while this is installed; this is the price of the feature.
|
||||
- **Firewall allowance** for inbound **UDP only**, from the overlay range only,
|
||||
on that interface only (Linux: an `iptables -I INPUT` rule tagged
|
||||
`tsunagi:<interface>`; Windows: a Defender rule of that name). Replies to a
|
||||
broadcast come from another address than the request went to, so a stateful
|
||||
firewall never matches them to it. TCP services such as SSH stay unexposed.
|
||||
|
||||
Both are tagged, idempotent and reversible, and are never derived from a remote
|
||||
announcement. A rule left by a crashed run is replaced on the next apply. If
|
||||
`iptables` is missing (for example a host with only `nft`) or the process is not
|
||||
privileged, the route is still installed and `status` prints a
|
||||
`broadcast rules` line saying which half is missing and why. To undo it all,
|
||||
turn broadcast off for the network: `tsunagi network broadcast <network> off`.
|
||||
|
||||
**One interface, several networks.** The host has one `255.255.255.255` route
|
||||
per interface, so only one overlay address can be its source. The lowest network
|
||||
id among broadcast-enabled networks with an address is used; `status` says when
|
||||
that is not the network being shown. Directed broadcasts (`10.13.37.255`) follow
|
||||
the ordinary connected route and are not affected.
|
||||
|
||||
**What it cannot fix.** A game that binds its socket to a physical address or
|
||||
device, or sends to the physical subnet's broadcast address, still bypasses the
|
||||
TUN. The Windows implementation could not be run while it was written; its
|
||||
scripts are unit-tested only.
|
||||
|
||||
The suite tests real agents, authenticated iroh links and WireGuard encryption
|
||||
with memory TUNs: limited/directed UDP discovery, multihop fanout, single-copy
|
||||
delivery, opt-out, unicast replies, malformed input, source validation and
|
||||
network isolation. It does not launch CS 1.6 or Warcraft III or establish that
|
||||
every game/host chooses the virtual adapter automatically.
|
||||
network isolation. Host rules are tested through a mock host and a scripted
|
||||
`iptables`; the default suite changes no OS setting. It does not launch CS 1.6 or
|
||||
Warcraft III.
|
||||
|
||||
## Future exported LANs
|
||||
|
||||
|
||||
Reference in new issue
Block a user