Skip to main content

irtt_client/
event.rs

1use std::{
2    net::SocketAddr,
3    time::{Duration, Instant},
4};
5
6use crate::{session::NegotiatedParams, timing::ClientTimestamp};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum OpenOutcome {
10    Started {
11        remote: SocketAddr,
12        token: u64,
13        negotiated: NegotiatedParams,
14        event: ClientEvent,
15    },
16    NoTestCompleted {
17        remote: SocketAddr,
18        negotiated: NegotiatedParams,
19        event: ClientEvent,
20    },
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum ClientEvent {
25    SessionStarted {
26        remote: SocketAddr,
27        token: u64,
28        negotiated: NegotiatedParams,
29        at: ClientTimestamp,
30    },
31    NoTestCompleted {
32        remote: SocketAddr,
33        negotiated: NegotiatedParams,
34        at: ClientTimestamp,
35    },
36    SessionClosed {
37        remote: SocketAddr,
38        token: u64,
39        at: ClientTimestamp,
40    },
41
42    EchoSent {
43        seq: u32,
44        logical_seq: u64,
45        remote: SocketAddr,
46        scheduled_at: Instant,
47        sent_at: ClientTimestamp,
48        bytes: usize,
49        send_call: Duration,
50        timer_error: Duration,
51    },
52
53    EchoReply {
54        seq: u32,
55        logical_seq: u64,
56        remote: SocketAddr,
57        sent_at: ClientTimestamp,
58        received_at: ClientTimestamp,
59        rtt: RttSample,
60        server_timing: Option<ServerTiming>,
61        one_way: Option<OneWayDelaySample>,
62        received_stats: Option<ReceivedStatsSample>,
63        bytes: usize,
64        packet_meta: PacketMeta,
65    },
66
67    EchoLoss {
68        seq: u32,
69        logical_seq: u64,
70        sent_at: ClientTimestamp,
71        timeout_at: std::time::Instant,
72    },
73
74    DuplicateReply {
75        seq: u32,
76        remote: SocketAddr,
77        received_at: ClientTimestamp,
78        bytes: usize,
79    },
80
81    LateReply {
82        seq: u32,
83        logical_seq: Option<u64>,
84        highest_seen: u32,
85        remote: SocketAddr,
86        sent_at: Option<ClientTimestamp>,
87        received_at: ClientTimestamp,
88        rtt: Option<RttSample>,
89        server_timing: Option<ServerTiming>,
90        one_way: Option<OneWayDelaySample>,
91        received_stats: Option<ReceivedStatsSample>,
92        bytes: usize,
93        packet_meta: PacketMeta,
94    },
95
96    Warning {
97        kind: WarningKind,
98        message: String,
99    },
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub enum WarningKind {
104    MalformedOrUnrelatedPacket,
105    WrongToken,
106    UntrackedReply,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110pub struct RttSample {
111    pub raw: Duration,
112    pub adjusted: Option<Duration>,
113    pub effective: Duration,
114    pub adjusted_signed: Option<SignedDuration>,
115    pub effective_signed: SignedDuration,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119pub struct SignedDuration {
120    pub ns: i128,
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124pub struct ServerTiming {
125    pub receive_wall_ns: Option<i64>,
126    pub receive_mono_ns: Option<i64>,
127    pub send_wall_ns: Option<i64>,
128    pub send_mono_ns: Option<i64>,
129    pub midpoint_wall_ns: Option<i64>,
130    pub midpoint_mono_ns: Option<i64>,
131    pub processing: Option<Duration>,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
135pub struct OneWayDelaySample {
136    pub client_to_server: Option<Duration>,
137    pub server_to_client: Option<Duration>,
138}
139
140#[derive(Debug, Clone, Copy, PartialEq, Eq)]
141pub struct ReceivedStatsSample {
142    pub count: Option<u32>,
143    pub window: Option<u64>,
144}
145
146/// Receive-side packet metadata observed outside the IRTT wire protocol.
147///
148/// `None` means the metadata was unavailable. `Some(0)` means the metadata was
149/// observed and its value was zero.
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
151pub struct PacketMeta {
152    pub traffic_class: Option<u8>,
153    pub dscp: Option<u8>,
154    pub ecn: Option<u8>,
155    pub kernel_rx_timestamp: Option<std::time::SystemTime>,
156}
157
158#[cfg(test)]
159mod tests {
160    use super::PacketMeta;
161
162    #[test]
163    fn packet_meta_default_is_unavailable() {
164        let meta = PacketMeta::default();
165
166        assert_eq!(meta.traffic_class, None);
167        assert_eq!(meta.dscp, None);
168        assert_eq!(meta.ecn, None);
169        assert_eq!(meta.kernel_rx_timestamp, None);
170    }
171}