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 Windows client reads TAP frames and then applies the same local safety path
used for malformed, jumbo, over-MTU, and forbidden remote-client traffic. The
read buffer was only one standard Ethernet frame long, which made an oversized
TAP frame more likely to fail at the device-read boundary before the client
could count and log the drop.
Keep the accepted Ethernet-frame limit unchanged, but make the TAP read buffer
large enough to receive oversized frames and let the existing safety checks
reject them in the normal path. Document the distinction in the TAP crate
summary.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-client-tap -p lanparty-client-win
- cargo check -p lanparty-client-tap --target x86_64-pc-windows-msvc
- cargo clippy -p lanparty-client-tap -p lanparty-client-win \
--all-targets -- -D warnings
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
- git diff --cached --check
Refs: MVP TAP drop diagnostics
The Windows client already generates and announces a stable locally administered
MAC, but it only rejected the TAP adapter when the driver reported a different
address. Persist the tunnel MAC to tap-windows6's NetworkAddress registry value
before opening the adapter so the driver can load the intended current address.
The TAP crate now keeps the driver registry key name from discovery, formats the
NetworkAddress value as the 12-digit hex string expected by NDIS, and rejects
invalid multicast, broadcast, or globally administered MACs before writing.
Runtime validation stays in place. tap-windows6 reads NetworkAddress during
adapter initialization, so an adapter that Windows already initialized with an
old value may still need disable/enable or reinstall on the real Windows test
machine before the GET_MAC ioctl reports the new identity.
Test Plan:
- cargo fmt --check
- cargo test -p lanparty-client-tap
- cargo test -p lanparty-client-win
- cargo clippy -p lanparty-client-tap --all-targets -- -D warnings
- cargo check -p lanparty-client-tap --target x86_64-pc-windows-gnu
- cargo check -p lanparty-client-tap --target x86_64-pc-windows-msvc
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check
Refs: PLAN.md
The Windows client frame pump needs one task reading TAP frames while another
writes relay frames back to the adapter. The TAP crate already owns the raw
Windows file handle; this change makes the handle's thread-safety boundary
explicit with `Send` and `Sync` impls and documents the Windows handle
assumption next to the unsafe code.
This does not add the pump yet. It only prepares the adapter type for the
separate read/write loops that will wire TAP I/O to the relay session.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- CC_x86_64_pc_windows_msvc=clang-cl AR_x86_64_pc_windows_msvc=llvm-lib \
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER=lld-link cargo clippy \
-p lanparty-client-tap --target x86_64-pc-windows-msvc -- -D warnings
- git diff --check
Refs: PLAN.md
The future client pump should exchange Ethernet frames with TAP through a narrow
API, not raw byte reads and writes. Add TAP frame validation at the adapter
boundary so malformed or jumbo frames are rejected before they enter the relay
path.
Expose `TAP_FRAME_BUFFER_LEN` and `validate_tap_ethernet_frame`, then add
Windows helpers that read a TAP frame and validate it, or validate and fully
write an Ethernet frame. Raw read/write methods remain available for lower-level
adapter work.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- Windows-target cargo clippy for lanparty-client-tap with -D warnings
- git diff --check
Refs: PLAN.md one TAP Ethernet frame per datagram
The Windows client still needs a real Ethernet TAP boundary before it can pump
frames between the adapter and the relay session. Keep that OS-specific surface
separate from the QUIC client state by adding a `lanparty-client-tap` crate.
The new crate discovers TAP-Windows6 adapters through the Windows network
adapter registry class, validates `tap0901` component ids, constructs the
`\\.\Global\{NetCfgInstanceId}.tap` device path, opens the TAP device handle,
and exposes blocking Ethernet frame read/write helpers. It also wraps the
TAP-Windows IOCTLs for media status, driver MAC, and driver MTU.
This does not wire the TAP crate into `lanparty-client-win` yet and does not
attempt route protection. The value of this slice is the target-checkable OS
boundary that the next client pump can depend on.
Test Plan:
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- Windows-target cargo check for lanparty-client-tap with clang-cl/lld-link
- Windows-target cargo clippy for lanparty-client-tap with -D warnings
- git diff --check
Refs: PLAN.md Windows TAP client