Exit nodes on Windows: offer through WinNAT; using is refused

Windows reported exit nodes as unsupported. The offering side now creates one
WinNAT object per offered range (New-NetNat, named tsunagi-exit:<if>:<range>),
prunes this interface's stale ones, reads (never writes) IPv4 forwarding of
the overlay interface, and removes everything on clear. All values are
single-quoted PowerShell literals.

The using side is deliberately not implemented: Windows has no per-user or
per-process routing, so the agent's own QUIC/relay traffic cannot be kept out
of a default route through the overlay and would loop. It reports that reason
and installs no route. The CLI/tray forwarding hint and the kernel-forwarding
warning name the Windows command; docs/exit-node.md has a Windows section.

Checks: cargo fmt --check, cargo clippy --locked --workspace --all-targets
-D warnings and cargo test --locked --workspace --all-targets passed on macOS.
The script builders and plan logic are unit-tested with an injected runner on
every platform; nothing was run against a real Windows host or cross-compiled
(no Windows target installed).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
UltradesuandClaude Sonnet 5.5 committed 2026-10-03 12:33:22 +01:00
1 parent 47c5d38d0c
commit 637915600e
7 files changed
+343 -5

No files matched your search

+3 -1
View File
@@ -400,7 +400,9 @@ impl Interface {
interface = %self.name,
"kernel forwarding is off for this interface, so nothing is forwarded for the \
exit node yet: {}",
if cfg!(target_os = "macos") {
if cfg!(target_os = "windows") {
"`Set-NetIPInterface -Forwarding Enabled` on the interfaces involved"
} else if cfg!(target_os = "macos") {
"`sysctl -w net.inet.ip.forwarding=1`, set again after every reboot"
} else {
"`sysctl -w net.ipv4.ip_forward=1` (or `net.ipv4.conf.<interface>.forwarding=1`), \