edcd30f6bc
The relay welcome now carries the gateway peer id, but the first Windows client startup line still only showed whether a gateway was connected. Surface the peer id there when it is known so manual MVP testers can record it even before or without relying on a later lifecycle catch-up line. Keep the older yes/no text when a gateway is connected but the peer id is not available, which preserves useful output for older welcome payloads. Test Plan: - cargo fmt --check - cargo test -p lanparty-client-win gateway_status - cargo clippy -p lanparty-client-win --all-targets -- -D warnings - git diff --check - git diff --cached --check Refs: MVP manual validation
391 lines
11 KiB
Markdown
391 lines
11 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>
|
|
```
|
|
|
|
Keep these values from the logs as you go:
|
|
|
|
```text
|
|
gateway peer id:
|
|
client peer id:
|
|
client virtual MAC:
|
|
Windows TAP IPv4:
|
|
```
|
|
|
|
## 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`.
|
|
Start order is relay first, gateway second, Windows client last.
|
|
|
|
## 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 ...; LAN gateway connected yes (peer ...)
|
|
relay event: LAN gateway 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.
|
|
|
|
## Lifecycle Sanity Check
|
|
|
|
Run this after the basic tunnel works. It verifies that the room lifecycle is
|
|
visible to the Windows client and that a gateway restart does not leave stale
|
|
status behind.
|
|
|
|
1. Stop the gateway with Ctrl-C while the relay and client keep running.
|
|
|
|
Expected client output:
|
|
|
|
```text
|
|
relay event: LAN gateway disconnected (peer ..., Normal)
|
|
gateway connected no
|
|
Waiting for LAN gateway
|
|
```
|
|
|
|
2. Start the gateway again with the same relay, room, cert, and interface.
|
|
|
|
Expected client output:
|
|
|
|
```text
|
|
relay event: LAN gateway connected as peer ...
|
|
gateway connected yes
|
|
Connected to LAN gateway
|
|
```
|
|
|
|
After the reconnect, repeat one quick `ping -S <tap-ip> <lan-host-ip>`.
|
|
|
|
## 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 client stays on `gateway connected yes` after the gateway has stopped,
|
|
capture the relay and client lifecycle logs. The client should clear this state
|
|
from the gateway peer id it received during welcome or peer-join catch-up.
|
|
|
|
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
|
|
- lifecycle sanity-check result
|