chore(lints): enforce per-crate lint policy and add build profiles

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
This commit is contained in:
2026-08-16 19:00:54 +02:00
parent 2bed62e9ec
commit e62f584377
35 changed files with 1024 additions and 227 deletions
+10
View File
@@ -16,3 +16,13 @@ windows-sys = {
"Win32_Networking_WinSock",
]
}
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
todo = "warn"
unwrap_used = "warn"
[lints.rust]
# `deny` rather than `forbid`: this crate needs OS FFI, so single
# modules opt back in with `#![allow(unsafe_code)]`.
unsafe_code = "deny"
+61
View File
@@ -3,6 +3,7 @@
//! The client binary uses this crate to keep Win32 route/metric calls out of
//! the relay session code. The crate can snapshot the current relay route and
//! install scoped route/interface overrides that are restored when dropped.
#![cfg_attr(test, allow(clippy::unwrap_used))]
use std::net::IpAddr;
@@ -297,6 +298,13 @@ pub use windows::{
set_scoped_interface_mtu,
};
/// Returns the route Windows would currently use to reach
/// `destination`, so the relay path can be pinned to it.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn best_route_to(_destination: IpAddr) -> Result<RouteSnapshot> {
bail!("Windows route inspection is only available on Windows");
@@ -308,11 +316,26 @@ pub struct PinnedRelayRoute {
_private: (),
}
/// Installs a host route that keeps relay traffic on `route`'s
/// interface, restoring the previous state when the returned guard is
/// dropped.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn pin_relay_route(_route: &RouteSnapshot) -> Result<PinnedRelayRoute> {
bail!("Windows route pinning is only available on Windows");
}
/// Resolves a Windows interface GUID string to the LUID and index the
/// IP Helper API expects.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn interface_identity_from_guid(_interface_guid: &str) -> Result<NetworkInterfaceIdentity> {
bail!("Windows interface identity lookup is only available on Windows");
@@ -324,6 +347,12 @@ pub struct ScopedInterfaceMetric {
_private: (),
}
/// Reads the current routing metric of an interface.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn interface_metric(
_identity: NetworkInterfaceIdentity,
@@ -332,6 +361,13 @@ pub fn interface_metric(
bail!("Windows interface metric lookup is only available on Windows");
}
/// Overrides an interface's routing metric until the returned guard is
/// dropped.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn set_scoped_interface_metric(
_identity: NetworkInterfaceIdentity,
@@ -347,6 +383,13 @@ pub struct ScopedDefaultRoutes {
_private: (),
}
/// Enables or disables an interface's default routes until the returned
/// guard is dropped.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn set_scoped_default_routes_disabled(
_identity: NetworkInterfaceIdentity,
@@ -356,6 +399,12 @@ pub fn set_scoped_default_routes_disabled(
bail!("Windows interface default-route updates are only available on Windows");
}
/// Reads the current MTU of an interface.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn interface_mtu(
_identity: NetworkInterfaceIdentity,
@@ -364,6 +413,12 @@ pub fn interface_mtu(
bail!("Windows interface MTU lookup is only available on Windows");
}
/// Lists the unicast IP addresses currently assigned to an interface.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn interface_unicast_addresses(
_identity: NetworkInterfaceIdentity,
@@ -377,6 +432,12 @@ pub struct ScopedInterfaceMtu {
_private: (),
}
/// Overrides an interface's MTU until the returned guard is dropped.
///
/// # Errors
///
/// Always fails on non-Windows targets; this crate only implements the
/// Windows IP Helper backend.
#[cfg(not(windows))]
pub fn set_scoped_interface_mtu(
_identity: NetworkInterfaceIdentity,
@@ -1,3 +1,9 @@
//! Windows IP Helper (`iphlpapi`) route and interface manipulation.
//!
//! All Win32 FFI is confined to this module, which is why it opts back into
//! `unsafe`.
#![allow(unsafe_code)]
use std::{
fmt,
io,
@@ -58,6 +64,13 @@ use crate::{
RouteSnapshot,
};
/// Resolves a Windows interface GUID string to the LUID and index the
/// IP Helper API expects.
///
/// # Errors
///
/// Returns an error if `interface_guid` is not a well-formed GUID or
/// does not name an existing interface.
pub fn interface_identity_from_guid(interface_guid: &str) -> Result<NetworkInterfaceIdentity> {
let guid = parse_interface_guid(interface_guid)?;
let mut luid = NET_LUID_LH::default();
@@ -83,6 +96,11 @@ pub fn interface_identity_from_guid(interface_guid: &str) -> Result<NetworkInter
Ok(NetworkInterfaceIdentity::new(index, luid_value(luid)))
}
/// Reads the current routing metric of an interface.
///
/// # Errors
///
/// Returns an error if the interface row cannot be read.
pub fn interface_metric(
identity: NetworkInterfaceIdentity,
family: IpInterfaceFamily,
@@ -92,6 +110,11 @@ pub fn interface_metric(
Ok(metric_snapshot(identity, family, row))
}
/// Reads the current MTU of an interface.
///
/// # Errors
///
/// Returns an error if the interface row cannot be read.
pub fn interface_mtu(
identity: NetworkInterfaceIdentity,
family: IpInterfaceFamily,
@@ -101,6 +124,11 @@ pub fn interface_mtu(
Ok(mtu_snapshot(identity, family, row))
}
/// Lists the unicast IP addresses currently assigned to an interface.
///
/// # Errors
///
/// Returns an error if the unicast address table cannot be read.
pub fn interface_unicast_addresses(
identity: NetworkInterfaceIdentity,
) -> Result<Vec<InterfaceUnicastAddress>> {
@@ -128,6 +156,13 @@ pub fn interface_unicast_addresses(
.collect())
}
/// Overrides an interface's routing metric until the returned guard is
/// dropped.
///
/// # Errors
///
/// Returns an error if the previous metric cannot be read or the new
/// one cannot be applied.
pub fn set_scoped_interface_metric(
identity: NetworkInterfaceIdentity,
family: IpInterfaceFamily,
@@ -146,6 +181,12 @@ pub fn set_scoped_interface_metric(
})
}
/// Enables or disables an interface's default routes until the returned
/// guard is dropped.
///
/// # Errors
///
/// Returns an error if the interface row cannot be read or updated.
pub fn set_scoped_default_routes_disabled(
identity: NetworkInterfaceIdentity,
family: IpInterfaceFamily,
@@ -164,6 +205,12 @@ pub fn set_scoped_default_routes_disabled(
})
}
/// Overrides an interface's MTU until the returned guard is dropped.
///
/// # Errors
///
/// Returns an error if `mtu` is zero, or if the interface row cannot be
/// read or updated.
pub fn set_scoped_interface_mtu(
identity: NetworkInterfaceIdentity,
family: IpInterfaceFamily,
@@ -299,6 +346,12 @@ impl Drop for ScopedInterfaceMtu {
}
}
/// Returns the route Windows would currently use to reach
/// `destination`, so the relay path can be pinned to it.
///
/// # Errors
///
/// Returns an error if the Windows best-route lookup fails.
pub fn best_route_to(destination: IpAddr) -> Result<RouteSnapshot> {
let destination_sockaddr = sockaddr_from_ip(destination);
let mut route = MIB_IPFORWARD_ROW2::default();
@@ -481,6 +534,13 @@ const fn address_family(family: IpInterfaceFamily) -> u16 {
}
}
/// Installs a host route that keeps relay traffic on `route`'s
/// interface, restoring the previous state when the returned guard is
/// dropped.
///
/// # Errors
///
/// Returns an error if the route cannot be installed.
pub fn pin_relay_route(route: &RouteSnapshot) -> Result<PinnedRelayRoute> {
let mut pinned = pinned_route_row(route);
let status = unsafe {