Capture hard-won dev knowledge that was only in commit messages: - wsl-dev-networking: WSL2 NAT blocks UDP broadcast (device discovery can't reach the LAN); fix is mirrored networking (.wslconfig, Win11 22H2+), plus the gotchas that remained after — multiple interfaces, subnet-directed broadcast, localhost->IPv6 stall. Alternatives for non-mirrored setups. - local-dev-workflow: first-time setup, pnpm dev, and the gotchas (the strip-types dev-server hang -> tsx, the 127.0.0.1 proxy fix, .env loading, seeding into the right DB). - device-discovery: corrected the old "broadcast permission (EACCES)" note — the real cause was the lib not enabling SO_BROADCAST for global 255.255.255.255; documented the three verified broadcast gotchas + I/O serialization. - schema: add a `reference` page type; new "Dev environment" index section; log. Links lint clean; both new pages well-connected.
2.8 KiB
type, tags, sources, updated
| type | tags | sources | updated | |||||
|---|---|---|---|---|---|---|---|---|
| reference |
|
2026-06-15 |
WSL2 Dev Networking (for device testing)
Dev-environment note, not product architecture. Recorded because reaching real hardware (the uhppote-controller) from a dev box running under WSL2 took significant debugging. If you test devices from WSL, read this first.
The problem
By default WSL2 uses NAT networking: the Linux VM sits on its own virtual subnet
(e.g. 172.x), not the Windows host's LAN. Consequences for device work:
- UDP broadcast (UHPPOTE discovery) cannot leave the VM — a
get-devicesbroadcast getsEACCES/ never reaches a controller on the physical LAN. The device is reachable from Windows but not from inside WSL. - Even unicast to a LAN device may not route, depending on setup.
The fix: mirrored networking
Switch WSL to mirrored mode so it shares the Windows host's interfaces (and thus the real LAN). Requires Windows 11 22H2+ and WSL ≥ 2.0.
%UserProfile%\.wslconfig (create it; it doesn't exist by default):
[wsl2]
networkingMode=mirrored
firewall=false # Windows Firewall otherwise filters WSL traffic (can drop UDP replies)
[experimental]
hostAddressLoopback=true # host <-> WSL over the host's IP
Apply: in PowerShell wsl --shutdown, wait ~10 s, reopen WSL. Verify with ip -4 addr —
interfaces should now show the real LAN subnet (e.g. 10.0.10.x) instead of 172.x.
(Microsoft recommends editing via the WSL Settings GUI rather than the file by hand.)
wsl --shutdownkills the dev servers — restartpnpm devafterward.
After mirrored mode: app-level gotchas that remained
Mirrored networking is necessary but not sufficient — these still bit us:
- Multiple interfaces. Mirrored WSL exposes all host NICs (LAN, Tailscale/CGNAT
100.x, docker bridges). UHPPOTE discovery must broadcast on every subnet, not the first one — see device-discovery. - Subnet-directed broadcast (
10.0.10.255, not255.255.255.255) — the lib won't enableSO_BROADCASTotherwise. See device-discovery. localhost→ IPv6 first.localhostresolves to::1, but the backend binds IPv4 (127.0.0.1). Node's Vite proxy can stall on the v6 attempt before falling back — point the proxy at127.0.0.1explicitly. (See local-dev-workflow.)
Alternative if you can't use mirrored mode
Windows 10 / old WSL can't do mirrored mode. Options: run the backend natively on Windows (shares the LAN), or use unicast by IP instead of broadcast discovery (target the controller's known IP — the driver supports an explicit host). On the real appliance (a dedicated hardened Linux box, disk-os-hardening) none of this applies — it's bare-metal on the device VLAN (network-isolation).