Simplify RttSample by merging signed and unsigned fields into a single SignedDuration for adjusted and effective RTT. This ensures accurate reporting and statistics when server processing time exceeds raw RTT.
145 lines
3.1 KiB
Markdown
145 lines
3.1 KiB
Markdown
# irtt-rs
|
|
|
|
`irtt-rs` is a Rust implementation of an IRTT-compatible client.
|
|
|
|
It is not the upstream IRTT project. For the original implementation, protocol background, and broader project documentation, see:
|
|
|
|
<https://github.com/heistp/irtt>
|
|
|
|
## Status
|
|
|
|
This repository currently provides:
|
|
|
|
- `irtt-cli`, a command-line IRTT-compatible client
|
|
- `irtt-client`, a Rust library for running client sessions and consuming events
|
|
- finite and continuous probe runs
|
|
- human, simple, machine-readable, and RTT-only output modes
|
|
- optional local summary statistics
|
|
|
|
Server support is not implemented.
|
|
|
|
## Install
|
|
|
|
Requires Rust 1.75 or newer.
|
|
|
|
From a local checkout:
|
|
|
|
```sh
|
|
git clone https://github.com/Lochnair/irtt-rs.git
|
|
cd irtt-rs
|
|
cargo install --path crates/irtt-cli
|
|
```
|
|
|
|
Or run it directly without installing:
|
|
|
|
```sh
|
|
cargo run -p irtt-cli -- <server>
|
|
```
|
|
|
|
## CLI usage
|
|
|
|
Basic test:
|
|
|
|
```sh
|
|
irtt-cli <server>
|
|
```
|
|
|
|
Set duration and interval:
|
|
|
|
```sh
|
|
irtt-cli <server> --duration 30s --interval 100ms
|
|
```
|
|
|
|
Run continuously:
|
|
|
|
```sh
|
|
irtt-cli <server> --duration 0
|
|
```
|
|
|
|
Use a specific output mode:
|
|
|
|
```sh
|
|
irtt-cli <server> --output human
|
|
irtt-cli <server> --output simple
|
|
irtt-cli <server> --output machine
|
|
irtt-cli <server> --output rtt-us
|
|
```
|
|
|
|
For available options:
|
|
|
|
```sh
|
|
irtt-cli --help
|
|
```
|
|
|
|
## Machine output
|
|
|
|
Use `--output machine` for line-oriented `key=value` output intended for scripts, monitoring, and autorate consumers.
|
|
|
|
Example:
|
|
|
|
```sh
|
|
irtt-cli <server> --duration 0 --interval 250ms --output machine
|
|
```
|
|
|
|
Each line represents one client event and starts with an `event` field, for example:
|
|
|
|
```text
|
|
event=echo_reply seq=4 logical_seq=4 remote=203.0.113.10:2112 raw_rtt_us=12400 effective_rtt_us=12100 adjusted_rtt_us=12100 server_processing_us=300 dscp=0 ecn=0 kernel_rx_ns=none
|
|
```
|
|
|
|
Consumers should match on `event=...` and read the fields they need. Unknown fields should be ignored.
|
|
|
|
For consumers that only need RTT values, use:
|
|
|
|
```sh
|
|
irtt-cli <server> --output rtt-us
|
|
```
|
|
|
|
## Library usage
|
|
|
|
`irtt-client` can be used directly from Rust code.
|
|
|
|
Example `Cargo.toml` dependency from a local checkout:
|
|
|
|
```toml
|
|
[dependencies]
|
|
irtt-client = { path = "crates/irtt-client" }
|
|
```
|
|
|
|
Minimal managed-client example:
|
|
|
|
```rust
|
|
use std::time::Duration;
|
|
|
|
use irtt_client::{
|
|
ClientConfig, ClientEvent, ManagedClient, SubscriberConfig,
|
|
};
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let config = ClientConfig {
|
|
server_addr: "netperf-eu.bufferbloat.net:2112".to_owned(),
|
|
duration: Some(Duration::from_secs(10)),
|
|
interval: Duration::from_secs(1),
|
|
..ClientConfig::default()
|
|
};
|
|
|
|
let (session, events) =
|
|
ManagedClient::start_with_subscription(config, SubscriberConfig::default())?;
|
|
|
|
while let Ok(event) = events.recv() {
|
|
match event {
|
|
ClientEvent::EchoReply { seq, rtt, .. } => {
|
|
println!("seq={seq} rtt_us={}", rtt.effective.ns / 1_000);
|
|
}
|
|
ClientEvent::SessionClosed { .. } => break,
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
let outcome = session.join()?;
|
|
println!("session ended: {:?}", outcome.end_reason);
|
|
|
|
Ok(())
|
|
}
|
|
```
|