irtt_client/lib.rs
1//! Reusable client/session/event layer for IRTT-compatible probes.
2//!
3//! `irtt-client` opens IRTT-compatible sessions, sends echo probes, receives
4//! replies, classifies loss/late/duplicate packets, and emits [`ClientEvent`]
5//! values for callers to consume directly or aggregate with `irtt-stats`.
6//!
7//! Timing values intentionally preserve signed measurement semantics. When
8//! server timing is available, [`RttSample::effective`] is adjusted for server
9//! processing and can be negative if the reported server processing time exceeds
10//! the raw client-observed RTT. Directional [`OneWayDelaySample`] values are
11//! also signed when the required wall-clock timestamps are available; negative
12//! values usually indicate client/server clock skew.
13//!
14//! A managed session can drive the socket loop on a worker thread and publish
15//! events through a subscription:
16//!
17//! ```no_run
18//! use std::time::Duration;
19//!
20//! use irtt_client::{ClientConfig, ClientEvent, ManagedClient, SubscriberConfig};
21//!
22//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
23//! let config = ClientConfig {
24//! server_addr: "127.0.0.1:2112".to_owned(),
25//! duration: Some(Duration::from_secs(10)),
26//! interval: Duration::from_secs(1),
27//! ..ClientConfig::default()
28//! };
29//!
30//! let (session, events) =
31//! ManagedClient::start_with_subscription(config, SubscriberConfig::default())?;
32//!
33//! while let Ok(event) = events.recv() {
34//! match event {
35//! ClientEvent::EchoReply { seq, rtt, .. } => {
36//! println!("seq={seq} effective_rtt_us={}", rtt.effective.as_micros());
37//! }
38//! ClientEvent::SessionClosed { .. } => break,
39//! _ => {}
40//! }
41//! }
42//!
43//! let _outcome = session.join()?;
44//! # Ok(())
45//! # }
46//! ```
47//!
48#![cfg_attr(
49 not(all(target_os = "linux", feature = "ancillary")),
50 forbid(unsafe_code)
51)]
52#![cfg_attr(all(target_os = "linux", feature = "ancillary"), deny(unsafe_code))]
53
54mod client;
55mod config;
56mod error;
57mod event;
58mod managed;
59mod metadata;
60mod probe;
61mod receive;
62mod session;
63mod socket;
64mod socket_options;
65mod timing;
66
67pub use client::Client;
68pub use config::{
69 ClientConfig, NegotiationPolicy, RecvBudget, RunMode, SocketConfig, MAX_DSCP_CODEPOINT,
70 MAX_SERVER_FILL_BYTES, MAX_TTL, MAX_UDP_PAYLOAD_LENGTH,
71};
72pub use error::{ClientError, EventSubscriptionError};
73pub use event::{
74 ClientEvent, OneWayDelaySample, OpenOutcome, PacketMeta, ReceivedStatsSample, RttSample,
75 ServerTiming, SignedDuration, WarningKind,
76};
77pub use managed::{
78 CancellationToken, EventHub, EventSubscription, ManagedClient, ManagedClientSession,
79 SessionEndReason, SessionOutcome, SubscriberConfig, SubscriberOverflow,
80};
81pub use session::{NegotiatedParams, NegotiationRestriction};
82pub use timing::ClientTimestamp;