The Windows client now verifies that the relay path still uses the pinned host
route after the TAP adapter is activated, and keeps checking that invariant
while frames are being bridged. If Windows starts choosing a different prefix,
next hop, or interface for the relay IP, the client exits instead of silently
letting the tunnel route itself through the TAP side.
This closes the remaining detection half of the route-protection startup flow
from PLAN.md. The previous commits installed the pre-TAP host route, scoped TAP
metrics, and disabled TAP default routes; this commit proves those protections
are still winning after TAP activation and catches later DHCP-driven route
changes during the session.
The route crate now exposes small helpers for route-interface identity and host
route matching so the client does not duplicate route-prefix semantics inline.
The full Windows client target check still cannot complete on this Linux host:
`ring` fails while compiling for `x86_64-pc-windows-msvc` because the Windows C
header `assert.h` is unavailable, before `lanparty-client-win` is typechecked.
The independent Windows-target route crate checks do pass.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
The Windows route helper now supports a scoped DisableDefaultRoutes override
for an IP interface family. The guard snapshots the existing interface row,
sets the requested default-route disabled state, and restores the previous
state when dropped.
This is the route-crate half of neutralizing TAP default-route takeover from
PLAN.md. It intentionally does not wire the client yet, so the public API can
be reviewed independently from the client startup behavior.
The implementation keeps metric restoration and default-route restoration
separate even though both read the same IP interface row. That avoids one guard
accidentally reverting the other guard's setting when the Windows client holds
both at the same time.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-client-route
- cargo clippy -p lanparty-client-route --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
Add a reversible IP interface metric boundary to `lanparty-client-route`. The
crate can now read an IPv4 or IPv6 interface metric snapshot and temporarily set
a manual interface metric with an RAII guard that restores the previous metric
and automatic-metric state on drop.
This prepares the TAP metric handling without wiring policy into the Windows
client yet. Default-route disabling is captured in snapshots for diagnostics and
future decisions, but this slice deliberately changes only `UseAutomaticMetric`
and `Metric`.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
Refs: https://learn.microsoft.com/en-us/windows-hardware/drivers/network/initializeipinterfaceentry
Refs: https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-setipinterfaceentry
Add a small route-crate API that resolves a Windows network adapter GUID into
its interface LUID and index. The TAP adapter discovery already gives us the
NetCfgInstanceId GUID, and the route/metric work needs the corresponding IP
interface identity before it can safely inspect or adjust TAP metrics.
The implementation keeps GUID parsing local and dependency-free, then delegates
the actual identity lookup to Windows IP Helper calls. Non-Windows builds expose
the same API shape with a clear unsupported-platform error.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
Add the first route-table mutation API to `lanparty-client-route`. Given the
pre-TAP best-route snapshot, the crate can now create a host route for the relay
IP on that same interface and return an RAII guard that deletes the route when
it is dropped.
The route row is initialized with `InitializeIpForwardEntry`, uses a /32 or
/128 destination prefix for the relay IP, preserves the pre-TAP interface
index/LUID, and uses the remembered next hop or an on-link unspecified next hop
when Windows reported no gateway. The guard tracks whether creation actually
succeeded so pure row-construction tests and failed creates do not try to delete
routes they did not install.
This remains a crate-level boundary only. The Windows client still reports the
pre-TAP route but does not yet hold a pin across TAP activation; that is the
next integration slice.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-client-route
- cargo clippy -p lanparty-client-route --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc --all-targets -- -D warnings
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
Refs: https://learn.microsoft.com/en-us/windows-hardware/drivers/network/createipforwardentry2
Refs: https://learn.microsoft.com/en-us/windows-hardware/drivers/network/initializeipforwardentry
Add `lanparty-client-route` as the Win32 boundary for route-table work. The
first API is intentionally read-only: `best_route_to` wraps `GetBestRoute2`
and returns the selected source address, next hop, route prefix, interface
index/LUID, and route metric for a relay destination IP.
This keeps the route-protection work separate from the QUIC client binary, so
we can typecheck the Windows IP Helper calls on this Linux host without pulling
in the `ring` build path that currently blocks full Windows binary checks.
Actual route pinning and metric mutation remain later slices.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-route --target x86_64-pc-windows-msvc -- -D warnings
- git diff --check
Refs: PLAN.md