fix(client): verify relay route before TAP activation

The Windows client pinned the relay host route before opening TAP, but only
verified that Windows was actually using that host route after TAP activation.
If an existing route or pinning failure prevented the host route from becoming
the active relay path, the client could discover that only after touching TAP
route policy.

Verify the pinned host route immediately after installing/reusing it, before
opening the TAP adapter. Keep the existing after-activation verification as the
runtime guard against TAP route takeover, and document the new expected startup
log line in the MVP guide.

Test Plan:
- cargo fmt --check
- cargo test -p lanparty-client-win
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- git diff --check
- git diff --cached --check

Windows-target check attempted:
- cargo check -p lanparty-client-win --target x86_64-pc-windows-msvc

With LLVM tools configured, that still stops inside ring on this Linux host
because the Windows C headers are unavailable, starting with assert.h.

Refs: MVP relay-route protection
This commit is contained in:
2026-05-22 07:55:02 +02:00
parent 81878133d2
commit ec82cae981
3 changed files with 11 additions and 7 deletions
+6 -3
View File
@@ -276,7 +276,7 @@ async fn run_client(
let relay_route =
verify_relay_route_is_pinned(session.config().relay_addr().ip(), relay_route_pin)
.context("relay route changed after TAP activation")?;
print_verified_relay_route(&relay_route);
print_verified_relay_route("after TAP activation", &relay_route);
print_and_report_client_diagnostics(
session,
&client_diagnostics_snapshot(
@@ -370,6 +370,9 @@ fn pin_relay_route_before_tap(destination: std::net::IpAddr) -> Result<PinnedRel
let pin = lanparty_client_route::pin_relay_route(&route)
.context("failed to pin relay route before TAP activation")?;
print_pinned_relay_route(&pin);
let route = verify_relay_route_is_pinned(destination, &pin)
.context("relay route did not use pinned host route before TAP activation")?;
print_verified_relay_route("before TAP activation", &route);
Ok(pin)
}
@@ -445,9 +448,9 @@ fn relay_route_matches_pin(route: &RouteSnapshot, pin: &PinnedRelayRoute) -> boo
}
#[cfg(windows)]
fn print_verified_relay_route(route: &RouteSnapshot) {
fn print_verified_relay_route(phase: &str, route: &RouteSnapshot) {
println!(
"relay route verified after TAP activation: destination {} next hop {} interface index {} LUID {} prefix {}/{} metric {}",
"relay route verified {phase}: destination {} next hop {} interface index {} LUID {} prefix {}/{} metric {}",
route.destination(),
route_next_hop_label(route.next_hop()),
route.interface_index(),