1use serde::Deserialize;
28use serde::Serialize;
29
30use smallvec::SmallVec;
31
32use super::connectivity::TransportOwner;
33use super::Bytes;
34use super::DataRecipient;
35use super::RawInfo;
36use super::Token;
37use crate::HexSlice;
38use crate::StatelessResetToken;
39
40#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
41#[serde(rename_all = "snake_case")]
42pub 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")]
60pub 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)]
68pub 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
85impl PacketHeader {
86 #[allow(clippy::too_many_arguments)]
87 pub fn new(
89 packet_type: PacketType, packet_number: Option<u64>, flags: Option<u8>,
90 token: Option<Token>, length: Option<u16>, version: Option<u32>,
91 scid: Option<&[u8]>, dcid: Option<&[u8]>,
92 ) -> Self {
93 let (scil, scid) = match scid {
94 Some(cid) => (
95 Some(cid.len() as u8),
96 Some(format!("{}", HexSlice::new(&cid))),
97 ),
98
99 None => (None, None),
100 };
101
102 let (dcil, dcid) = match dcid {
103 Some(cid) => (
104 Some(cid.len() as u8),
105 Some(format!("{}", HexSlice::new(&cid))),
106 ),
107
108 None => (None, None),
109 };
110
111 let version = version.map(|v| format!("{v:x?}"));
112
113 PacketHeader {
114 packet_type,
115 packet_number,
116 flags,
117 token,
118 length,
119 version,
120 scil,
121 dcil,
122 scid,
123 dcid,
124 }
125 }
126
127 pub fn with_type(
133 ty: PacketType, packet_number: Option<u64>, version: Option<u32>,
134 scid: Option<&[u8]>, dcid: Option<&[u8]>,
135 ) -> Self {
136 match ty {
137 PacketType::OneRtt => PacketHeader::new(
138 ty,
139 packet_number,
140 None,
141 None,
142 None,
143 None,
144 None,
145 None,
146 ),
147
148 _ => PacketHeader::new(
149 ty,
150 packet_number,
151 None,
152 None,
153 None,
154 version,
155 scid,
156 dcid,
157 ),
158 }
159 }
160}
161
162#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
163#[serde(rename_all = "snake_case")]
164pub enum StreamType {
165 Bidirectional,
166 Unidirectional,
167}
168
169#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
170#[serde(rename_all = "snake_case")]
171pub enum StreamSide {
172 Sending,
173 Receiving,
174}
175
176#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
177#[serde(rename_all = "snake_case")]
178pub enum StreamState {
179 Idle,
181 Open,
182 HalfClosedLocal,
183 HalfClosedRemote,
184 Closed,
185
186 Ready,
188 Send,
189 DataSent,
190 ResetSent,
191 ResetReceived,
192
193 Receive,
195 SizeKnown,
196 DataRead,
197 ResetRead,
198
199 DataReceived,
201
202 Destroyed,
204}
205
206#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
207#[serde(rename_all = "snake_case")]
208pub enum ErrorSpace {
209 TransportError,
210 ApplicationError,
211}
212
213#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
214#[serde(rename_all = "snake_case")]
215pub 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")]
237pub 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")]
263pub 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")]
273pub enum PacketReceivedTrigger {
274 KeysUnavailable,
275}
276
277#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
278#[serde(rename_all = "snake_case")]
279pub 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")]
291pub enum PacketBufferedTrigger {
292 Backpressure,
293 KeysUnavailable,
294}
295
296#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
297#[serde(rename_all = "snake_case")]
298pub enum SecurityEventType {
299 KeyUpdated,
300 KeyDiscarded,
301}
302
303#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
304#[serde(rename_all = "snake_case")]
305pub 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")]
316pub enum CongestionStateUpdatedTrigger {
317 PersistentCongestion,
318 Ecn,
319}
320
321#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
322#[serde(rename_all = "snake_case")]
323pub enum PacketLostTrigger {
324 ReorderingThreshold,
325 TimeThreshold,
326 PtoExpired,
327}
328
329#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
330#[serde(rename_all = "snake_case")]
331pub enum LossTimerEventType {
332 Set,
333 Expired,
334 Cancelled,
335}
336
337#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
338#[serde(rename_all = "snake_case")]
339pub enum TimerType {
340 Ack,
341 Pto,
342}
343
344#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
345#[serde(untagged)]
346pub 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")]
353pub 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")]
384pub 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)]
519pub 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)]
532pub 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)]
540pub 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)]
548pub 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)]
581pub 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)]
588pub 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)]
605pub 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)]
615pub 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)]
625pub struct DatagramDropped {
626 pub raw: Option<RawInfo>,
627}
628
629#[serde_with::skip_serializing_none]
630#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
631pub struct PacketReceived {
632 pub header: PacketHeader,
633 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)]
654pub struct PacketSent {
655 pub header: PacketHeader,
656 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)]
679pub 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)]
692pub 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)]
703pub 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)]
710pub 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)]
722pub 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)]
730pub 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)]
743pub 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)]
758pub 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 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)]
779pub 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)]
788pub 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)]
799pub 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)]
809pub struct MarkedForRetransmit {
810 pub frames: Vec<QuicFrame>,
811}
812
813#[cfg(test)]
814mod 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}