Coverage Report

Created: 2025-11-02 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/qlog-0.15.2/src/events/quic.rs
Line
Count
Source
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
27
use serde::Deserialize;
28
use serde::Serialize;
29
30
use smallvec::SmallVec;
31
32
use super::connectivity::TransportOwner;
33
use super::Bytes;
34
use super::DataRecipient;
35
use super::RawInfo;
36
use super::Token;
37
use crate::HexSlice;
38
use crate::StatelessResetToken;
39
40
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
41
#[serde(rename_all = "snake_case")]
42
pub enum PacketType {
43
    Initial,
44
    Handshake,
45
46
    #[serde(rename = "0RTT")]
47
    ZeroRtt,
48
49
    #[serde(rename = "1RTT")]
50
    OneRtt,
51
52
    Retry,
53
    VersionNegotiation,
54
    #[default]
55
    Unknown,
56
}
57
58
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
59
#[serde(rename_all = "snake_case")]
60
pub enum PacketNumberSpace {
61
    Initial,
62
    Handshake,
63
    ApplicationData,
64
}
65
66
#[serde_with::skip_serializing_none]
67
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
68
pub struct PacketHeader {
69
    pub packet_type: PacketType,
70
    pub packet_number: Option<u64>,
71
72
    pub flags: Option<u8>,
73
    pub token: Option<Token>,
74
75
    pub length: Option<u16>,
76
77
    pub version: Option<Bytes>,
78
79
    pub scil: Option<u8>,
80
    pub dcil: Option<u8>,
81
    pub scid: Option<Bytes>,
82
    pub dcid: Option<Bytes>,
83
}
84
85
impl PacketHeader {
86
    #[allow(clippy::too_many_arguments)]
87
    /// Creates a new PacketHeader.
88
3.22k
    pub fn new(
89
3.22k
        packet_type: PacketType, packet_number: Option<u64>, flags: Option<u8>,
90
3.22k
        token: Option<Token>, length: Option<u16>, version: Option<u32>,
91
3.22k
        scid: Option<&[u8]>, dcid: Option<&[u8]>,
92
3.22k
    ) -> Self {
93
3.22k
        let (scil, scid) = match scid {
94
0
            Some(cid) => (
95
0
                Some(cid.len() as u8),
96
0
                Some(format!("{}", HexSlice::new(&cid))),
97
0
            ),
98
99
3.22k
            None => (None, None),
100
        };
101
102
3.22k
        let (dcil, dcid) = match dcid {
103
0
            Some(cid) => (
104
0
                Some(cid.len() as u8),
105
0
                Some(format!("{}", HexSlice::new(&cid))),
106
0
            ),
107
108
3.22k
            None => (None, None),
109
        };
110
111
3.22k
        let version = version.map(|v| format!("{v:x?}"));
112
113
3.22k
        PacketHeader {
114
3.22k
            packet_type,
115
3.22k
            packet_number,
116
3.22k
            flags,
117
3.22k
            token,
118
3.22k
            length,
119
3.22k
            version,
120
3.22k
            scil,
121
3.22k
            dcil,
122
3.22k
            scid,
123
3.22k
            dcid,
124
3.22k
        }
125
3.22k
    }
126
127
    /// Creates a new PacketHeader.
128
    ///
129
    /// Once a QUIC connection has formed, version, dcid and scid are stable, so
130
    /// there are space benefits to not logging them in every packet, especially
131
    /// PacketType::OneRtt.
132
3.22k
    pub fn with_type(
133
3.22k
        ty: PacketType, packet_number: Option<u64>, version: Option<u32>,
134
3.22k
        scid: Option<&[u8]>, dcid: Option<&[u8]>,
135
3.22k
    ) -> Self {
136
3.22k
        match ty {
137
0
            PacketType::OneRtt => PacketHeader::new(
138
0
                ty,
139
0
                packet_number,
140
0
                None,
141
0
                None,
142
0
                None,
143
0
                None,
144
0
                None,
145
0
                None,
146
            ),
147
148
3.22k
            _ => PacketHeader::new(
149
3.22k
                ty,
150
3.22k
                packet_number,
151
3.22k
                None,
152
3.22k
                None,
153
3.22k
                None,
154
3.22k
                version,
155
3.22k
                scid,
156
3.22k
                dcid,
157
            ),
158
        }
159
3.22k
    }
160
}
161
162
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
163
#[serde(rename_all = "snake_case")]
164
pub enum StreamType {
165
    Bidirectional,
166
    Unidirectional,
167
}
168
169
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
170
#[serde(rename_all = "snake_case")]
171
pub enum StreamSide {
172
    Sending,
173
    Receiving,
174
}
175
176
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
177
#[serde(rename_all = "snake_case")]
178
pub enum StreamState {
179
    // bidirectional stream states, draft-23 3.4.
180
    Idle,
181
    Open,
182
    HalfClosedLocal,
183
    HalfClosedRemote,
184
    Closed,
185
186
    // sending-side stream states, draft-23 3.1.
187
    Ready,
188
    Send,
189
    DataSent,
190
    ResetSent,
191
    ResetReceived,
192
193
    // receive-side stream states, draft-23 3.2.
194
    Receive,
195
    SizeKnown,
196
    DataRead,
197
    ResetRead,
198
199
    // both-side states
200
    DataReceived,
201
202
    // qlog-defined
203
    Destroyed,
204
}
205
206
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
207
#[serde(rename_all = "snake_case")]
208
pub enum ErrorSpace {
209
    TransportError,
210
    ApplicationError,
211
}
212
213
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
214
#[serde(rename_all = "snake_case")]
215
pub enum TransportError {
216
    NoError,
217
    InternalError,
218
    ConnectionRefused,
219
    FlowControlError,
220
    StreamLimitError,
221
    StreamStateError,
222
    FinalSizeError,
223
    FrameEncodingError,
224
    TransportParameterError,
225
    ConnectionIdLimitError,
226
    ProtocolViolation,
227
    InvalidToken,
228
    ApplicationError,
229
    CryptoBufferExceeded,
230
    KeyUpdateError,
231
    AeadLimitReached,
232
    NoViablePath,
233
}
234
235
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
236
#[serde(rename_all = "snake_case")]
237
pub enum TransportEventType {
238
    VersionInformation,
239
    AlpnInformation,
240
241
    ParametersSet,
242
    ParametersRestored,
243
244
    DatagramsSent,
245
    DatagramsReceived,
246
    DatagramDropped,
247
248
    PacketSent,
249
    PacketReceived,
250
    PacketDropped,
251
    PacketBuffered,
252
    PacketsAcked,
253
254
    FramesProcessed,
255
256
    StreamStateUpdated,
257
258
    DataMoved,
259
}
260
261
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
262
#[serde(rename_all = "snake_case")]
263
pub enum PacketSentTrigger {
264
    RetransmitReordered,
265
    RetransmitTimeout,
266
    PtoProbe,
267
    RetransmitCrypto,
268
    CcBandwidthProbe,
269
}
270
271
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
272
#[serde(rename_all = "snake_case")]
273
pub enum PacketReceivedTrigger {
274
    KeysUnavailable,
275
}
276
277
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
278
#[serde(rename_all = "snake_case")]
279
pub enum PacketDroppedTrigger {
280
    InternalError,
281
    Rejected,
282
    Unsupported,
283
    Invalid,
284
    ConnectionUnknown,
285
    DecryptionFailure,
286
    General,
287
}
288
289
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
290
#[serde(rename_all = "snake_case")]
291
pub enum PacketBufferedTrigger {
292
    Backpressure,
293
    KeysUnavailable,
294
}
295
296
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
297
#[serde(rename_all = "snake_case")]
298
pub enum SecurityEventType {
299
    KeyUpdated,
300
    KeyDiscarded,
301
}
302
303
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
304
#[serde(rename_all = "snake_case")]
305
pub enum RecoveryEventType {
306
    ParametersSet,
307
    MetricsUpdated,
308
    CongestionStateUpdated,
309
    LossTimerUpdated,
310
    PacketLost,
311
    MarkedForRetransmit,
312
}
313
314
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
315
#[serde(rename_all = "snake_case")]
316
pub enum CongestionStateUpdatedTrigger {
317
    PersistentCongestion,
318
    Ecn,
319
}
320
321
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
322
#[serde(rename_all = "snake_case")]
323
pub enum PacketLostTrigger {
324
    ReorderingThreshold,
325
    TimeThreshold,
326
    PtoExpired,
327
}
328
329
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
330
#[serde(rename_all = "snake_case")]
331
pub enum LossTimerEventType {
332
    Set,
333
    Expired,
334
    Cancelled,
335
}
336
337
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
338
#[serde(rename_all = "snake_case")]
339
pub enum TimerType {
340
    Ack,
341
    Pto,
342
}
343
344
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
345
#[serde(untagged)]
346
pub enum AckedRanges {
347
    Single(Vec<Vec<u64>>),
348
    Double(Vec<(u64, u64)>),
349
}
350
351
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
352
#[serde(rename_all = "snake_case")]
353
pub enum QuicFrameTypeName {
354
    Padding,
355
    Ping,
356
    Ack,
357
    ResetStream,
358
    StopSending,
359
    Crypto,
360
    NewToken,
361
    Stream,
362
    MaxData,
363
    MaxStreamData,
364
    MaxStreams,
365
    DataBlocked,
366
    StreamDataBlocked,
367
    StreamsBlocked,
368
    NewConnectionId,
369
    RetireConnectionId,
370
    PathChallenge,
371
    PathResponse,
372
    ConnectionClose,
373
    ApplicationClose,
374
    HandshakeDone,
375
    Datagram,
376
    #[default]
377
    Unknown,
378
}
379
380
#[serde_with::skip_serializing_none]
381
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
382
#[serde(tag = "frame_type")]
383
#[serde(rename_all = "snake_case")]
384
// Strictly, the qlog spec says that all these frame types have a frame_type
385
// field. But instead of making that a rust object property, just use serde to
386
// ensure it goes out on the wire. This means that deserialization of frames
387
// also works automatically.
388
pub enum QuicFrame {
389
    Padding {
390
        length: Option<u32>,
391
        payload_length: u32,
392
    },
393
394
    Ping {
395
        length: Option<u32>,
396
        payload_length: Option<u32>,
397
    },
398
399
    Ack {
400
        ack_delay: Option<f32>,
401
        acked_ranges: Option<AckedRanges>,
402
403
        ect1: Option<u64>,
404
        ect0: Option<u64>,
405
        ce: Option<u64>,
406
407
        length: Option<u32>,
408
        payload_length: Option<u32>,
409
    },
410
411
    ResetStream {
412
        stream_id: u64,
413
        error_code: u64,
414
        final_size: u64,
415
416
        length: Option<u32>,
417
        payload_length: Option<u32>,
418
    },
419
420
    StopSending {
421
        stream_id: u64,
422
        error_code: u64,
423
424
        length: Option<u32>,
425
        payload_length: Option<u32>,
426
    },
427
428
    Crypto {
429
        offset: u64,
430
        length: u64,
431
    },
432
433
    NewToken {
434
        token: Token,
435
    },
436
437
    Stream {
438
        stream_id: u64,
439
        offset: u64,
440
        length: u64,
441
        fin: Option<bool>,
442
443
        raw: Option<RawInfo>,
444
    },
445
446
    MaxData {
447
        maximum: u64,
448
    },
449
450
    MaxStreamData {
451
        stream_id: u64,
452
        maximum: u64,
453
    },
454
455
    MaxStreams {
456
        stream_type: StreamType,
457
        maximum: u64,
458
    },
459
460
    DataBlocked {
461
        limit: u64,
462
    },
463
464
    StreamDataBlocked {
465
        stream_id: u64,
466
        limit: u64,
467
    },
468
469
    StreamsBlocked {
470
        stream_type: StreamType,
471
        limit: u64,
472
    },
473
474
    NewConnectionId {
475
        sequence_number: u32,
476
        retire_prior_to: u32,
477
        connection_id_length: Option<u8>,
478
        connection_id: Bytes,
479
        stateless_reset_token: Option<StatelessResetToken>,
480
    },
481
482
    RetireConnectionId {
483
        sequence_number: u32,
484
    },
485
486
    PathChallenge {
487
        data: Option<Bytes>,
488
    },
489
490
    PathResponse {
491
        data: Option<Bytes>,
492
    },
493
494
    ConnectionClose {
495
        error_space: Option<ErrorSpace>,
496
        error_code: Option<u64>,
497
        error_code_value: Option<u64>,
498
        reason: Option<String>,
499
500
        trigger_frame_type: Option<u64>,
501
    },
502
503
    HandshakeDone,
504
505
    Datagram {
506
        length: u64,
507
508
        raw: Option<Bytes>,
509
    },
510
511
    Unknown {
512
        raw_frame_type: u64,
513
        frame_type_value: Option<u64>,
514
        raw: Option<RawInfo>,
515
    },
516
}
517
518
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
519
pub struct PreferredAddress {
520
    pub ip_v4: String,
521
    pub ip_v6: String,
522
523
    pub port_v4: u16,
524
    pub port_v6: u16,
525
526
    pub connection_id: Bytes,
527
    pub stateless_reset_token: StatelessResetToken,
528
}
529
530
#[serde_with::skip_serializing_none]
531
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
532
pub struct VersionInformation {
533
    pub server_versions: Option<Vec<Bytes>>,
534
    pub client_versions: Option<Vec<Bytes>>,
535
    pub chosen_version: Option<Bytes>,
536
}
537
538
#[serde_with::skip_serializing_none]
539
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
540
pub struct AlpnInformation {
541
    pub server_alpns: Option<Vec<Bytes>>,
542
    pub client_alpns: Option<Vec<Bytes>>,
543
    pub chosen_alpn: Option<Bytes>,
544
}
545
546
#[serde_with::skip_serializing_none]
547
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
548
pub struct TransportParametersSet {
549
    pub owner: Option<TransportOwner>,
550
551
    pub resumption_allowed: Option<bool>,
552
    pub early_data_enabled: Option<bool>,
553
    pub tls_cipher: Option<String>,
554
    pub aead_tag_length: Option<u8>,
555
556
    pub original_destination_connection_id: Option<Bytes>,
557
    pub initial_source_connection_id: Option<Bytes>,
558
    pub retry_source_connection_id: Option<Bytes>,
559
    pub stateless_reset_token: Option<StatelessResetToken>,
560
    pub disable_active_migration: Option<bool>,
561
562
    pub max_idle_timeout: Option<u64>,
563
    pub max_udp_payload_size: Option<u32>,
564
    pub ack_delay_exponent: Option<u16>,
565
    pub max_ack_delay: Option<u16>,
566
    pub active_connection_id_limit: Option<u32>,
567
568
    pub initial_max_data: Option<u64>,
569
    pub initial_max_stream_data_bidi_local: Option<u64>,
570
    pub initial_max_stream_data_bidi_remote: Option<u64>,
571
    pub initial_max_stream_data_uni: Option<u64>,
572
    pub initial_max_streams_bidi: Option<u64>,
573
    pub initial_max_streams_uni: Option<u64>,
574
575
    pub preferred_address: Option<PreferredAddress>,
576
577
    pub unknown_parameters: Vec<UnknownTransportParameter>,
578
}
579
580
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
581
pub struct UnknownTransportParameter {
582
    pub id: u64,
583
    pub value: Bytes,
584
}
585
586
#[serde_with::skip_serializing_none]
587
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
588
pub struct TransportParametersRestored {
589
    pub disable_active_migration: Option<bool>,
590
591
    pub max_idle_timeout: Option<u64>,
592
    pub max_udp_payload_size: Option<u32>,
593
    pub active_connection_id_limit: Option<u32>,
594
595
    pub initial_max_data: Option<u64>,
596
    pub initial_max_stream_data_bidi_local: Option<u64>,
597
    pub initial_max_stream_data_bidi_remote: Option<u64>,
598
    pub initial_max_stream_data_uni: Option<u64>,
599
    pub initial_max_streams_bidi: Option<u64>,
600
    pub initial_max_streams_uni: Option<u64>,
601
}
602
603
#[serde_with::skip_serializing_none]
604
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
605
pub struct DatagramsReceived {
606
    pub count: Option<u16>,
607
608
    pub raw: Option<Vec<RawInfo>>,
609
610
    pub datagram_ids: Option<Vec<u32>>,
611
}
612
613
#[serde_with::skip_serializing_none]
614
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
615
pub struct DatagramsSent {
616
    pub count: Option<u16>,
617
618
    pub raw: Option<Vec<RawInfo>>,
619
620
    pub datagram_ids: Option<Vec<u32>>,
621
}
622
623
#[serde_with::skip_serializing_none]
624
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
625
pub struct DatagramDropped {
626
    pub raw: Option<RawInfo>,
627
}
628
629
#[serde_with::skip_serializing_none]
630
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
631
pub struct PacketReceived {
632
    pub header: PacketHeader,
633
    // `frames` is defined here in the QLog schema specification. However,
634
    // our streaming serializer requires serde to put the object at the end,
635
    // so we define it there and depend on serde's preserve_order feature.
636
    pub is_coalesced: Option<bool>,
637
638
    pub retry_token: Option<Token>,
639
640
    pub stateless_reset_token: Option<StatelessResetToken>,
641
642
    pub supported_versions: Option<Vec<Bytes>>,
643
644
    pub raw: Option<RawInfo>,
645
    pub datagram_id: Option<u32>,
646
647
    pub trigger: Option<PacketReceivedTrigger>,
648
649
    pub frames: Option<Vec<QuicFrame>>,
650
}
651
652
#[serde_with::skip_serializing_none]
653
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
654
pub struct PacketSent {
655
    pub header: PacketHeader,
656
    // `frames` is defined here in the QLog schema specification. However,
657
    // our streaming serializer requires serde to put the object at the end,
658
    // so we define it there and depend on serde's preserve_order feature.
659
    pub is_coalesced: Option<bool>,
660
661
    pub retry_token: Option<Token>,
662
663
    pub stateless_reset_token: Option<StatelessResetToken>,
664
665
    pub supported_versions: Option<Vec<Bytes>>,
666
667
    pub raw: Option<RawInfo>,
668
    pub datagram_id: Option<u32>,
669
670
    pub trigger: Option<PacketSentTrigger>,
671
672
    pub send_at_time: Option<f32>,
673
674
    pub frames: Option<SmallVec<[QuicFrame; 1]>>,
675
}
676
677
#[serde_with::skip_serializing_none]
678
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
679
pub struct PacketDropped {
680
    pub header: Option<PacketHeader>,
681
682
    pub raw: Option<RawInfo>,
683
    pub datagram_id: Option<u32>,
684
685
    pub details: Option<String>,
686
687
    pub trigger: Option<PacketDroppedTrigger>,
688
}
689
690
#[serde_with::skip_serializing_none]
691
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
692
pub struct PacketBuffered {
693
    pub header: Option<PacketHeader>,
694
695
    pub raw: Option<RawInfo>,
696
    pub datagram_id: Option<u32>,
697
698
    pub trigger: Option<PacketBufferedTrigger>,
699
}
700
701
#[serde_with::skip_serializing_none]
702
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
703
pub struct PacketsAcked {
704
    pub packet_number_space: Option<PacketNumberSpace>,
705
    pub packet_numbers: Option<Vec<u64>>,
706
}
707
708
#[serde_with::skip_serializing_none]
709
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
710
pub struct StreamStateUpdated {
711
    pub stream_id: u64,
712
    pub stream_type: Option<StreamType>,
713
714
    pub old: Option<StreamState>,
715
    pub new: StreamState,
716
717
    pub stream_side: Option<StreamSide>,
718
}
719
720
#[serde_with::skip_serializing_none]
721
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
722
pub struct FramesProcessed {
723
    pub frames: Vec<QuicFrame>,
724
725
    pub packet_number: Option<u64>,
726
}
727
728
#[serde_with::skip_serializing_none]
729
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
730
pub struct DataMoved {
731
    pub stream_id: Option<u64>,
732
    pub offset: Option<u64>,
733
    pub length: Option<u64>,
734
735
    pub from: Option<DataRecipient>,
736
    pub to: Option<DataRecipient>,
737
738
    pub raw: Option<RawInfo>,
739
}
740
741
#[serde_with::skip_serializing_none]
742
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
743
pub struct RecoveryParametersSet {
744
    pub reordering_threshold: Option<u16>,
745
    pub time_threshold: Option<f32>,
746
    pub timer_granularity: Option<u16>,
747
    pub initial_rtt: Option<f32>,
748
749
    pub max_datagram_size: Option<u32>,
750
    pub initial_congestion_window: Option<u64>,
751
    pub minimum_congestion_window: Option<u32>,
752
    pub loss_reduction_factor: Option<f32>,
753
    pub persistent_congestion_threshold: Option<u16>,
754
}
755
756
#[serde_with::skip_serializing_none]
757
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
758
pub struct MetricsUpdated {
759
    pub min_rtt: Option<f32>,
760
    pub smoothed_rtt: Option<f32>,
761
    pub latest_rtt: Option<f32>,
762
    pub rtt_variance: Option<f32>,
763
764
    pub pto_count: Option<u16>,
765
766
    pub congestion_window: Option<u64>,
767
    pub bytes_in_flight: Option<u64>,
768
769
    pub ssthresh: Option<u64>,
770
771
    // qlog defined
772
    pub packets_in_flight: Option<u64>,
773
774
    pub pacing_rate: Option<u64>,
775
}
776
777
#[serde_with::skip_serializing_none]
778
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
779
pub struct CongestionStateUpdated {
780
    pub old: Option<String>,
781
    pub new: String,
782
783
    pub trigger: Option<CongestionStateUpdatedTrigger>,
784
}
785
786
#[serde_with::skip_serializing_none]
787
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
788
pub struct LossTimerUpdated {
789
    pub timer_type: Option<TimerType>,
790
    pub packet_number_space: Option<PacketNumberSpace>,
791
792
    pub event_type: LossTimerEventType,
793
794
    pub delta: Option<f32>,
795
}
796
797
#[serde_with::skip_serializing_none]
798
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
799
pub struct PacketLost {
800
    pub header: Option<PacketHeader>,
801
802
    pub frames: Option<Vec<QuicFrame>>,
803
804
    pub trigger: Option<PacketLostTrigger>,
805
}
806
807
#[serde_with::skip_serializing_none]
808
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
809
pub struct MarkedForRetransmit {
810
    pub frames: Vec<QuicFrame>,
811
}
812
813
#[cfg(test)]
814
mod tests {
815
    use super::*;
816
    use crate::testing::*;
817
818
    #[test]
819
    fn packet_header() {
820
        let pkt_hdr = make_pkt_hdr(PacketType::Initial);
821
822
        let log_string = r#"{
823
  "packet_type": "initial",
824
  "packet_number": 0,
825
  "version": "1",
826
  "scil": 8,
827
  "dcil": 8,
828
  "scid": "7e37e4dcc6682da8",
829
  "dcid": "36ce104eee50101c"
830
}"#;
831
832
        assert_eq!(serde_json::to_string_pretty(&pkt_hdr).unwrap(), log_string);
833
    }
834
}