fix(client): clear TAP media before relay connect

If the Windows client is killed hard, the TAP adapter can be left in a connected
media state. A retry should not resolve or connect to the relay while stale TAP
state might still influence Windows routing.

Select and open the intended TAP adapter before relay endpoint resolution, force
its media state to disconnected, then proceed with the existing relay connect,
route pin, TAP route protection, and bridge startup flow. This also makes
missing or ambiguous TAP adapters fail before the client joins the relay room.
The README and MVP test guide now show the new startup line and the early TAP
preflight troubleshooting checks.

Test Plan:
All cargo commands used these environment variables:
RUSTUP_HOME=/tmp/softlan-vpn-rustup
CARGO_HOME=/tmp/softlan-vpn-cargo

- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-tap --tests
  --target x86_64-pc-windows-gnu
- cargo check -p lanparty-client-tap --tests
  --target x86_64-pc-windows-msvc
- cargo check -p lanparty-client-route --tests
  --target x86_64-pc-windows-gnu
- cargo check -p lanparty-client-route --tests
  --target x86_64-pc-windows-msvc
- git diff --check

Known limitation: full lanparty-client-win Windows cross-check is still blocked
on this Linux host by the external ring toolchain setup. The default GNU target
lacks x86_64-w64-mingw32-gcc, the default MSVC target lacks lib.exe, and the
LLVM MSVC attempt gets as far as ring C compilation but lacks Windows CRT
headers such as assert.h.

Refs: PLAN.md route-protection startup requirement
This commit is contained in:
2026-05-22 04:44:13 +02:00
parent abc75831cb
commit ac03bf1616
3 changed files with 35 additions and 8 deletions
+11 -8
View File
@@ -207,14 +207,17 @@ cargo run -p lanparty-client-win -- \
The Windows client binary currently connects to the relay as `role = client`
with a generated locally administered virtual MAC persisted in
`lanparty-client-identity.json`, resolves the relay DNS name before TAP
activation, completes the control-stream hello/welcome handshake, pins a host
route for the resolved relay IP on the current pre-TAP interface, verifies that
the relay route still uses that pinned host route after TAP activation, and then
bridges Ethernet frames between the relay and the first TAP-Windows6 adapter
until shutdown. `--relay` accepts a DNS name or socket address; bare hosts
default to UDP/443. Before opening the adapter, it writes the
generated tunnel MAC to the TAP driver's `NetworkAddress` registry setting.
`lanparty-client-identity.json`. Before resolving or connecting to the relay,
it selects the TAP-Windows6 adapter and marks TAP media disconnected to clear
stale connected state from a previous crashed run. It then resolves the relay
DNS name before TAP activation, completes the control-stream hello/welcome
handshake, pins a host route for the resolved relay IP on the current pre-TAP
interface, verifies that the relay route still uses that pinned host route
after TAP activation, and then bridges Ethernet frames between the relay and
the first TAP-Windows6 adapter until shutdown. `--relay` accepts a DNS name or
socket address; bare hosts default to UDP/443. Before opening the adapter for
bridging, it writes the generated tunnel MAC to the TAP driver's
`NetworkAddress` registry setting.
If the exact relay host route already exists, the client uses it and leaves it
alone on exit. The startup status reports whether the relay already has a LAN
gateway for the room.