chore: improve documentation and README
Rust CI / cargo fmt (push) Successful in 17s
Rust CI / cargo clippy (push) Successful in 33s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Successful in 23s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Successful in 33s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Successful in 1m7s
Rust CI / cargo doc (push) Successful in 27s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Successful in 1m21s
Fuzz Smoke / cargo fuzz smoke (push) Successful in 1m40s
Netem Interop / netem interop (push) Successful in 1m18s
Supply chain / cargo-deny advisories (push) Successful in 18s
Supply chain / actionlint (push) Failing after 4s
Supply chain / cargo-deny bans licenses sources (push) Successful in 17s
Build binaries / Build (arm-musleabi) (push) Successful in 4m58s
Build binaries / Build (aarch64-musl) (push) Successful in 5m6s
Build binaries / Build (arm-musleabihf) (push) Successful in 4m38s
Build binaries / Build (armv7-musleabi) (push) Successful in 4m33s
Build binaries / Build (armv7-musleabihf) (push) Successful in 4m57s
Build binaries / Build (i686-musl) (push) Successful in 5m1s
Build binaries / Build (mips64-muslabi64) (push) Successful in 4m35s
Build binaries / Build (mips-musl) (push) Successful in 4m42s
Build binaries / Build (mips64el-muslabi64) (push) Successful in 4m54s
Build binaries / Build (mipsel-musl) (push) Successful in 4m54s
Build binaries / Build (riscv64gc-musl) (push) Successful in 4m36s
Build binaries / Build (x86_64-musl) (push) Successful in 4m40s

This commit is contained in:
Nils Andreas Svee committed 2026-10-28 12:17:48 +07:00
1 parent f02f9c0714
commit 97bd903769
6 files changed
+534 -466

No files matched your search

+74 -85
View File
@@ -1,97 +1,67 @@
# irtt-rs
`irtt-rs` is a Rust implementation of an IRTT-compatible client and server:
finite or continuous UDP latency probing, plus the server side those probes
run against.
`irtt-rs` is an IRTT-compatible client and server written in Rust. You can use
it to measure UDP latency for a fixed duration or leave it running
continuously, and run your own server for the probes to talk to.
This is not the upstream IRTT project. For the original implementation,
protocol background, and broader documentation, see
[heistp/irtt](https://github.com/heistp/irtt). The installed dispatcher is
named `irtt-rs` rather than `irtt` to avoid conflicting with or being
mistaken for it.
The original IRTT implementation is [heistp/irtt](https://github.com/heistp/irtt),
which also has protocol background and more documentation. This project is
independent, so the installed dispatcher is named `irtt-rs` to keep it from
conflicting with or being mistaken for `irtt`.
## Features
* Finite and continuous probe sessions
* Concurrent probing of multiple targets, with staggered or burst pacing
* Reusable client library with a structured event stream (blocking, Tokio,
- Finite and continuous probe sessions
- Concurrent probing of multiple targets, with staggered or burst pacing
- Reusable client library with a structured event stream (blocking, Tokio,
or managed)
* Human-readable table output, plus CSV, TSV, and JSON Lines for scripts and
- Human-readable table output, plus CSV, TSV, and JSON Lines for scripts and
monitoring systems, with selectable output columns
* Optional terminal UI
* Reusable Tokio-native server library
* UDP server applet with sensible zero-argument defaults and explicit bind
and session-policy options
* Router-friendly multi-applet binary layout
- Optional terminal UI
- Reusable Tokio-native server library
- UDP server applet you can run without arguments, with options for bind
addresses and session policy when you need them
- A single binary that can run several applets, useful on routers
## Comparison with upstream IRTT
`irtt-rs` is an independent, compatible reimplementation, not a successor or
replacement for upstream IRTT — [heistp/irtt](https://github.com/heistp/irtt)
remains the original implementation. Interoperability is a project goal; see
[`docs/INTEROP_COMPARISON.md`](docs/INTEROP_COMPARISON.md) and
[`docs/protocol/`](docs/protocol/) for the black-box interoperability
methodology and protocol baseline this project verifies against. Choose
between them based on the capabilities and deployment model you need.
`irtt-rs` is useful if you want to watch several targets at once, compare
them in a terminal dashboard, or feed selected measurements into a script.
You can leave it running with statistics and automatic reconnection, use
its Rust libraries in your own application, or deploy a single binary on
a router.
The table below was checked against upstream release
[v0.9.2](https://github.com/heistp/irtt/releases/tag/v0.9.2) (2026-07-17).
This project's own interop testing and protocol baseline are currently
pinned to the prior release, v0.9.1; the wire protocol version number is
unchanged between the two, but v0.9.2 has not itself been exercised against
this project's interop harness.
Upstream IRTT is much more mature, and if you don't need the features
specific to `irtt-rs`, you should probably use it. It also has more tools
for working with saved results and controlling how probes run, including
replaying saved JSON reports, timer and clock diagnostics, and client
payload fill and timing algorithms.
| Capability | irtt-rs | upstream IRTT (v0.9.2) |
| --- | --- | --- |
| Wire protocol | Protocol version 1, verified against upstream v0.9.1 | Protocol version 1 (unchanged in v0.9.2) |
| Finite probing | Supported, default 10s | Supported, default 1m |
| Continuous/indefinite operation | Supported (`--continuous` or `--duration 0`), with optional per-target reconnection | Supported via streaming mode (`-s`, added in v0.9.2); computes no statistics at all in that mode |
| Statistics in continuous mode | Optional running count/min/max/mean/variance per session; no exact medians; bounded IPDV tracking. Use `--no-stats` or omit the `stats` feature to disable collection | None in streaming mode — raw/event output only, by design, to avoid unbounded memory |
| Multi-target probing (one invocation) | Supported, with labels and staggered/burst pacing | Not supported — one remote address per invocation |
| Terminal UI | `irtt-tui`, a live graph/dashboard applet | Not present |
| Output formats | table, csv, tsv, jsonl, with selectable columns | Text summary, JSON (optionally gzip to file), and a fixed-field raw mode; no CSV/TSV and no column selection |
| Client/server library API | Separate, independently versioned Rust crates (`irtt-client`, `irtt-server`) | One combined Go package exposing both roles |
| Server: multiple listeners | `ServerSet` supervises several listeners in one process | `ListenAndServe` also serves multiple requested addresses |
| Server: wildcard reply-source | Default behavior on Linux/macOS/FreeBSD; refused elsewhere rather than served incorrectly | Opt-in via `--set-src-ip`, with a documented per-packet allocation cost |
| Server: zero-argument bind | Binds the wildcard address on both families by default, gated by the platform check above | Binds the wildcard address on both families by default; no documented platform gate |
| Prebuilt release binaries | Published for six target triples | None published; install via `go install` or manual build |
Upstream has capabilities this project does not implement: a `report`
subcommand for replaying saved JSON results, benchmarking and
timer/clock-diagnostic subcommands, client-side payload fill and
don't-fragment/wait-strategy/timer-algorithm controls, an operator-configurable
server-side fill policy (this project's server always honors a session's
negotiated fill request, with a fixed fallback pattern, but has no equivalent
to upstream's flags for restricting or overriding it), syslog logging, and
bundled systemd/OpenRC service files.
This project has capabilities upstream does not implement: multi-target
probing with labels, the terminal UI, CSV/TSV output with selectable
columns, a quantified and actively-warned memory-retention model for
long-running client sessions, and best-effort Linux kernel-timestamp
preference for its own send/receive endpoint.
See the [detailed comparison](docs/INTEROP_COMPARISON.md) for individual
features, version coverage, and black-box interoperability testing.
## Installation
The build requires Rust 1.88 or newer.
Prebuilt binaries for supported platforms are available on the
[GitHub Releases](https://github.com/Lochnair/irtt-rs/releases) page.
Install the latest release from crates.io:
Alternatively, install from crates.io using Rust 1.88 or newer:
```sh
cargo install irtt-rs --locked
```
This installs the `irtt-rs` dispatcher plus dedicated `irtt-client`,
`irtt-tui`, and `irtt-server` binaries. Each applet can also be built in
isolation with `--no-default-features` plus the applet's own feature, for
example a lightweight client-only install without statistics:
This installs the `irtt-rs` dispatcher along with dedicated `irtt-client`,
`irtt-tui`, and `irtt-server` binaries. If you only need the client, you can
disable the other applets and statistics:
```sh
cargo install irtt-rs --locked --no-default-features --features client
```
Add `stats` (`--features client,stats`) to retain statistics in a client-only
build. Statistics are enabled by default; the TUI always enables them.
This installs `irtt-client` and the `irtt-rs` dispatcher. Add `stats`
(`--features client,stats`) to retain statistics in a client-only build.
Statistics are enabled by default; the TUI always enables them.
For development, or to install directly from a checkout:
@@ -131,30 +101,56 @@ Watch the same session live in the terminal UI:
irtt-tui netperf-eu.bufferbloat.net:2112
```
Run a server with sensible defaults — no `--bind` needed:
To run your own server, you can leave out `--bind` and use the defaults:
```sh
irtt-server
```
### Dynamic targets from stdin
If another application decides which servers to probe, `--targets-stdin`
lets it change targets without restarting the client. It works in
continuous mode:
```sh
irtt-client --continuous --targets-stdin --reconnect --no-stats \
--format csv --columns event,target,seq,rd_us,sd_us
```
Send one comma-separated target set per line to stdin, for example:
```text
ams=ams.example:2112,lhr=lhr.example:2112
ams=ams.example:2112
[]
```
Each line gives the complete desired target set. Unchanged targets keep
running, removed targets stop, and new or changed targets start. Use `[]`
to clear all targets without exiting.
The CSV includes an `event` column so your script can distinguish
`echo_reply` measurements from other events.
Keep stdin open while controlling the client. Closing it sends EOF and stops the run gracefully.
See [Dynamic target sets from standard input](docs/irtt-client.md#dynamic-target-sets-from-standard-input)
for the full syntax and behavior.
## Documentation
* [`docs/irtt-client.md`](docs/irtt-client.md) — target syntax, output
- [`docs/irtt-client.md`](docs/irtt-client.md): target syntax, output
formats and columns, measurement field definitions, finite/continuous
memory behavior, kernel timestamps.
* [`docs/irtt-tui.md`](docs/irtt-tui.md) — controls, continuous default,
- [`docs/irtt-tui.md`](docs/irtt-tui.md): controls, continuous default,
retained history.
* [`docs/irtt-server.md`](docs/irtt-server.md) — bind defaults and
- [`docs/irtt-server.md`](docs/irtt-server.md): bind defaults and
overrides, wildcard listener behavior, session policy, HMAC.
* [`docs/irtt-rs.md`](docs/irtt-rs.md) — the multicall dispatcher, applet
- [`docs/irtt-rs.md`](docs/irtt-rs.md): the multicall dispatcher, applet
binary names, feature-gated builds.
* [docs.rs](https://docs.rs) for the library crates below.
* [`docs/protocol/`](docs/protocol/) and
[`docs/INTEROP_COMPARISON.md`](docs/INTEROP_COMPARISON.md) for the wire
protocol specification and interoperability validation against upstream
`irtt`.
Every applet also documents its full option list with `--help`.
You can also run any applet with `--help` for its full option list.
## Crates
@@ -166,9 +162,6 @@ Every applet also documents its full option list with `--help`.
| [`irtt-stats`](crates/irtt-stats) | [crates.io](https://crates.io/crates/irtt-stats) | Statistics aggregation over `irtt-client` events ([docs.rs](https://docs.rs/irtt-stats)) |
| [`irtt-proto`](crates/irtt-proto) | [crates.io](https://crates.io/crates/irtt-proto) | Low-level wire protocol encode/decode ([docs.rs](https://docs.rs/irtt-proto)) |
Each library crate has its own crates.io README describing what it's for and
when to use it instead of `irtt-client`/`irtt-server` directly.
## Binaries and features
| Build | Binaries |
@@ -188,7 +181,3 @@ cargo test --workspace --locked
cargo test --workspace --doc --all-features --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
```
See [`AGENTS.md`](AGENTS.md) for architecture, testing policy, and the
clean-room provenance boundary this project maintains against upstream
`irtt`.