Give every member crate its own `[lints.clippy]` (`pedantic`, `todo`,
`unwrap_used`) and `[lints.rust]` block, add explicit `release` and
`production` profiles to the workspace manifest, and fix the code so that
`just clippy` -- `cargo clippy --workspace --all-targets --all-features
-- -D warnings` -- passes with zero warnings.
Declaring the lints is the easy half and on its own it was actively
harmful: `unsafe_code = "forbid"` cannot be overridden from source, so it
broke `lanparty-gateway`, `lanparty-client-tap`, and
`lanparty-client-route`, which all need OS FFI, and the workspace no
longer compiled on Linux at all. The rest of the workspace produced
roughly 120 denied lints. A lint policy nobody can satisfy is worse than
no policy, so this commit makes the tree actually clean.
Unsafe policy: the three FFI crates use `unsafe_code = "deny"`, and the
one module in each that holds the FFI (`gateway::packet`,
`client_tap::windows`, `client_route::windows`) opts back in with a
documented `#![allow(unsafe_code)]`. Every other crate keeps `"forbid"`.
`deny` was chosen over dropping the lint so that `unsafe` outside those
modules is still a hard error, and over per-block allows because the FFI
is dense enough that per-block attributes would drown the code.
Build profiles: `release` stays optimized but debuggable (debug info,
debug assertions, overflow checks, no LTO, incremental) so that a bug
reproduced at close-to-real speed still panics loudly and gives a usable
backtrace. `production` inherits from it and turns all of that off, adding
fat LTO and a single codegen unit, and is what ships. Note the
consequence: `cargo build --release` binaries are now slower than before
this commit and must not be shipped; use `just build-production`.
Code changes made to satisfy the lints, grouped by kind:
- `# Errors` sections on every public fallible function, and `# Panics`
on `RoomRegistry::new`. The Windows-only implementations and their
non-Windows `bail!` stubs are documented in parallel so the crates stay
clean when built for Windows too, which CI on Linux cannot check.
- Panicking paths removed rather than documented where the panic was only
an unreachable invariant: `OverlayHeader::decode` and
`declared_payload_len` take a fixed-size prefix via `first_chunk`
instead of `try_into().expect(...)`, and `RoomRegistry::join` returns an
`InternalError` reject instead of `expect`ing the room it just inserted.
- Tests keep using `unwrap`/`unwrap_err`: each crate root carries
`#![cfg_attr(test, allow(clippy::unwrap_used))]`. The lint is about
production code; an `expect` message per assertion buys nothing.
- Lossy casts replaced with `try_from` where a real conversion was
happening (datagram-size negotiation, control-frame length prefix,
MTU clamping). In `gateway::packet` the cast lints are allowed
module-wide instead: those casts move values between libc's C types
and ours after the value is already known to fit, so fallible
conversions would only add unreachable branches.
- Signature changes, all on private or crate-internal items except one:
`RoomRegistry::join` now takes `&EndpointHello` (public, it never
consumed the hello), `Room::join` and `reject_control_error` likewise.
`Room`'s `room_id` field is now `id`.
- `#[allow(clippy::too_many_lines)]` with a reason on three end-to-end
test scenarios and on `bridge_until_shutdown`, whose `select!` loop
mutates state shared by every arm; splitting it would hide that.
- Mechanical fixes from `cargo clippy --fix`: `map_or_else`, `let...else`,
inline format args, backticks in doc comments, `Duration::from_mins`.
No runtime behavior changes: the only observable differences are the
error text when a relay room lookup fails immediately after insertion
(previously a panic) and the profile rename described above.
Also documents the lint policy and the profile table in README.md, whose
build section now points at the `just` recipes it should have used all
along.
Test Plan:
- `just clippy` -- passes, zero warnings
- `just test` -- 186 tests pass, 0 failed
- `cargo check --profile production --workspace --all-features` -- passes
- `just fmt` -- clean
- Not verified: the Windows-only code paths and their doc comments, which
need a Windows target to compile.
Refs: https://doc.rust-lang.org/cargo/reference/profiles.html
Refs: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
Refs: https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes
Add a relay-server test that connects the production client-core session and the
production gateway session to the same in-process relay. The test verifies room
join catch-up, negotiated peer identities, Ethernet datagrams in both
directions, stats reporting, and room/session cleanup after graceful shutdown.
The existing relay tests covered forwarding with raw Quinn peers. This adds a
higher-level proof that the three MVP components agree on the same control and
datagram contracts before the final Windows TAP and physical LAN test.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-relay bridges_real_client_and_gateway_sessions -- --nocapture
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md Phase 1 relay/client/gateway proof
PLAN.md describes the first client flow as entering a relay domain and room
code, but the client and gateway CLIs only accepted socket-address literals.
Add a small shared RelayEndpoint parser so bare hosts default to UDP/443 while
IP literals and explicit host:port values stay supported.
The runtime configs still store resolved SocketAddr values. That keeps the
Windows route-pinning path on a concrete relay IP before TAP activation while
avoiding duplicated endpoint grammar between client and gateway. The relay
listen config reuses the same default port constant so UDP/443 has one source.
README examples now use lanparty-relay.local and document the shared endpoint
syntax.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-net
- cargo test -p lanparty-client-win \
accepts_relay_domain_with_default_port -- --nocapture
- cargo test -p lanparty-gateway \
accepts_iface_alias_for_gateway_interface -- --nocapture
- cargo test -p lanparty-net -p lanparty-client-win -p lanparty-gateway
- cargo clippy -p lanparty-net -p lanparty-client-win -p lanparty-gateway \
--all-targets -- -D warnings
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
The relay now keeps active peer sessions alongside room admission state. After
a successful hello/welcome handshake, the connection enters a datagram loop
and stays registered until the QUIC connection closes.
Incoming datagrams are only considered for forwarding when their overlay room
id, peer id, and Ethernet frame type match the peer assigned by the relay.
The relay then reuses the existing room forwarding decision logic, clones the
matching live target sessions, and sends a relay-stamped Ethernet datagram to
each connected target that can carry the frame.
This keeps spoofable wire metadata out of the trust boundary: clients can put
whatever they want in an overlay header, but the relay forwards using the
room and peer identity established during the control handshake.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
Refs: PLAN.md QUIC DATAGRAM Ethernet forwarding path
Make the relay binary bind a real Quinn endpoint instead of only printing its
configuration. This is the next runtime step toward the public relay while still
keeping connection handling out of this commit.
The relay now builds a self-signed development TLS configuration, advertises the
lanparty ALPN, enables QUIC datagram buffers, binds the configured UDP address,
prints the actual local address, and waits for Ctrl-C before closing the
endpoint. The generated certificate is explicitly a development placeholder;
production certificate and client trust handling remain future work.
The rustls dependency is pinned to the ring provider to match Quinn's selected
crypto backend and avoid process-level provider ambiguity at runtime.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- timeout 2s cargo run -p lanparty-relay -- --listen 127.0.0.1:0 || test $? -eq 124
Refs: PLAN.md public relay QUIC data path
Refs: https://docs.rs/quinn/0.11.9
Replace the placeholder relay binary with a typed command-line configuration
entry point. This gives the future QUIC server loop the listen endpoint and room
limit configuration it needs without mixing command parsing into networking or
room-state code.
The relay now accepts --listen as either a socket address or an explicit UDP
shorthand such as 443/udp, defaults to 0.0.0.0:443/udp, and validates that the
per-room client limit is positive. The binary currently reports the parsed
configuration and clearly states that the QUIC server loop is not wired yet, so
this commit does not pretend to provide a working relay.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo run -p lanparty-relay -- --listen 443/udp
Refs: PLAN.md public relay --listen requirement
Add socket-free relay forwarding logic for Ethernet datagrams. The future QUIC
relay loop can now ask the room registry which peer IDs should receive a frame
instead of embedding switching policy in network IO code.
Forwarding validates that the ingress peer belongs to the room, drops malformed
Ethernet frames, rejects client frames whose source MAC does not match the MAC
announced during admission, never reflects frames back to ingress, routes known
client unicasts directly, and floods broadcast/multicast or unknown unicast
frames to the other room peers. The decision reports shared observability action
and drop-reason values so the networking layer can log consistently.
This still does not send bytes over QUIC; it only defines the room-local switch
decision that the datagram loop will use.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
Refs: PLAN.md Switching model
Add a tested relay room layer before introducing QUIC socket handling. The relay
now has a focused place to enforce room membership rules instead of mixing those
rules into the future networking loop.
RoomRegistry accepts validated endpoint hellos, assigns room and peer IDs,
returns server welcome data, limits clients per room, permits only one gateway,
rejects duplicate client MACs, and keeps the room TAP MTU stable once the first
peer joins. A later peer must support the existing room MTU rather than silently
shrinking it after an earlier client may already have configured its TAP adapter.
The networking pieces still need to call this layer from the reliable control
stream and use the resulting peer metadata for datagram forwarding.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
Refs: PLAN.md relay responsibilities and MAC identity