21199edc0d
The manual MVP guide now has hardware pass conditions, but it did not give a single local command set to run before moving to Windows and the LAN. Add a short preflight section with the format, workspace test, clippy, and Linux release-build commands. The section also names what the workspace tests cover locally: DHCP-shaped, ARP-shaped, ping-shaped, UDP broadcast discovery, and gateway restart session paths. It explicitly keeps the Windows TAP driver, real LAN DHCP, switch MAC learning, and real game proof as manual acceptance work. Test Plan: - cargo fmt --check - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - cargo build --release -p lanparty-relay -p lanparty-gateway - git diff --check Refs: MVP manual test handoff
484 lines
15 KiB
Markdown
484 lines
15 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.
|
|
|
|
## Fast Path
|
|
|
|
Run the test in this order:
|
|
|
|
1. Build the relay and gateway on Linux, and build the Windows client on
|
|
Windows.
|
|
2. Start the relay and keep `relay-cert.der`.
|
|
3. Copy `relay-cert.der` to the gateway and Windows client.
|
|
4. Start the Linux gateway on the wired LAN interface.
|
|
5. Start the Windows client from an elevated terminal.
|
|
6. Verify DHCP, `ping -S`, switch MAC learning, and one LAN game.
|
|
7. Restart the gateway once while the client stays up.
|
|
|
|
## 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.
|
|
|
|
## Log Capture
|
|
|
|
Keep one log per process. They are the easiest way to diagnose a failed run.
|
|
|
|
On Linux:
|
|
|
|
```bash
|
|
./target/release/lanparty-relay ... 2>&1 | tee relay.log
|
|
sudo ./target/release/lanparty-gateway ... 2>&1 | tee gateway.log
|
|
```
|
|
|
|
On Windows PowerShell:
|
|
|
|
```powershell
|
|
Start-Transcript .\client.log
|
|
.\target\release\lanparty-client-win.exe ...
|
|
Stop-Transcript
|
|
```
|
|
|
|
## 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.
|
|
|
|
Use an elevated **x64 Native Tools Command Prompt for VS** or **Developer
|
|
PowerShell for VS** for the Windows build and client run. If the commands below
|
|
cannot find `cl`, `lib`, or `link`, install or repair Visual Studio Build Tools
|
|
with the C++ build tools and Windows SDK, then reopen the developer shell.
|
|
|
|
Quick Windows checks:
|
|
|
|
```powershell
|
|
rustc -vV
|
|
where.exe cl
|
|
where.exe lib
|
|
where.exe link
|
|
```
|
|
|
|
`rustc -vV` should report a `host` containing `x86_64-pc-windows-msvc`.
|
|
|
|
## Local Preflight
|
|
|
|
Run these before moving to the hardware test:
|
|
|
|
```bash
|
|
cargo fmt --check
|
|
cargo test --workspace
|
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
cargo build --release -p lanparty-relay -p lanparty-gateway
|
|
```
|
|
|
|
The workspace tests include real client/relay/gateway session coverage for
|
|
DHCP-shaped traffic, ARP-shaped traffic, ICMPv4 ping-shaped traffic, UDP
|
|
broadcast discovery traffic, and gateway restart lifecycle. They do not prove
|
|
the Windows TAP driver, real LAN DHCP, physical switch MAC learning, or a real
|
|
game. Those are the manual pass conditions below.
|
|
|
|
## 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
|
|
```
|
|
|
|
Then confirm the binary starts and can see TAP-Windows6:
|
|
|
|
```powershell
|
|
.\target\release\lanparty-client-win.exe --help
|
|
.\target\release\lanparty-client-win.exe --list-tap-adapters
|
|
```
|
|
|
|
The adapter list should show at least one TAP-Windows6 adapter before the full
|
|
tunnel run. If it does not, fix the TAP install first.
|
|
|
|
The binaries used below are:
|
|
|
|
```text
|
|
Linux: ./target/release/lanparty-relay
|
|
Linux: ./target/release/lanparty-gateway
|
|
Windows: .\target\release\lanparty-client-win.exe
|
|
```
|
|
|
|
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 wrote development certificate to relay-cert.der
|
|
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
|
|
relay route pinned before TAP ...
|
|
relay route verified before TAP activation ...
|
|
lanparty-client-win connecting virtual MAC ... to relay ... room ROOM1
|
|
lanparty-client-win connected as peer ...; LAN gateway connected yes (peer ...)
|
|
lanparty-client-win opened TAP adapter ...
|
|
TAP driver reports MAC ... and MTU ...
|
|
TAP interface index ... LUID ...
|
|
relay route verified after TAP activation ...
|
|
client diagnostics: relay reachable yes gateway connected yes route pinned yes ...
|
|
bridging TAP frames; relay route is pinned and TAP route policy is scoped ...
|
|
relay event: LAN gateway connected as peer ...
|
|
```
|
|
|
|
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.
|
|
You may also see TAP IPv4/IPv6 MTU, metric, and default-route protection lines
|
|
between the connect and TAP-open lines. Those are expected.
|
|
The lifecycle event may appear after the bridge starts because event logging
|
|
begins once TAP and route protection are ready.
|
|
|
|
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*"
|
|
Get-NetRoute | ? InterfaceAlias -like "*TAP*" | ft -AutoSize
|
|
```
|
|
|
|
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)
|
|
client diagnostics: relay reachable yes gateway connected no ...
|
|
Warning: 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 ...
|
|
client diagnostics: relay reachable yes gateway connected yes ...
|
|
Connected to LAN gateway
|
|
```
|
|
|
|
The diagnostics line is periodic, so it may appear up to one diagnostics
|
|
interval after the lifecycle event. After 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=-
|
|
client frame direction=RelayToTap ... action=Filtered drop_reason=UnknownDestination
|
|
```
|
|
|
|
A filtered `RelayToTap` line means the client received a relay frame but kept it
|
|
out of the TAP adapter. Occasional unrelated unicast can be normal; repeated
|
|
filtered DHCP, broadcast, or LAN-game traffic is worth investigating with the
|
|
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
|
|
- whether the relay route pin was `(created)` or `(already existed)`
|