Skip to main content

qlog/events/
quic.rs

1// Copyright (C) 2021, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright notice,
9//       this list of conditions and the following disclaimer.
10//
11//     * Redistributions in binary form must reproduce the above copyright
12//       notice, this list of conditions and the following disclaimer in the
13//       documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27use serde::de;
28use serde::Deserialize;
29use serde::Deserializer;
30use serde::Serialize;
31use serde::Serializer;
32
33use std::fmt;
34use std::ops::RangeInclusive;
35
36use super::ExData;
37use crate::HexSlice;
38
39use crate::events::ApplicationError;
40use crate::events::ConnectionClosedEventError;
41use crate::events::ConnectionClosedFrameError;
42use crate::events::DataRecipient;
43use crate::events::RawInfo;
44use crate::events::Token;
45use crate::events::TupleEndpointInfo;
46use crate::Bytes;
47use crate::StatelessResetToken;
48
49/// A single ACK range with inclusive start and end packet numbers.
50///
51/// Serializes as a 1-element JSON array `[n]` when `start == end`, and as a
52/// 2-element JSON array `[start, end]` otherwise. Both forms are accepted
53/// during deserialization.
54///
55/// *Note*, the draft-ietf-quic-qlog-quic-events-12 specifies that the
56/// range is a closed interval, i.e., `range.end` is part of the range.
57#[derive(Clone, PartialEq, Debug, Copy)]
58pub struct AckRange {
59    /// The first packet number in the range (inclusive).
60    pub start: u64,
61    /// The last packet number in the range (inclusive).
62    pub end: u64,
63}
64
65impl AckRange {
66    /// Creates a new `AckRange` spanning `[start, end]` (both inclusive).
67    pub fn new(start: u64, end: u64) -> Self {
68        AckRange { start, end }
69    }
70
71    pub fn as_range_inclusive(&self) -> RangeInclusive<u64> {
72        self.start..=self.end
73    }
74}
75
76impl fmt::Display for AckRange {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        if self.start == self.end {
79            write!(f, "{}", self.start)
80        } else {
81            write!(f, "{}-{}", self.start, self.end)
82        }
83    }
84}
85
86impl Serialize for AckRange {
87    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
88        if self.start == self.end {
89            [self.start].serialize(s)
90        } else {
91            [self.start, self.end].serialize(s)
92        }
93    }
94}
95
96impl<'de> Deserialize<'de> for AckRange {
97    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
98        let v = Vec::<u64>::deserialize(d)?;
99        match v.as_slice() {
100            [x] => Ok(AckRange::new(*x, *x)),
101            [a, b] => Ok(AckRange::new(*a, *b)),
102            _ => Err(de::Error::custom("ack range must have 1 or 2 elements")),
103        }
104    }
105}
106
107#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
108#[serde(rename_all = "snake_case")]
109pub enum PacketType {
110    Initial,
111    Handshake,
112
113    #[serde(rename = "0RTT")]
114    ZeroRtt,
115
116    #[serde(rename = "1RTT")]
117    OneRtt,
118
119    Retry,
120    VersionNegotiation,
121    StatelessReset,
122    #[default]
123    Unknown,
124}
125
126#[serde_with::skip_serializing_none]
127#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
128pub struct PacketHeader {
129    pub packet_type: PacketType,
130    pub packet_type_bytes: Option<u64>,
131    pub spin_bit: Option<bool>,
132    pub key_phase: Option<u64>,
133    pub key_phase_bit: Option<bool>,
134    pub packet_number_length: Option<u8>,
135    pub packet_number: Option<u64>,
136
137    pub token: Option<Box<Token>>,
138
139    pub length: Option<u16>,
140
141    pub version: Option<Bytes>,
142
143    pub scil: Option<u8>,
144    pub dcil: Option<u8>,
145    pub scid: Option<Bytes>,
146    pub dcid: Option<Bytes>,
147}
148
149impl PacketHeader {
150    #[allow(clippy::too_many_arguments)]
151    /// Creates a new PacketHeader.
152    pub fn new(
153        packet_type: PacketType, packet_number: Option<u64>,
154        token: Option<Box<Token>>, length: Option<u16>, version: Option<u32>,
155        scid: Option<&[u8]>, dcid: Option<&[u8]>,
156    ) -> Self {
157        let (scil, scid) = match scid {
158            Some(cid) => (
159                Some(cid.len() as u8),
160                Some(format!("{}", HexSlice::new(&cid))),
161            ),
162
163            None => (None, None),
164        };
165
166        let (dcil, dcid) = match dcid {
167            Some(cid) => (
168                Some(cid.len() as u8),
169                Some(format!("{}", HexSlice::new(&cid))),
170            ),
171
172            None => (None, None),
173        };
174
175        let version = version.map(|v| format!("{v:x?}"));
176
177        PacketHeader {
178            packet_type,
179            packet_number,
180            token,
181            length,
182            version,
183            scil,
184            dcil,
185            scid,
186            dcid,
187            ..Default::default()
188        }
189    }
190
191    /// Creates a new PacketHeader.
192    ///
193    /// Once a QUIC connection has formed, version, dcid and scid are stable, so
194    /// there are space benefits to not logging them in every packet, especially
195    /// PacketType::OneRtt.
196    pub fn with_type(
197        ty: PacketType, packet_number: Option<u64>, version: Option<u32>,
198        scid: Option<&[u8]>, dcid: Option<&[u8]>,
199    ) -> Self {
200        match ty {
201            PacketType::OneRtt =>
202                PacketHeader::new(ty, packet_number, None, None, None, None, None),
203
204            _ => PacketHeader::new(
205                ty,
206                packet_number,
207                None,
208                None,
209                version,
210                scid,
211                dcid,
212            ),
213        }
214    }
215}
216
217#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
218#[serde(rename_all = "snake_case")]
219pub enum PacketNumberSpace {
220    Initial,
221    Handshake,
222    ApplicationData,
223}
224
225#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
226#[serde(rename_all = "snake_case")]
227pub enum StreamType {
228    Bidirectional,
229    Unidirectional,
230}
231
232#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
233#[serde(rename_all = "snake_case")]
234pub enum StreamTrigger {
235    Local,
236    Remote,
237}
238
239#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
240#[serde(rename_all = "snake_case")]
241pub enum StreamState {
242    Idle,
243    Open,
244    Closed,
245
246    HalfClosedLocal,
247    HalfClosedRemote,
248    Ready,
249    Send,
250    DataSent,
251    ResetSent,
252    ResetReceived,
253    Receive,
254    SizeKnown,
255    DataRead,
256    ResetRead,
257    DataReceived,
258    Destroyed,
259}
260
261#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
262#[serde(rename_all = "snake_case")]
263pub enum ErrorSpace {
264    Transport,
265    Application,
266}
267
268#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
269#[serde(rename_all = "snake_case")]
270pub enum TransportError {
271    NoError,
272    InternalError,
273    ConnectionRefused,
274    FlowControlError,
275    StreamLimitError,
276    StreamStateError,
277    FinalSizeError,
278    FrameEncodingError,
279    TransportParameterError,
280    ConnectionIdLimitError,
281    ProtocolViolation,
282    InvalidToken,
283    ApplicationError,
284    CryptoBufferExceeded,
285    KeyUpdateError,
286    AeadLimitReached,
287    NoViablePath,
288    Unknown,
289}
290
291#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
292#[serde(rename_all = "snake_case")]
293pub enum QuicEventType {
294    ServerListening,
295    ConnectionStarted,
296    ConnectionClosed,
297    ConnectionIdUpdated,
298    SpinBitUpdated,
299    ConnectionStateUpdated,
300    TupleAssigned,
301    MtuUpdated,
302
303    VersionInformation,
304    AlpnInformation,
305    ParametersSet,
306    ParametersRestored,
307    PacketSent,
308    PacketReceived,
309    PacketDropped,
310    PacketBuffered,
311    PacketsAcked,
312    UdpDatagramsSent,
313    UdpDatagramsReceived,
314    UdpDatagramDropped,
315    StreamStateUpdated,
316    FramesProcessed,
317    StreamDataMoved,
318    DatagramDataMoved,
319    ConnectionDataBlockedUpdated,
320    StreamDataBlockedUpdated,
321    DatagramDataBlockedUpdated,
322    MigrationStateUpdated,
323
324    KeyUpdated,
325    KeyDiscarded,
326
327    RecoveryParametersSet,
328    RecoveryMetricsUpdated,
329    CongestionStateUpdated,
330    TimerUpdated,
331    PacketLost,
332    MarkedForRetransmit,
333    EcnStateUpdated,
334}
335
336#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
337#[serde(rename_all = "snake_case")]
338pub enum TransportInitiator {
339    Local,
340    Remote,
341}
342
343#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
344#[serde(rename_all = "snake_case")]
345pub enum ConnectionState {
346    Attempted,
347    PeerValidated,
348    HandshakeStarted,
349    EarlyWrite,
350    HandshakeCompleted,
351    HandshakeConfirmed,
352    Closing,
353    Draining,
354    Closed,
355}
356
357#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
358#[serde(rename_all = "snake_case")]
359pub enum ConnectionClosedTrigger {
360    Clean,
361    HandshakeTimeout,
362    IdleTimeout,
363    Error,
364    StatelessReset,
365    VersionMismatch,
366    Application,
367}
368
369#[serde_with::skip_serializing_none]
370#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
371pub struct ServerListening {
372    pub ip_v4: Option<String>, // human-readable or bytes
373    pub port_v4: Option<u16>,
374    pub ip_v6: Option<String>, // human-readable or bytes
375    pub port_v6: Option<u16>,
376
377    pub retry_required: Option<bool>,
378}
379
380#[serde_with::skip_serializing_none]
381#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
382pub struct ConnectionStarted {
383    pub local: TupleEndpointInfo,
384    pub remote: TupleEndpointInfo,
385}
386
387#[serde_with::skip_serializing_none]
388#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
389pub struct ConnectionClosed {
390    pub initiator: Option<TransportInitiator>,
391
392    pub connection_error: Option<ConnectionClosedEventError>,
393    pub application_error: Option<ApplicationError>,
394    pub error_code: Option<u64>,
395    pub internal_code: Option<u64>,
396
397    pub reason: Option<String>,
398
399    pub trigger: Option<ConnectionClosedTrigger>,
400}
401
402#[serde_with::skip_serializing_none]
403#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
404pub struct ConnectionIdUpdated {
405    pub owner: Option<TransportInitiator>,
406
407    pub old: Option<Bytes>,
408    pub new: Option<Bytes>,
409}
410
411#[serde_with::skip_serializing_none]
412#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
413pub struct SpinBitUpdated {
414    pub state: bool,
415}
416
417#[serde_with::skip_serializing_none]
418#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
419pub struct ConnectionStateUpdated {
420    pub old: Option<ConnectionState>,
421    pub new: ConnectionState,
422}
423
424#[serde_with::skip_serializing_none]
425#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
426pub struct TupleAssigned {
427    pub tuple_id: String,
428    pub tuple_remote: Option<TupleEndpointInfo>,
429    pub tuple_local: Option<TupleEndpointInfo>,
430}
431
432#[serde_with::skip_serializing_none]
433#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
434pub struct MtuUpdated {
435    pub old: Option<u32>,
436    pub new: u32,
437    pub done: Option<bool>,
438}
439
440#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
441#[serde(rename_all = "snake_case")]
442pub enum PacketSentTrigger {
443    RetransmitReordered,
444    RetransmitTimeout,
445    PtoProbe,
446    RetransmitCrypto,
447    CcBandwidthProbe,
448}
449
450#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
451#[serde(rename_all = "snake_case")]
452pub enum PacketReceivedTrigger {
453    KeysUnavailable,
454}
455
456#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
457#[serde(rename_all = "snake_case")]
458pub enum PacketDroppedTrigger {
459    InternalError,
460    Rejected,
461    Unsupported,
462    Invalid,
463    ConnectionUnknown,
464    DecryptionFailure,
465    General,
466}
467
468#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
469#[serde(rename_all = "snake_case")]
470pub enum PacketBufferedTrigger {
471    Backpressure,
472    KeysUnavailable,
473}
474
475#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
476#[serde(rename_all = "snake_case")]
477pub enum QuicFrameTypeName {
478    Padding,
479    Ping,
480    Ack,
481    ResetStream,
482    StopSending,
483    Crypto,
484    NewToken,
485    Stream,
486    MaxData,
487    MaxStreamData,
488    MaxStreams,
489    DataBlocked,
490    StreamDataBlocked,
491    StreamsBlocked,
492    NewConnectionId,
493    RetireConnectionId,
494    PathChallenge,
495    PathResponse,
496    ConnectionClose,
497    ApplicationClose,
498    HandshakeDone,
499    Datagram,
500    #[default]
501    Unknown,
502}
503
504#[serde_with::skip_serializing_none]
505#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
506#[serde(tag = "frame_type")]
507#[serde(rename_all = "snake_case")]
508// Strictly, the qlog spec says that all these frame types have a frame_type
509// field. But instead of making that a rust object property, just use serde to
510// ensure it goes out on the wire. This means that deserialization of frames
511// also works automatically.
512pub enum QuicFrame {
513    Padding {
514        raw: Option<Box<RawInfo>>,
515    },
516
517    Ping {
518        raw: Option<Box<RawInfo>>,
519    },
520
521    Ack {
522        ack_delay: Option<f32>,
523        acked_ranges: Option<Vec<AckRange>>,
524
525        ect1: Option<u64>,
526        ect0: Option<u64>,
527        ce: Option<u64>,
528
529        raw: Option<Box<RawInfo>>,
530    },
531
532    ResetStream {
533        stream_id: u64,
534        error: ApplicationError,
535        error_code: Option<u64>,
536        final_size: u64,
537
538        raw: Option<Box<RawInfo>>,
539    },
540
541    StopSending {
542        stream_id: u64,
543        error: ApplicationError,
544        error_code: Option<u64>,
545
546        raw: Option<Box<RawInfo>>,
547    },
548
549    Crypto {
550        offset: u64,
551        raw: Option<Box<RawInfo>>,
552    },
553
554    NewToken {
555        token: Token,
556        raw: Option<Box<RawInfo>>,
557    },
558
559    Stream {
560        stream_id: u64,
561        offset: Option<u64>,
562        fin: Option<bool>,
563
564        raw: Option<Box<RawInfo>>,
565    },
566
567    MaxData {
568        maximum: u64,
569        raw: Option<Box<RawInfo>>,
570    },
571
572    MaxStreamData {
573        stream_id: u64,
574        maximum: u64,
575        raw: Option<Box<RawInfo>>,
576    },
577
578    MaxStreams {
579        stream_type: StreamType,
580        maximum: u64,
581        raw: Option<Box<RawInfo>>,
582    },
583
584    DataBlocked {
585        limit: u64,
586        raw: Option<Box<RawInfo>>,
587    },
588
589    StreamDataBlocked {
590        stream_id: u64,
591        limit: u64,
592        raw: Option<Box<RawInfo>>,
593    },
594
595    StreamsBlocked {
596        stream_type: StreamType,
597        limit: u64,
598        raw: Option<Box<RawInfo>>,
599    },
600
601    NewConnectionId {
602        sequence_number: u64,
603        retire_prior_to: u64,
604        connection_id_length: Option<u8>,
605        connection_id: Bytes,
606        stateless_reset_token: Option<StatelessResetToken>,
607        raw: Option<Box<RawInfo>>,
608    },
609
610    RetireConnectionId {
611        sequence_number: u64,
612        raw: Option<Box<RawInfo>>,
613    },
614
615    PathChallenge {
616        data: Option<Bytes>,
617        raw: Option<Box<RawInfo>>,
618    },
619
620    PathResponse {
621        data: Option<Bytes>,
622        raw: Option<Box<RawInfo>>,
623    },
624
625    ConnectionClose {
626        error_space: Option<ErrorSpace>,
627        error: Option<ConnectionClosedFrameError>,
628        error_code: Option<u64>,
629        reason: Option<String>,
630        reason_bytes: Option<Bytes>,
631
632        trigger_frame_type: Option<u64>,
633    },
634
635    HandshakeDone {
636        raw: Option<Box<RawInfo>>,
637    },
638
639    Datagram {
640        raw: Option<Box<RawInfo>>,
641    },
642
643    Unknown {
644        frame_type_bytes: Option<u64>,
645        raw: Option<Box<RawInfo>>,
646    },
647}
648
649#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
650pub struct PreferredAddress {
651    pub ip_v4: String,
652    pub ip_v6: String,
653
654    pub port_v4: u16,
655    pub port_v6: u16,
656
657    pub connection_id: Bytes,
658    pub stateless_reset_token: StatelessResetToken,
659}
660
661#[serde_with::skip_serializing_none]
662#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
663pub struct AlpnIdentifier {
664    pub byte_value: Option<Bytes>,
665    pub string_value: Option<String>,
666}
667
668#[serde_with::skip_serializing_none]
669#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
670pub struct QuicVersionInformation {
671    pub server_versions: Option<Vec<Bytes>>,
672    pub client_versions: Option<Vec<Bytes>>,
673    pub chosen_version: Option<Bytes>,
674}
675
676#[serde_with::skip_serializing_none]
677#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
678pub struct AlpnInformation {
679    pub server_alpns: Option<Vec<AlpnIdentifier>>,
680    pub client_alpns: Option<Vec<AlpnIdentifier>>,
681    pub chosen_alpn: Option<AlpnIdentifier>,
682}
683
684#[serde_with::skip_serializing_none]
685#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
686pub struct ParametersSet {
687    pub initiator: Option<TransportInitiator>,
688
689    pub resumption_allowed: Option<bool>,
690    pub early_data_enabled: Option<bool>,
691    pub tls_cipher: Option<String>,
692
693    pub original_destination_connection_id: Option<Bytes>,
694    pub initial_source_connection_id: Option<Bytes>,
695    pub retry_source_connection_id: Option<Bytes>,
696    pub stateless_reset_token: Option<StatelessResetToken>,
697    pub disable_active_migration: Option<bool>,
698
699    pub max_idle_timeout: Option<u64>,
700    pub max_udp_payload_size: Option<u64>,
701    pub ack_delay_exponent: Option<u64>,
702    pub max_ack_delay: Option<u64>,
703    pub active_connection_id_limit: Option<u64>,
704
705    pub initial_max_data: Option<u64>,
706    pub initial_max_stream_data_bidi_local: Option<u64>,
707    pub initial_max_stream_data_bidi_remote: Option<u64>,
708    pub initial_max_stream_data_uni: Option<u64>,
709    pub initial_max_streams_bidi: Option<u64>,
710    pub initial_max_streams_uni: Option<u64>,
711
712    pub preferred_address: Option<PreferredAddress>,
713
714    pub unknown_parameters: Vec<UnknownTransportParameter>,
715
716    pub max_datagram_frame_size: Option<u64>,
717    pub grease_quic_bit: Option<bool>,
718}
719
720#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
721pub struct UnknownTransportParameter {
722    pub id: u64,
723    pub value: Bytes,
724}
725
726#[serde_with::skip_serializing_none]
727#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
728pub struct ParametersRestored {
729    pub disable_active_migration: Option<bool>,
730
731    pub max_idle_timeout: Option<u64>,
732    pub max_udp_payload_size: Option<u64>,
733    pub active_connection_id_limit: Option<u64>,
734
735    pub initial_max_data: Option<u64>,
736    pub initial_max_stream_data_bidi_local: Option<u64>,
737    pub initial_max_stream_data_bidi_remote: Option<u64>,
738    pub initial_max_stream_data_uni: Option<u64>,
739    pub initial_max_streams_bidi: Option<u64>,
740    pub initial_max_streams_uni: Option<u64>,
741
742    pub max_datagram_frame_size: Option<u64>,
743    pub grease_quic_bit: Option<bool>,
744}
745
746#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
747pub enum Ecn {
748    #[serde(rename = "Not-ECT")]
749    NotEct,
750    #[serde(rename = "ECT(1)")]
751    Ect1,
752    #[serde(rename = "ECT(0)")]
753    Ect0,
754    #[serde(rename = "CE")]
755    CE,
756}
757
758#[serde_with::skip_serializing_none]
759#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
760pub struct UdpDatagramsReceived {
761    pub count: Option<u16>,
762    pub raw: Option<Vec<RawInfo>>,
763    pub ecn: Option<Ecn>,
764    pub datagram_ids: Option<Vec<u32>>,
765}
766
767#[serde_with::skip_serializing_none]
768#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
769pub struct UdpDatagramsSent {
770    pub count: Option<u16>,
771    pub raw: Option<Vec<RawInfo>>,
772    pub ecn: Option<Ecn>,
773    pub datagram_ids: Option<Vec<u32>>,
774}
775
776#[serde_with::skip_serializing_none]
777#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
778pub struct UdpDatagramDropped {
779    pub raw: Option<RawInfo>,
780}
781
782#[serde_with::skip_serializing_none]
783#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
784pub struct PacketReceived {
785    pub header: PacketHeader,
786    // `frames` is defined here in the QLog schema specification. However,
787    // our streaming serializer requires serde to put the object at the end,
788    // so we define it there and depend on serde's preserve_order feature.
789    pub stateless_reset_token: Option<Box<StatelessResetToken>>,
790
791    pub supported_versions: Option<Vec<Bytes>>,
792
793    pub raw: Option<RawInfo>,
794    pub datagram_id: Option<u32>,
795
796    pub trigger: Option<PacketReceivedTrigger>,
797
798    pub frames: Option<Vec<QuicFrame>>,
799}
800
801#[serde_with::skip_serializing_none]
802#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
803pub struct PacketSent {
804    pub header: PacketHeader,
805    // `frames` is defined here in the QLog schema specification. However,
806    // our streaming serializer requires serde to put the object at the end,
807    // so we define it there and depend on serde's preserve_order feature.
808    pub stateless_reset_token: Option<Box<StatelessResetToken>>,
809
810    pub supported_versions: Option<Vec<Bytes>>,
811
812    pub raw: Option<RawInfo>,
813    pub datagram_id: Option<u32>,
814    pub is_mtu_probe_packet: Option<bool>,
815
816    pub trigger: Option<PacketSentTrigger>,
817
818    pub send_at_time: Option<f64>,
819
820    pub frames: Option<Vec<QuicFrame>>,
821}
822
823#[serde_with::skip_serializing_none]
824#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
825pub struct PacketDropped {
826    pub header: Option<PacketHeader>,
827
828    pub raw: Option<RawInfo>,
829    pub datagram_id: Option<u32>,
830
831    pub details: Option<String>,
832
833    pub trigger: Option<PacketDroppedTrigger>,
834}
835
836#[serde_with::skip_serializing_none]
837#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
838pub struct PacketBuffered {
839    pub header: Option<PacketHeader>,
840
841    pub raw: Option<RawInfo>,
842    pub datagram_id: Option<u32>,
843
844    pub trigger: Option<PacketBufferedTrigger>,
845}
846
847#[serde_with::skip_serializing_none]
848#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
849pub struct PacketsAcked {
850    pub packet_number_space: Option<PacketNumberSpace>,
851    pub packet_numbers: Option<Vec<u64>>,
852}
853
854#[serde_with::skip_serializing_none]
855#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
856pub struct StreamStateUpdated {
857    pub stream_id: u64,
858    pub stream_type: Option<StreamType>,
859
860    pub old: Option<StreamState>,
861    pub new: StreamState,
862
863    pub trigger: Option<StreamTrigger>,
864}
865
866#[serde_with::skip_serializing_none]
867#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
868pub struct FramesProcessed {
869    pub frames: Vec<QuicFrame>,
870
871    pub packet_numbers: Option<u64>,
872}
873
874#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
875#[serde(rename_all = "snake_case")]
876pub enum DataMovedAdditionalInfo {
877    FinSet,
878    StreamReset,
879}
880
881#[serde_with::skip_serializing_none]
882#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
883pub struct StreamDataMoved {
884    pub stream_id: Option<u64>,
885    pub offset: Option<u64>,
886    pub from: Option<DataRecipient>,
887    pub to: Option<DataRecipient>,
888    pub additional_info: Option<DataMovedAdditionalInfo>,
889    pub raw: Option<RawInfo>,
890}
891
892#[serde_with::skip_serializing_none]
893#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
894pub struct DatagramDataMoved {
895    pub from: Option<DataRecipient>,
896    pub to: Option<DataRecipient>,
897    pub raw: Option<RawInfo>,
898}
899
900#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
901#[serde(rename_all = "snake_case")]
902pub enum BlockedState {
903    Blocked,
904    Unblocked,
905    #[default]
906    Unknown,
907}
908
909#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
910#[serde(rename_all = "snake_case")]
911pub enum BlockedReason {
912    Scheduled,
913    Pacing,
914    AmplificationProtection,
915    CongestionControl,
916    ConnectionFlowControl,
917    StreamFlowControl,
918    StreamId,
919    Application,
920}
921
922#[serde_with::skip_serializing_none]
923#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
924pub struct ConnectionDataBlockedUpdated {
925    pub old: Option<BlockedState>,
926    pub new: BlockedState,
927    pub reason: Option<BlockedReason>,
928}
929
930#[serde_with::skip_serializing_none]
931#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
932pub struct StreamDataBlockedUpdated {
933    pub old: Option<BlockedState>,
934    pub new: BlockedState,
935    pub stream_id: u64,
936    pub reason: Option<BlockedReason>,
937}
938
939#[serde_with::skip_serializing_none]
940#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
941pub struct DatagramDataBlockedUpdated {
942    pub old: Option<BlockedState>,
943    pub new: BlockedState,
944    pub reason: Option<BlockedReason>,
945}
946
947#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
948#[serde(rename_all = "snake_case")]
949pub enum MigrationState {
950    ProbingStarted,
951    ProbingAbandoned,
952    ProbingSuccessful,
953    MigrationStarted,
954    MigrationAbandoned,
955    MigrationComplete,
956    #[default]
957    Unknown,
958}
959
960#[serde_with::skip_serializing_none]
961#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
962pub struct MigrationStateUpdated {
963    pub old: Option<MigrationState>,
964    pub new: MigrationState,
965
966    pub tuple_id: Option<String>,
967
968    pub tuple_remote: Option<TupleEndpointInfo>,
969    pub tuple_local: Option<TupleEndpointInfo>,
970}
971
972#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, Default)]
973#[serde(rename_all = "snake_case")]
974pub enum CongestionStateUpdatedTrigger {
975    PersistentCongestion,
976    Ecn,
977    #[default]
978    Unknown,
979}
980
981#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
982#[serde(rename_all = "snake_case")]
983pub enum TimerType {
984    Ack,
985    Pto,
986    LossTimeout,
987    PathValidation,
988    HandshakeTimeout,
989    IdleTimeout,
990    #[default]
991    Unknown,
992}
993
994#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, Default)]
995#[serde(rename_all = "snake_case")]
996pub enum PacketLostTrigger {
997    ReorderingThreshold,
998    TimeThreshold,
999    PtoExpired,
1000    #[default]
1001    Unknown,
1002}
1003
1004#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
1005#[serde(rename_all = "snake_case")]
1006pub enum TimerEventType {
1007    Set,
1008    Expired,
1009    Cancelled,
1010    #[default]
1011    Unknown,
1012}
1013
1014#[serde_with::skip_serializing_none]
1015#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1016pub struct RecoveryParametersSet {
1017    pub reordering_threshold: Option<u16>,
1018    pub time_threshold: Option<f32>,
1019    pub timer_granularity: Option<u16>,
1020    pub initial_rtt: Option<f32>,
1021
1022    pub max_datagram_size: Option<u32>,
1023    pub initial_congestion_window: Option<u64>,
1024    pub minimum_congestion_window: Option<u32>,
1025    pub loss_reduction_factor: Option<f32>,
1026    pub persistent_congestion_threshold: Option<u16>,
1027}
1028
1029#[serde_with::skip_serializing_none]
1030#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1031pub struct RecoveryMetricsUpdated {
1032    /// Extension data for non-standard fields. `flatten` causes these fields to
1033    /// be serialized into the `data` field of a qlog event. On deserialize,
1034    /// unknown fields are collected into `ex_data`.
1035    #[serde(flatten)]
1036    pub ex_data: ExData,
1037
1038    pub min_rtt: Option<f32>,
1039    pub smoothed_rtt: Option<f32>,
1040    pub latest_rtt: Option<f32>,
1041    pub rtt_variance: Option<f32>,
1042
1043    pub pto_count: Option<u16>,
1044
1045    pub congestion_window: Option<u64>,
1046    pub bytes_in_flight: Option<u64>,
1047
1048    pub ssthresh: Option<u64>,
1049
1050    // qlog defined
1051    pub packets_in_flight: Option<u64>,
1052
1053    pub pacing_rate: Option<u64>,
1054}
1055
1056#[serde_with::skip_serializing_none]
1057#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
1058pub struct CongestionStateUpdated {
1059    pub old: Option<String>,
1060    pub new: String,
1061
1062    pub trigger: Option<CongestionStateUpdatedTrigger>,
1063}
1064
1065#[serde_with::skip_serializing_none]
1066#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
1067pub struct TimerUpdated {
1068    pub timer_type: Option<TimerType>,
1069    pub timer_id: Option<u64>,
1070    pub packet_number_space: Option<PacketNumberSpace>,
1071    pub event_type: TimerEventType,
1072    pub delta: Option<f32>,
1073}
1074
1075#[serde_with::skip_serializing_none]
1076#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1077pub struct PacketLost {
1078    pub header: Option<PacketHeader>,
1079
1080    pub frames: Option<Vec<QuicFrame>>,
1081    pub is_mtu_probe_packet: Option<bool>,
1082
1083    pub trigger: Option<PacketLostTrigger>,
1084}
1085
1086#[serde_with::skip_serializing_none]
1087#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1088pub struct MarkedForRetransmit {
1089    pub frames: Vec<QuicFrame>,
1090}
1091
1092#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
1093#[serde(rename_all = "snake_case")]
1094pub enum EcnState {
1095    Testing,
1096    #[default]
1097    Unknown,
1098    Failed,
1099    Capable,
1100}
1101
1102#[serde_with::skip_serializing_none]
1103#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1104pub struct EcnStateUpdated {
1105    pub old: Option<EcnState>,
1106    pub new: EcnState,
1107}
1108
1109#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
1110#[serde(rename_all = "snake_case")]
1111pub enum KeyType {
1112    ServerInitialSecret,
1113    ClientInitialSecret,
1114
1115    ServerHandshakeSecret,
1116    ClientHandshakeSecret,
1117
1118    #[serde(rename = "server_0rtt_secret")]
1119    Server0RttSecret,
1120    #[serde(rename = "client_0rtt_secret")]
1121    Client0RttSecret,
1122    #[serde(rename = "server_1rtt_secret")]
1123    Server1RttSecret,
1124    #[serde(rename = "client_1rtt_secret")]
1125    Client1RttSecret,
1126    #[default]
1127    Unknown,
1128}
1129
1130#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1131#[serde(rename_all = "snake_case")]
1132pub enum KeyUpdateOrRetiredTrigger {
1133    Tls,
1134    RemoteUpdate,
1135    LocalUpdate,
1136}
1137
1138#[serde_with::skip_serializing_none]
1139#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
1140pub struct KeyUpdated {
1141    pub key_type: KeyType,
1142
1143    pub old: Option<Bytes>,
1144    pub new: Option<Bytes>,
1145
1146    pub key_phase: Option<u64>,
1147
1148    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
1149}
1150
1151#[serde_with::skip_serializing_none]
1152#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1153pub struct KeyDiscarded {
1154    pub key_type: KeyType,
1155    pub key: Option<Bytes>,
1156
1157    pub key_phase: Option<u64>,
1158
1159    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
1160}