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
The MVP tunnel negotiates an effective TAP MTU and configures the Windows TAP IP
interface to that value, but the forwarding path only rejected frames that were
standard-Ethernet jumbo frames or exceeded the QUIC datagram budget. A frame
could therefore be larger than the negotiated TAP MTU while still fitting inside
the QUIC datagram budget.
Make the TAP-MTU frame limit an explicit shared protocol helper and enforce it
at every data-path boundary: Windows client send/receive, Linux gateway
send/receive, and relay forwarding. Such frames now produce TapMtuExceeded in
logs and counters instead of being forwarded until a later layer drops or
accepts them implicitly.
This keeps the no-fragmentation contract honest: one Ethernet frame still maps
to one QUIC datagram, but only if that frame also fits the room's negotiated TAP
MTU.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-proto tap_mtu
- cargo test -p lanparty-client-core connects_to_relay_control_stream_as_client
- cargo test -p lanparty-gateway connects_to_relay_control_stream_as_gateway
- cargo test -p lanparty-relay drops_frames_above_effective_tap_mtu
- cargo test -p lanparty-relay rate_limits_client_total_bandwidth_after_burst
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo build --release -p lanparty-relay -p lanparty-gateway
- git diff --check
- git diff --cached --check
Refs: MVP no-fragmentation tunnel MTU contract
The MVP overlay reserves its flags field for later features such as
fragmentation or payload encryption, but version 1 does not define any flag
semantics. Accepting nonzero flags would let unknown behavior silently traverse
the relay and reach the tunnel endpoints.
Make zero the only valid v1 flag value. Overlay encoding and decoding now reject
reserved nonzero flags, production send paths use the explicit
OVERLAY_FLAGS_NONE constant, and the relay emits forwarded datagrams with the
same zero-flag policy instead of preserving peer-supplied bits.
Document the reserved-flag rule in the protocol crate overview.
Test Plan:
- cargo test -p lanparty-proto overlay
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo fmt --check
- git diff --check
Refs: PLAN.md no-fragmentation MVP overlay format
Safety filtering now applies at several tunnel boundaries. The relay remains
the trust boundary, while the client and gateway also drop unsafe frames before
spending relay bandwidth. Duplicating EtherType and IPv4/IPv6 parsers across
crates would make those rules drift as the MVP grows.
Move the Ethernet safety classifiers into lanparty-proto, expose typed safety
drop reasons, and map them back into the existing DropReason vocabulary. The
relay now uses the shared client and gateway classifiers, the gateway keeps its
local LAN-send drops through the shared classifier, and the client drops the
same remote-to-LAN safety cases before QUIC DATAGRAM encoding.
Document the client-side local drops and list the additional suspicious drop
reasons in the manual MVP test guide.
Test Plan:
- cargo test -p lanparty-proto safety
- cargo test -p lanparty-client-core connects_to_relay_control_stream_as_client
- cargo test -p lanparty-gateway connects_to_relay_control_stream_as_gateway
- cargo test -p lanparty-relay
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check -p lanparty-client-tap --target x86_64-pc-windows-gnu --tests
- cargo check -p lanparty-client-route --target x86_64-pc-windows-gnu --tests
- cargo check -p lanparty-client-tap --target x86_64-pc-windows-msvc --tests
- cargo check -p lanparty-client-route --target x86_64-pc-windows-msvc --tests
- git diff --check
Refs: PLAN.md safety filters and client source-MAC isolation
PLAN.md keeps MVP traffic to one Ethernet frame per QUIC datagram with no
fragmentation. The relay already negotiates a datagram budget, but the client
and gateway send paths still relied on Quinn to reject oversized encoded
Ethernet datagrams.
Add a shared protocol validation helper for encoded datagram length versus the
negotiated QUIC budget. Thread the negotiated budget into client and gateway
send boundaries, reject oversized datagrams before send, and count those valid
but unsent frames as local drops.
Document the budget check in the workspace decomposition and gateway behavior.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-proto -p lanparty-client-core -p lanparty-gateway
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
Build the shared protocol contract that the client, gateway, and relay will use
for Ethernet datagrams. The MVP needs these pieces agreed on before socket or
TAP work can be reasoned about safely.
This adds strict MAC parsing and client identity validation, Ethernet header
inspection, fixed overlay datagram encoding and decoding, and MTU helpers for
the no-fragmentation QUIC datagram design. The protocol crate stays
transport-agnostic so platform and network code can depend on it without
pulling in OS-specific behavior.
Remaining work is to put these primitives behind the control-plane handshake,
relay forwarding loop, Windows TAP client, and Linux AF_PACKET gateway.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
Refs: PLAN.md Phase 1: prove the illusion