# 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: ## 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, RTT-only, and optional TUI 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 -- ``` ## CLI usage Basic test: ```sh irtt-cli ``` Set duration and interval: ```sh irtt-cli --duration 30s --interval 100ms ``` Run continuously: ```sh irtt-cli --duration 0 ``` Use a specific output mode: ```sh irtt-cli --output human irtt-cli --output simple irtt-cli --output machine irtt-cli --output rtt-us ``` With the optional TUI feature, `--output tui` opens a live cumulative and rolling dashboard for interactive probing. Quit with `q` or `Ctrl-C`; the client will drain and close the session gracefully. ```sh cargo run -p irtt-cli --features tui -- --output tui ``` 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 --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 remote=203.0.113.10:2112 client_send_wall_ns=1760000000000000000 client_receive_wall_ns=1760000000012400000 raw_rtt_us=12400 effective_rtt_us=12100 adjusted_rtt_us=12100 server_receive_wall_ns=1760000000006100000 server_receive_mono_ns=5000006100000 server_send_wall_ns=1760000000006400000 server_send_mono_ns=5000006400000 server_processing_us=300 client_to_server_us=6100 server_to_client_us=6000 server_received_count=5 server_received_window=0x1f dscp=0 ecn=0 kernel_rx_ns=none ``` Consumers should match on `event=...` and read the fields they need. Unknown fields should be ignored. RTT fields are reported in microseconds. `raw_rtt_us` is the measured client send-to-receive RTT. `effective_rtt_us` and `adjusted_rtt_us` are signed and may be negative when server processing exceeds the raw RTT or timing correction produces a negative adjusted value. When one-way delay fields are present, `client_to_server_us` and `server_to_client_us` are also signed microseconds and may be negative due to wall-clock skew. For consumers that only need RTT values, use: ```sh irtt-cli --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> { 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.as_micros()); } ClientEvent::SessionClosed { .. } => break, _ => {} } } let outcome = session.join()?; println!("session ended: {:?}", outcome.end_reason); Ok(()) } ```