What's New
Added
- Max jitter and packet size in UDP summary (#48 follow-up) — final UDP summary now reports
Jitter Max(peak of the RFC 3550 running estimate) alongside the average, plusPacket Size(UDP payload bytes). Surfaced in plain text and JSON. Requested by @brettowe for NFS UDP packet-size tuning context. -wshort alias for--window(#60) — matches iperf3 muscle memory.
Changed
- Bare-integer duration arguments mean seconds (#61) —
-t 10,--max-duration 60,--rate-limit-window 30, anddiscover --timeout 5now accept plain integers as seconds. Unit-suffixed forms (10s,1min,500ms) continue to work unchanged.- Side effect:
--rate-limit-windownow rejects zero (0,0s,0ms) —0swas previously accepted and would later panic in the rate-limiter cleanup task becausetokio::time::intervalrequires a non-zero duration. Other duration flags still accept0for their existing meanings (-t 0is infinite).
- Side effect:
- Smoothed TUI jitter reading (#48) — the UDP stats panel shows jitter averaged over a 10-second rolling window rather than raw per-second samples. Server data pipeline is unchanged; display is smoothed. While running, the label reads
Jitter (10s):; on completion it reverts toJitter:with the authoritative final value from the server.
Fixed
-
Duplicate receive-error log on the server (#54) —
tcp::receive_data/receive_data_halfeach warned at the read-error site, and the caller warned again on the returnedErr. The innerwarn!is removed so receive errors log exactly once. Reported by @matttbe. -
Default to kernel TCP autotuning (#60) — xfr no longer forces
SO_SNDBUF/SO_RCVBUFto 4 MB on either side by default. Both ends let the kernel autotune unless the user passes-w/--window. When set, the client's value propagates to the server over the control protocol so both sides apply the socket option symmetrically (matching iperf3). Reported by @matttbe.Caveats:
- Loopback / intra-host benchmark numbers may decrease by roughly 10% — this is expected; the previous numbers were inflated by the oversized app-applied buffer.
- On high-RTT paths, very short tests (e.g.
-t 1sat high bitrate) may now show ramp-up-limited throughput in the final summary because kernel autotune takes a handful of RTTs to grow the window. Use a longer-tor pass an explicit-wto skip autotune. Note that-O/--omitonly hides early intervals from output — the server's final summary is computed over the full test duration. - Explicit window sizes above
c_int::MAX(≈2.1 GB on 64-bit) are now rejected withInvalidInputinstead of silently wrapping beforesetsockopt.
Removed
- Library API: pre-1.0 break —
TcpConfig::high_speed()andTcpConfig::with_auto_detect()are gone; constructTcpConfigdirectly with the fields you want set. TheHIGH_SPEED_BUFFERandHIGH_SPEED_WINDOW_THRESHOLDconstants (which were private) are also removed. Downstream code that constructsControlMessage::TestStart,protocol::UdpStats, ortui::app::Appby name now needs to supply the new fields (window_size,jitter_max_ms,packet_size,jitter_history); all are additive with sensible defaults.
Install
- Homebrew:
brew upgrade xfr(vialance0/tap) - crates.io:
cargo install xfr - Pre-built binaries: see assets below
Full Changelog: v0.9.8...v0.9.9