iroh_netbench/report.rs
1//! Serializable final report types.
2
3use std::time::Duration;
4
5use serde::{Deserialize, Serialize};
6
7/// High-level path classification over the lifetime of a run.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9pub enum PathKind {
10 /// Direct UDP path, address family not known.
11 Direct,
12 /// Direct IPv4 path.
13 DirectIpv4,
14 /// Direct IPv6 path.
15 DirectIpv6,
16 /// Traffic used an iroh relay.
17 Relay,
18 /// Path type changed during accounted measurements.
19 Mixed,
20 /// Path information was unavailable.
21 Unknown,
22}
23
24/// Path observations made during the benchmark business flow.
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
26pub struct MeasurementPathReport {
27 /// Time from starting the business flow until the first control response.
28 pub negotiation_time: Duration,
29 /// Selected path at the start of the measurement window.
30 pub initial_path: PathKind,
31 /// Selected path at the end of the measurement window.
32 pub final_path: PathKind,
33 /// Whether the selected path changed during the flow.
34 pub path_changed: bool,
35 /// Whether a relay-to-direct transition was seen.
36 pub became_direct: bool,
37 /// Time from business-flow start until the first direct path.
38 pub time_to_direct: Option<Duration>,
39}
40
41/// Idle or loaded RTT distribution.
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43pub struct LatencyReport {
44 /// Successful RTT sample count.
45 pub samples: u32,
46 /// Minimum RTT.
47 pub min: Duration,
48 /// Arithmetic mean RTT.
49 pub mean: Duration,
50 /// Median RTT.
51 pub p50: Duration,
52 /// 95th percentile RTT.
53 pub p95: Duration,
54 /// 99th percentile RTT.
55 pub p99: Duration,
56 /// Maximum RTT.
57 pub max: Duration,
58 /// Mean absolute difference between adjacent RTT samples.
59 pub jitter_mean: Duration,
60 /// 95th percentile adjacent-sample jitter.
61 pub jitter_p95: Duration,
62}
63
64/// Application datagram echo results.
65#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub struct LossReport {
67 /// Unique probes sent.
68 pub sent: u64,
69 /// Unique probe echoes received before timeout.
70 pub received: u64,
71 /// Probes not echoed before the deadline.
72 pub timed_out: u64,
73 /// Duplicate echoes observed.
74 pub duplicated: u64,
75 /// Out-of-order echoes observed.
76 pub reordered: u64,
77 /// `timed_out / sent`, or zero when no probes were sent.
78 pub timeout_ratio: f64,
79}
80
81/// One throughput direction.
82#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
83pub struct ThroughputReport {
84 /// Payload bytes received by the measuring side.
85 pub received_bytes: u64,
86 /// Accounted measurement duration.
87 pub measurement_duration: Duration,
88 /// Payload bits per second.
89 pub bits_per_second: f64,
90 /// Parallel stream count.
91 pub streams: u16,
92}
93
94/// RTT while throughput traffic is active.
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96pub struct LoadedLatencyReport {
97 /// Idle median RTT used as the baseline.
98 pub idle_p50: Duration,
99 /// Median RTT during download.
100 pub download_p50: Duration,
101 /// Saturated download minus idle baseline.
102 pub download_increase: Duration,
103 /// Median RTT during upload.
104 pub upload_p50: Duration,
105 /// Saturated upload minus idle baseline.
106 pub upload_increase: Duration,
107}
108
109/// Delta between transport snapshots taken before and after measurements.
110#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111pub struct TransportReport {
112 /// QUIC packets declared lost.
113 pub lost_packets: u64,
114 /// QUIC bytes declared lost.
115 pub lost_bytes: u64,
116 /// Congestion events.
117 pub congestion_events: u64,
118 /// UDP datagrams received.
119 pub udp_rx_datagrams: u64,
120 /// UDP datagrams transmitted.
121 pub udp_tx_datagrams: u64,
122 /// Final path maximum transmission unit.
123 pub current_mtu: u16,
124 /// Black-hole detections.
125 pub black_holes_detected: u64,
126 /// Final transport RTT estimate.
127 pub final_rtt: Duration,
128}
129
130/// Complete result of a benchmark run.
131#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
132pub struct NetBenchReport {
133 /// JSON schema version.
134 pub schema_version: u16,
135 /// Negotiated wire protocol version.
136 pub protocol_version: u16,
137 /// Remote peer identity.
138 pub peer_id: String,
139 /// Wall-clock duration of the run.
140 pub total_duration: Duration,
141 /// Path details observed during the benchmark flow.
142 pub path: MeasurementPathReport,
143 /// Idle latency.
144 pub idle_latency: LatencyReport,
145 /// Application probe timeout results.
146 pub loss: LossReport,
147 /// Download rate.
148 pub download: ThroughputReport,
149 /// Upload rate.
150 pub upload: ThroughputReport,
151 /// Latency under load.
152 pub loaded_latency: LoadedLatencyReport,
153 /// QUIC path-statistics delta.
154 pub transport: TransportReport,
155}
156
157/// Complete result of a low-bandwidth latency and loss probe run.
158#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
159pub struct NetBenchProbeReport {
160 /// JSON schema version.
161 pub schema_version: u16,
162 /// Negotiated wire protocol version.
163 pub protocol_version: u16,
164 /// Remote peer identity.
165 pub peer_id: String,
166 /// Wall-clock duration of the run.
167 pub total_duration: Duration,
168 /// Path details observed during the probe flow.
169 pub path: MeasurementPathReport,
170 /// Idle latency and jitter.
171 pub idle_latency: LatencyReport,
172 /// Application Datagram timeout results.
173 pub loss: LossReport,
174 /// QUIC path-statistics delta during the probe run.
175 pub transport: TransportReport,
176}