rperf3/lib.rs
1//! # rperf3-rs
2//!
3//! A high-performance network throughput measurement tool written in Rust, inspired by iperf3.
4//!
5//! This library provides accurate bandwidth testing capabilities for both TCP and UDP protocols.
6//! Built on Tokio's async runtime with Rust's memory safety guarantees, rperf3-rs eliminates
7//! entire classes of bugs (buffer overflows, use-after-free, data races) while achieving
8//! 40+ Gbps throughput on localhost tests.
9//!
10//! ## Features
11//!
12//! - **TCP & UDP Testing**: Measure throughput for both reliable and unreliable protocols
13//! - **Bidirectional Testing**: Normal mode (client → server) and reverse mode (server → client)
14//! - **Bandwidth Limiting**: Control send rate for both TCP and UDP with K/M/G notation (e.g., 100M = 100 Mbps)
15//! - **UDP Metrics**: Packet loss percentage, jitter (RFC 3550), and out-of-order packet detection
16//! - **TCP Statistics**: Retransmits, congestion window (cwnd), and real-time interval reporting (Linux only)
17//! - **Async Interval Reporting**: Non-blocking progress updates with 5-10% performance improvement
18//! - **Memory-Optimized Storage**: Ring buffer design prevents unbounded growth, 30-50% memory reduction
19//! - **Lock-Free Measurements**: Atomic operations eliminate contention in high-throughput scenarios
20//! - **Interval Reporting**: Configurable interval updates with iperf3-style formatted output (default: 1 second)
21//! - **Real-time Callbacks**: Monitor test progress programmatically with event-driven callbacks
22//! - **Parallel Streams**: Multiple concurrent connections for aggregate testing
23//! - **JSON Output**: Machine-readable output compatible with automation systems (client and server)
24//! - **Dual Interface**: Use as a Rust library or standalone CLI tool
25//! - **Async I/O**: Built on Tokio for high-performance non-blocking operations
26//! - **Cross-Platform**: Linux, macOS, and Windows support
27//!
28//! ## Quick Start
29//!
30//! ### Basic TCP Test
31//!
32//! ```no_run
33//! use rperf3::{Client, Config, Protocol};
34//! use std::time::Duration;
35//!
36//! #[tokio::main]
37//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
38//! let config = Config::client("192.168.1.100".to_string(), 5201)
39//! .with_protocol(Protocol::Tcp)
40//! .with_duration(Duration::from_secs(10))
41//! .with_interval(Duration::from_secs(1)); // Report every second
42//!
43//! let client = Client::new(config)?;
44//! client.run().await?;
45//!
46//! let measurements = client.get_measurements();
47//! println!("Bandwidth: {:.2} Mbps",
48//! measurements.total_bits_per_second() / 1_000_000.0);
49//!
50//! Ok(())
51//! }
52//! ```
53//!
54//! ### UDP Test with Metrics
55//!
56//! ```no_run
57//! use rperf3::{Client, Config, Protocol};
58//! use std::time::Duration;
59//!
60//! #[tokio::main]
61//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
62//! let config = Config::client("192.168.1.100".to_string(), 5201)
63//! .with_protocol(Protocol::Udp)
64//! .with_bandwidth(100_000_000) // 100 Mbps
65//! .with_duration(Duration::from_secs(10));
66//!
67//! let client = Client::new(config)?;
68//! client.run().await?;
69//!
70//! let measurements = client.get_measurements();
71//! println!("Bandwidth: {:.2} Mbps",
72//! measurements.total_bits_per_second() / 1_000_000.0);
73//! println!("Packets: {}, Loss: {} ({:.2}%), Jitter: {:.3} ms",
74//! measurements.total_packets,
75//! measurements.lost_packets,
76//! (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0,
77//! measurements.jitter_ms);
78//!
79//! Ok(())
80//! }
81//! ```
82//!
83//! ### Server Example
84//!
85//! ```no_run
86//! use rperf3::{Server, Config};
87//! use std::time::Duration;
88//!
89//! #[tokio::main]
90//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
91//! // Server with JSON output and custom interval
92//! let config = Config::server(5201)
93//! .with_json(true)
94//! .with_interval(Duration::from_secs(2));
95//! let server = Server::new(config);
96//!
97//! println!("Server listening on port 5201");
98//! server.run().await?;
99//!
100//! Ok(())
101//! }
102//! ```
103//!
104//! ### Progress Callbacks
105//!
106//! Monitor test progress in real-time:
107//!
108//! ```no_run
109//! use rperf3::{Client, Config, ProgressEvent};
110//! use std::time::Duration;
111//!
112//! #[tokio::main]
113//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
114//! let config = Config::client("192.168.1.100".to_string(), 5201)
115//! .with_duration(Duration::from_secs(10));
116//!
117//! let client = Client::new(config)?
118//! .with_callback(|event: ProgressEvent| {
119//! match event {
120//! ProgressEvent::TestStarted => {
121//! println!("Test started");
122//! }
123//! ProgressEvent::IntervalUpdate { bits_per_second, .. } => {
124//! println!("Current: {:.2} Mbps", bits_per_second / 1_000_000.0);
125//! }
126//! ProgressEvent::TestCompleted { bits_per_second, .. } => {
127//! println!("Average: {:.2} Mbps", bits_per_second / 1_000_000.0);
128//! }
129//! ProgressEvent::Error(msg) => {
130//! eprintln!("Error: {}", msg);
131//! }
132//! }
133//! });
134//!
135//! client.run().await?;
136//! Ok(())
137//! }
138//! ```
139//!
140//! ## Bandwidth Notation
141//!
142//! When specifying bandwidth limits, use K/M/G suffixes:
143//! - `100K` = 100,000 bits/second
144//! - `100M` = 100,000,000 bits/second
145//! - `1G` = 1,000,000,000 bits/second
146//!
147//! The bandwidth limiting applies to both TCP (in reverse mode) and UDP tests.
148//!
149//! ## Interval Reporting
150//!
151//! Real-time interval reports show throughput statistics at regular intervals (default: 1 second).
152//! Reports use iperf3-compatible formatting with proper alignment:
153//!
154//! ```text
155//! [ ID] Interval Transfer Bitrate Retr Cwnd
156//! [ 5] 0.00-1.00 sec 7.23 GBytes 58.1 Gbits/sec 0
157//! [ 5] 1.00-2.00 sec 7.42 GBytes 59.4 Gbits/sec 0 1215 KBytes
158//! ```
159//!
160//! Configure intervals with the `-i` flag or `.with_interval()` method:
161//!
162//! ```no_run
163//! use rperf3::{Client, Config};
164//! use std::time::Duration;
165//!
166//! # #[tokio::main]
167//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
168//! let config = Config::client("192.168.1.100".to_string(), 5201)
169//! .with_duration(Duration::from_secs(10))
170//! .with_interval(Duration::from_secs(2)); // Report every 2 seconds
171//!
172//! let client = Client::new(config)?;
173//! client.run().await?;
174//! # Ok(())
175//! # }
176//! ```
177//!
178//! ## Architecture
179//!
180//! The library is organized into the following modules:
181//!
182//! - [`client`]: Client implementation for initiating tests and collecting results
183//! - [`server`]: Server implementation for handling connections and running tests
184//! - [`config`]: Configuration structures with builder pattern
185//! - [`measurements`]: Thread-safe statistics collection and calculation
186//! - [`protocol`]: Message format and serialization for client-server communication
187//! - [`udp_packet`]: UDP packet format with sequence numbers and timestamps
188//! - [`error`]: Custom error types and result aliases
189//!
190//! ## Performance
191//!
192//! Typical performance on modern hardware:
193//! - **TCP localhost**: 25-30 Gbps
194//! - **UDP with limiting**: Accurate rate control within 2-3% of target
195//! - **Packet loss detection**: Sub-millisecond precision
196//! - **Jitter measurement**: RFC 3550 compliant algorithm
197
198pub mod batch_socket;
199pub mod buffer_pool;
200pub mod client;
201pub mod config;
202pub mod error;
203pub mod interval_reporter;
204pub mod measurements;
205pub mod protocol;
206pub mod server;
207pub mod token_bucket;
208pub mod udp_packet;
209
210pub use batch_socket::{UdpRecvBatch, UdpSendBatch, MAX_BATCH_SIZE};
211pub use client::{Client, ProgressCallback, ProgressEvent};
212pub use config::{Config, Protocol};
213pub use error::{Error, Result};
214pub use interval_reporter::{IntervalMessage, IntervalReport, IntervalReporter};
215pub use measurements::Measurements;
216pub use protocol::{stream_id_for_index, DEFAULT_STREAM_ID};
217pub use server::Server;
218pub use token_bucket::TokenBucket;
219
220/// Library version string.
221///
222/// This constant contains the version of the rperf3-rs library, automatically
223/// extracted from the package version in `Cargo.toml`.
224///
225/// # Examples
226///
227/// ```
228/// use rperf3::VERSION;
229///
230/// println!("rperf3-rs version: {}", VERSION);
231/// ```
232pub const VERSION: &str = env!("CARGO_PKG_VERSION");