bd22a68a6f
The MVP tunnel negotiates an effective TAP MTU and configures the Windows TAP IP interface to that value, but the forwarding path only rejected frames that were standard-Ethernet jumbo frames or exceeded the QUIC datagram budget. A frame could therefore be larger than the negotiated TAP MTU while still fitting inside the QUIC datagram budget. Make the TAP-MTU frame limit an explicit shared protocol helper and enforce it at every data-path boundary: Windows client send/receive, Linux gateway send/receive, and relay forwarding. Such frames now produce TapMtuExceeded in logs and counters instead of being forwarded until a later layer drops or accepts them implicitly. This keeps the no-fragmentation contract honest: one Ethernet frame still maps to one QUIC datagram, but only if that frame also fits the room's negotiated TAP MTU. Test Plan: - cargo fmt --check - cargo test -p lanparty-proto tap_mtu - cargo test -p lanparty-client-core connects_to_relay_control_stream_as_client - cargo test -p lanparty-gateway connects_to_relay_control_stream_as_gateway - cargo test -p lanparty-relay drops_frames_above_effective_tap_mtu - cargo test -p lanparty-relay rate_limits_client_total_bandwidth_after_burst - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - cargo build --release -p lanparty-relay -p lanparty-gateway - git diff --check - git diff --cached --check Refs: MVP no-fragmentation tunnel MTU contract
347 lines
10 KiB
Markdown
347 lines
10 KiB
Markdown
# MVP Test Guide
|
|
|
|
This guide is for the manual end-to-end MVP proof:
|
|
|
|
```text
|
|
Windows TAP client -> public QUIC relay -> Linux AF_PACKET gateway -> LAN
|
|
```
|
|
|
|
The MVP is intentionally manual. It does not include an installer, GUI,
|
|
production certificates, auth, or end-to-end payload encryption.
|
|
|
|
## MVP Pass Conditions
|
|
|
|
The MVP proof is successful when all of these are true:
|
|
|
|
- Relay shows one gateway peer and one Windows client peer in the same room.
|
|
- Windows client reports `gateway connected yes`.
|
|
- Windows TAP adapter gets a real LAN DHCP address, not only `169.254.x.x`.
|
|
- A LAN host can be reached from the TAP address with `ping -S`.
|
|
- The physical switch learns the Windows client MAC on the Linux gateway port.
|
|
- A LAN game can discover or join a server through the TAP adapter.
|
|
|
|
Fill these in before starting so the commands below are just copy/edit/run:
|
|
|
|
```text
|
|
relay host: relay.example.net
|
|
relay UDP port: 8443
|
|
room code: ROOM1
|
|
gateway iface: eth0
|
|
LAN test host: <lan-host-ip>
|
|
```
|
|
|
|
## Machines
|
|
|
|
- Relay: public Linux host reachable over UDP.
|
|
- Gateway: Linux machine plugged into the LAN party switch with wired Ethernet.
|
|
- Client: Windows 11 machine with TAP-Windows6 installed.
|
|
|
|
Use the same room code everywhere, for example `ROOM1`.
|
|
|
|
## Build Prerequisites
|
|
|
|
On Windows, use the Rust MSVC toolchain and install Visual Studio Build Tools
|
|
with the C++ build tools. The dependency stack includes native code, so tools
|
|
such as `cl.exe` and `lib.exe` must be available in the build environment.
|
|
TAP-Windows6 must be installed before running the client.
|
|
|
|
Quick Windows checks:
|
|
|
|
```powershell
|
|
rustc -vV
|
|
where.exe cl
|
|
where.exe lib
|
|
```
|
|
|
|
`rustc -vV` should report a `host` containing `x86_64-pc-windows-msvc`.
|
|
|
|
## Build
|
|
|
|
On the relay or Linux build host:
|
|
|
|
```bash
|
|
cargo build --release -p lanparty-relay -p lanparty-gateway
|
|
```
|
|
|
|
On Windows, in an Administrator terminal:
|
|
|
|
```powershell
|
|
cargo build --release -p lanparty-client-win
|
|
```
|
|
|
|
The Windows client must run elevated because it opens TAP and edits routes.
|
|
The gateway usually needs root because it opens an AF_PACKET raw socket.
|
|
|
|
## Start The Relay
|
|
|
|
Use a high UDP port first unless you already want to deal with privileged
|
|
`443/udp` binding:
|
|
|
|
```bash
|
|
./target/release/lanparty-relay \
|
|
--listen 0.0.0.0:8443 \
|
|
--dev-cert-der-out relay-cert.der
|
|
```
|
|
|
|
Open inbound UDP for the selected port on the relay host firewall.
|
|
|
|
Expected relay output:
|
|
|
|
```text
|
|
lanparty-relay configured for 0.0.0.0:8443/udp ...
|
|
lanparty-relay listening on 0.0.0.0:8443
|
|
```
|
|
|
|
Copy `relay-cert.der` to the gateway and Windows client. The development
|
|
certificate is for `lanparty-relay.local`, so keep
|
|
`--server-name lanparty-relay.local` even when `--relay` is an IP address or
|
|
another DNS name.
|
|
|
|
## Start The Gateway
|
|
|
|
On the LAN gateway machine:
|
|
|
|
```bash
|
|
sudo ./target/release/lanparty-gateway \
|
|
--relay relay.example.net:8443 \
|
|
--server-name lanparty-relay.local \
|
|
--relay-ca-cert ./relay-cert.der \
|
|
--room ROOM1 \
|
|
--interface eth0
|
|
```
|
|
|
|
Use the real wired LAN interface name for `--interface`. `--iface` is accepted
|
|
as a shorter alias. Do not use Wi-Fi. The gateway fails before joining the
|
|
relay if sysfs reports no Ethernet carrier.
|
|
|
|
Expected gateway output:
|
|
|
|
```text
|
|
lanparty-gateway opening interface eth0 and connecting to relay ...
|
|
lanparty-gateway opened AF_PACKET socket on eth0 ...
|
|
lanparty-gateway connected as peer ...
|
|
lanparty-gateway bridging frames; press Ctrl-C to stop
|
|
```
|
|
|
|
Expected relay output:
|
|
|
|
```text
|
|
accepted Gateway peer ... in room ROOM1 ...
|
|
```
|
|
|
|
Leave this running before starting the Windows client.
|
|
|
|
## Start The Windows Client
|
|
|
|
In an Administrator terminal on Windows:
|
|
|
|
```powershell
|
|
.\target\release\lanparty-client-win.exe `
|
|
--relay relay.example.net:8443 `
|
|
--server-name lanparty-relay.local `
|
|
--relay-ca-cert .\relay-cert.der `
|
|
--room ROOM1
|
|
```
|
|
|
|
If the Windows machine has multiple TAP-Windows6 adapters, select the intended
|
|
one explicitly:
|
|
|
|
```powershell
|
|
.\target\release\lanparty-client-win.exe --list-tap-adapters
|
|
|
|
.\target\release\lanparty-client-win.exe `
|
|
--relay relay.example.net:8443 `
|
|
--server-name lanparty-relay.local `
|
|
--relay-ca-cert .\relay-cert.der `
|
|
--room ROOM1 `
|
|
--tap-instance-id "{InterfaceGuid-from-the-command-above}"
|
|
```
|
|
|
|
Expected client output:
|
|
|
|
```text
|
|
prepared TAP adapter ... MAC ... configured and media disconnected before relay connect
|
|
lanparty-client-win connected as peer ...
|
|
relay route pinned before TAP ...
|
|
relay route verified after TAP activation ...
|
|
TAP driver reports MAC ... and MTU ...
|
|
client diagnostics: relay reachable yes gateway connected yes route pinned yes ...
|
|
```
|
|
|
|
The route pin line ends with `(created)` or `(already existed)`. Either is OK.
|
|
`already existed` usually means a matching relay host route was already present,
|
|
for example after a previous crashed test run.
|
|
|
|
The first diagnostics line may show `IP unknown`. After DHCP succeeds, a later
|
|
line should show:
|
|
|
|
```text
|
|
DHCP received: 10.x.x.x
|
|
```
|
|
|
|
If Windows reports both a `169.254.x.x` TAP address and a real LAN IPv4
|
|
address, the client diagnostics should prefer the real LAN address.
|
|
|
|
## Verify The Tunnel
|
|
|
|
1. Relay sees both peers:
|
|
|
|
```text
|
|
accepted Gateway peer ...
|
|
accepted Client peer ...
|
|
```
|
|
|
|
2. Client sees the gateway:
|
|
|
|
```text
|
|
gateway connected yes
|
|
Connected to LAN gateway
|
|
```
|
|
|
|
3. Windows TAP gets an address from the LAN:
|
|
|
|
```powershell
|
|
Get-NetIPAddress | ? InterfaceAlias -like "*TAP*"
|
|
```
|
|
|
|
Use the non-link-local IPv4 address as `<tap-ip>` in the next step.
|
|
|
|
4. ARP and ping work from the TAP-side address:
|
|
|
|
```powershell
|
|
arp -d *
|
|
ping -S <tap-ip> <lan-host-ip>
|
|
arp -a
|
|
```
|
|
|
|
5. The LAN switch learns the remote client MAC on the gateway port.
|
|
|
|
Use the switch UI or CLI and look for the client MAC printed by the Windows
|
|
client. It should appear on the physical port connected to the Linux gateway.
|
|
|
|
6. A real LAN game discovers or joins a LAN server.
|
|
|
|
This is the practical MVP acceptance test.
|
|
|
|
## Useful Log Signals
|
|
|
|
Relay frame forwarding:
|
|
|
|
```text
|
|
relay frame room=ROOM1 ... action=Forwarded drop_reason=- targets=1
|
|
```
|
|
|
|
Gateway LAN traffic:
|
|
|
|
```text
|
|
gateway control event: client peer ... joined with MAC ...
|
|
gateway frame interface=eth0 direction=LanToRemote ... action=Forwarded
|
|
gateway frame interface=eth0 direction=RemoteToLan ... action=Forwarded
|
|
gateway CAM refresh interface=eth0 peer_id=... mac=... reason=peer_joined
|
|
gateway CAM refresh interface=eth0 peer_id=... mac=... reason=periodic
|
|
```
|
|
|
|
Client health:
|
|
|
|
```text
|
|
Relay RTT: 23 ms
|
|
Broadcast traffic flowing
|
|
Broadcast sent toward LAN; waiting for LAN broadcast reply
|
|
LAN broadcast received
|
|
client frame direction=TapToRelay ... action=Forwarded drop_reason=-
|
|
client frame direction=RelayToTap ... action=Forwarded drop_reason=-
|
|
```
|
|
|
|
Drops that can be normal during testing:
|
|
|
|
```text
|
|
drop_reason=UnknownDestination
|
|
drop_reason=TapMtuExceeded
|
|
drop_reason=DatagramBudget
|
|
drop_reason=RateLimit
|
|
```
|
|
|
|
On gateway `LanToRemote` logs, `UnknownDestination` usually means the gateway
|
|
captured unrelated LAN unicast and dropped it locally instead of sending it to
|
|
the relay.
|
|
`TapMtuExceeded` means a host emitted an Ethernet frame larger than the
|
|
negotiated tunnel MTU; occasional drops can happen while testing software that
|
|
does not honor the smaller adapter MTU yet.
|
|
|
|
Drops that should be investigated if they dominate:
|
|
|
|
```text
|
|
drop_reason=Malformed
|
|
drop_reason=InvalidSourceMac
|
|
drop_reason=UnauthorizedSourceMac
|
|
drop_reason=ControlPlaneEtherType
|
|
drop_reason=VlanTaggedFrame
|
|
drop_reason=DhcpServerReply
|
|
drop_reason=Ipv6RouterAdvertisement
|
|
drop_reason=Ipv6Fragment
|
|
```
|
|
|
|
On gateway `RemoteToLan` logs, `UnauthorizedSourceMac` means the relayed peer id
|
|
did not match the client MAC announced by lifecycle events. If it repeats,
|
|
check relay lifecycle logs and duplicate-MAC rejection first.
|
|
|
|
## Troubleshooting
|
|
|
|
If the client says `Waiting for LAN gateway`, check that the gateway uses the
|
|
same room code and is connected to the same relay.
|
|
|
|
If the gateway fails with `reports no carrier`, plug the selected Ethernet
|
|
interface into the LAN party switch, bring the interface up, and restart the
|
|
gateway.
|
|
|
|
If startup fails before the relay connection while preparing the TAP adapter,
|
|
check that the terminal is elevated, TAP-Windows6 is installed, and
|
|
`--tap-instance-id` selects the intended adapter when more than one TAP adapter
|
|
exists.
|
|
|
|
If the client says `Waiting for TAP IP`, DHCP is not making the full round trip.
|
|
Check relay/gateway frame logs for broadcast traffic and check that the gateway
|
|
is on wired Ethernet.
|
|
|
|
If the client reports a TAP link-local address such as `169.254.x.x`, treat it
|
|
the same way: Windows has self-assigned an address, but LAN DHCP did not
|
|
complete through the tunnel.
|
|
|
|
If startup fails with a TAP MAC mismatch, disable/enable the TAP adapter or
|
|
reinstall TAP-Windows6 so Windows reloads the `NetworkAddress` value. Do not
|
|
continue with a mismatched MAC.
|
|
|
|
If startup says the relay route changed, stop. The client is refusing to run
|
|
because Windows would route the relay connection through the tunnel.
|
|
|
|
If ping fails but DHCP worked, check Windows firewall, the target LAN host
|
|
firewall, and whether the LAN subnet conflicts with the client's home LAN.
|
|
Uncommon LAN subnets such as `10.73.42.0/24` are safer than `192.168.0.0/24`.
|
|
|
|
If switch MAC learning does not show the Windows client MAC on the gateway
|
|
port, look for `gateway CAM refresh ... reason=peer_joined` immediately after
|
|
join and `gateway CAM refresh ... reason=periodic` about once per minute after
|
|
that. If those lines are present but the switch still does not learn it, check
|
|
the selected gateway interface and switch port first.
|
|
|
|
## Cleanup
|
|
|
|
Stop client, gateway, and relay with Ctrl-C. The Windows client removes the
|
|
relay host route only when it created that route itself, restores the TAP route
|
|
policy, and marks TAP media disconnected when it exits normally.
|
|
|
|
Keep `lanparty-client-identity.json` if you want the same virtual MAC on the
|
|
next run. Delete it only when you intentionally want a new client identity.
|
|
|
|
## Report Back
|
|
|
|
For a useful test report, capture:
|
|
|
|
- relay command and relay logs
|
|
- gateway command and gateway logs
|
|
- client command and client logs
|
|
- Windows TAP MAC and IP
|
|
- ping result from `<tap-ip>` to a LAN host
|
|
- switch MAC-table entry for the Windows client MAC
|
|
- LAN game discovery or join result
|