The gateway and Windows client now pin a relay certificate, but local relay runs generated an ephemeral self-signed certificate only in memory. That made the development trust flow awkward because there was no stable DER artifact to feed into the new CLIs. Add `--dev-cert-der-out` to write the generated development certificate before the relay binds its endpoint. The file is DER-encoded and parent directories are created when needed. This keeps the production certificate/key path explicit future work while making the current pinned-trust flow usable. Test Plan: - cargo fmt --check - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - git diff --check Refs: PLAN.md relay/client trust bootstrap
3.7 KiB
softlan-vpn
Monorepo for a Layer 2 over QUIC LAN party bridge.
Workspace crates
lanparty-proto: shared frame format, MAC validation, MTU helpers.lanparty-ctrl: control-plane messages (join/hello/role/version).lanparty-obs: shared diagnostics/logging event models.lanparty-client-core: platform-agnostic client session state.lanparty-client-win: Windows TAP + route/metric handling binary.lanparty-gateway: Linux AF_PACKET gateway binary.lanparty-relay: public QUIC relay binary.
lanparty-proto
Transport-agnostic tunnel contract shared by all binaries:
- overlay datagram header encoding and decoding
- Ethernet frame header parsing
- MAC address parsing and identity validation
- QUIC datagram to TAP MTU budget helpers
lanparty-ctrl
Reliable control-plane schema shared by the QUIC stream handlers:
- endpoint hello messages with role, room, MAC, and datagram budget
- server welcome, reject, peer lifecycle, stats, and disconnect messages
- room-code, role/MAC, peer-id, and effective-MTU validation
- length-prefixed JSON control frames for reliable QUIC streams
lanparty-obs
Shared diagnostics and structured logging vocabulary:
- gateway/relay frame logs with MACs, ethertype, length, peer, and action
- tunnel counters shared by control messages and runtime diagnostics
- client connectivity/TAP diagnostics and user-facing status messages
lanparty-client-core
Platform-neutral remote client relay session:
- relay QUIC connection with pinned relay certificate trust
- client hello with room, virtual MAC, and datagram budget
- welcome/reject handling with assigned peer id and effective TAP MTU
- Ethernet frame send/receive helpers over QUIC DATAGRAM
lanparty-relay
Public relay binary and relay-owned room state:
- QUIC endpoint binding and first-stream hello/welcome admission
- room admission for clients and gateways
- one gateway per room, duplicate client MAC rejection, and room limits
- stable effective room MTU chosen before Ethernet datagrams flow
- live Ethernet datagram forwarding with no ingress reflection
- L2 safety filters for jumbo, switch-control, DHCP-server, and IPv6-RA frames
- peer leave cleanup for room membership and MAC indexes
Build
cargo check --workspace
Relay
cargo run -p lanparty-relay -- --listen 443/udp --dev-cert-der-out relay-cert.der
--listen accepts either a socket address or a UDP port shorthand such as
443/udp. The relay binds a QUIC endpoint, accepts a control-stream hello,
replies with welcome or reject, and forwards live Ethernet QUIC datagrams
between accepted peers in the same room. It currently uses a generated
self-signed development certificate; --dev-cert-der-out writes that
certificate so the gateway and client can pin it in development. Production
certificate handling remains future work.
Gateway
cargo run -p lanparty-gateway -- \
--relay 203.0.113.10:443 \
--server-name lanparty-relay.local \
--relay-ca-cert relay-cert.der \
--room ROOM1 \
--interface eth0
The gateway connects to the relay as role = gateway, completes the
control-stream hello/welcome handshake, opens an AF_PACKET socket on the LAN
interface, and bridges Ethernet frames between the relay and wired LAN until
shutdown.
Windows Client
cargo run -p lanparty-client-win -- \
--relay 203.0.113.10:443 \
--server-name lanparty-relay.local \
--relay-ca-cert relay-cert.der \
--room ROOM1 \
--virtual-mac 02:00:00:00:00:51
The Windows client binary currently connects to the relay as role = client
with the configured virtual MAC, completes the control-stream hello/welcome
handshake, and then waits for shutdown. TAP adapter binding and route pinning
are not wired yet.