What's New
Fixed
- TCP teardown no longer hangs under rate-limited paths (#54) — the v0.9.8
SO_LINGER=0fix didn't take effect when the send loop was parked instream.write().awaitunder heavy backpressure (tc rate limiting, slow peers, MPTCP subflows filling).send_dataandsend_data_halfnow race the pendingwrite()against cancel and deadline in abiased tokio::select!, so either signal breaks the loop and letsSO_LINGER=0do its job. Confirmed by @matttbe against his MPTCP + tc reproducer. - TUI elapsed time stays live during data gaps (#62) —
app.elapsedwas only updated when the server'sIntervalprogress message arrived. On lossy paths that starved the control channel, the elapsed counter could freeze for several seconds, creating the impression of a "stall" even though the TUI was still redrawing at 20 Hz. The loop now refresheselapsedfrom the wall clock every iteration. Pause handling shiftsstart_timeforward by the paused duration on resume, so the counter excludes paused time. Reported by @brettowe. - Infinite-duration (
-t 0) TUI now shows a live elapsed counter — same fix covers this.
Added
- Client/server version in the Configuration panel (#62) — the TUI now shows
xfr/<client> ↔ <server>so cross-version test pairings are obvious at a glance.
Changed
- TUI jitter line shows latest + smoothed together (#48 follow-up) — running display now reads
Jitter: 0.02 ms (10s: 0.03 ms)so the instantaneous per-interval value and the 10-second rolling mean are side-by-side. Resolves the confusion where the rolling mean could stay above any single sample's value, making the live display look inconsistent with the final. Completed state still shows just the authoritative final.
Security
- Sanitize server-advertised version before rendering — the
Hello.serverfield crosses a network trust boundary and was being rendered verbatim into the TUI. A hostile or compromised server could send ANSI escape sequences or an oversized string and have the user's terminal act on them. Control characters are now stripped, length is capped at 32, and empty/all-control inputs fall back to(unknown). - Bump rustls-webpki 0.103.12 → 0.103.13 (RUSTSEC-2026-0104) — reachable panic in CRL parsing.
Install
- Homebrew:
brew upgrade xfr(vialance0/tap) - crates.io:
cargo install xfr - Pre-built binaries: see assets below
Full Changelog: v0.9.9...v0.9.10