v2.1.1 — property-based parser fuzzing
Hardening release: property-based fuzzing of the MQTT parser and packet handlers, wired into cargo test. Closes the last testing gap named in the audits. No runtime behaviour change (test-only + a dev-dependency).
Parser fuzzing
A proptest harness (src/server/connection/tests.rs::fuzz) that runs inside cargo test, so the parser is fuzzed continuously in CI rather than only spot-checked against the hand-curated malformed battery. Three properties over an adversarial input distribution — pure random bytes, single plausible-but-malformed packets, and concatenations (framing-boundary fuzzing):
- the frame parser never panics and every parse loop terminates;
- a fully-connected connection fed arbitrary bytes drives every handler (publish, subscribe, the QoS ack flows, ping) through the real dispatch seam without panicking;
- a pre-CONNECT arbitrary packet is rejected cleanly by the CONNECT-first guard.
Deep-validated at PROPTEST_CASES=50000 (50 k parser + 3 k dispatch cases) with no findings.
On the remaining audit deficits (measured, documented)
- Active-connection memory, CPU-per-message, and the −7% saturating throughput share one root cause — the task-per-connection model and the io_uring per-wake floor. This release measured that runtime tuning cannot close them (a
spin_before_parksweep left saturating QoS 1 flat at ~81k). The only lever is dispatcher mode + multishotRECV, gated behind a prototype (next-steps.md§1). - The cross-shard delivery tax is structural, not a defect: one mandatory cross-thread reactor wake over the mesh, inherent to shared-nothing. Recorded in
scope.md.
Assets: rusquitto-x86_64-unknown-linux-gnu, rusquitto-aarch64-unknown-linux-gnu (zig-built against glibc 2.31), and the annotated rusquitto.config.toml. Full details in CHANGELOG.md.