qlog/events/
mod.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 crate::Bytes;
28use crate::Token;
29use h3::*;
30use qpack::*;
31use quic::*;
32
33use connectivity::ConnectivityEventType;
34
35use serde::Deserialize;
36use serde::Serialize;
37
38use std::collections::BTreeMap;
39
40pub type ExData = BTreeMap<String, serde_json::Value>;
41
42#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, Default)]
43#[serde(untagged)]
44pub enum EventType {
45    ConnectivityEventType(ConnectivityEventType),
46
47    TransportEventType(TransportEventType),
48
49    SecurityEventType(SecurityEventType),
50
51    RecoveryEventType(RecoveryEventType),
52
53    Http3EventType(Http3EventType),
54
55    QpackEventType(QpackEventType),
56
57    GenericEventType(GenericEventType),
58
59    #[default]
60    None,
61}
62
63#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
64pub enum TimeFormat {
65    Absolute,
66    Delta,
67    Relative,
68}
69
70#[serde_with::skip_serializing_none]
71#[derive(Serialize, Deserialize, Clone, Debug)]
72pub struct Event {
73    pub time: f32,
74
75    // Strictly, the qlog 02 spec says we should have a name field in the
76    // `Event` structure. However, serde's autogenerated Deserialize code
77    // struggles to read Events properly because the `EventData` types often
78    // alias. In order to work around that, we use can use a trick that will
79    // give serde autogen all the information that it needs while also produced
80    // a legal qlog. Specifically, strongly linking an EventData enum variant
81    // with the wire-format name.
82    //
83    // The trick is to use Adjacent Tagging
84    // (https://serde.rs/enum-representations.html#adjacently-tagged) with
85    // Struct flattening (https://serde.rs/attr-flatten.html). At a high level
86    // this first creates an `EventData` JSON object:
87    //
88    // {name: <enum variant name>, data: enum variant data }
89    //
90    // and then flattens those fields into the `Event` object.
91    #[serde(flatten)]
92    pub data: EventData,
93
94    #[serde(flatten)]
95    pub ex_data: ExData,
96
97    pub protocol_type: Option<String>,
98    pub group_id: Option<String>,
99
100    pub time_format: Option<TimeFormat>,
101
102    #[serde(skip)]
103    ty: EventType,
104}
105
106impl Event {
107    /// Returns a new `Event` object with the provided time and data.
108    pub fn with_time(time: f32, data: EventData) -> Self {
109        Self::with_time_ex(time, data, Default::default())
110    }
111
112    /// Returns a new `Event` object with the provided time, data and ex_data.
113    pub fn with_time_ex(time: f32, data: EventData, ex_data: ExData) -> Self {
114        let ty = EventType::from(&data);
115        Event {
116            time,
117            data,
118            ex_data,
119            protocol_type: Default::default(),
120            group_id: Default::default(),
121            time_format: Default::default(),
122            ty,
123        }
124    }
125}
126
127impl Eventable for Event {
128    fn importance(&self) -> EventImportance {
129        self.ty.into()
130    }
131
132    fn set_time(&mut self, time: f32) {
133        self.time = time;
134    }
135}
136
137impl PartialEq for Event {
138    // custom comparison to skip over the `ty` field
139    fn eq(&self, other: &Event) -> bool {
140        self.time == other.time &&
141            self.data == other.data &&
142            self.ex_data == other.ex_data &&
143            self.protocol_type == other.protocol_type &&
144            self.group_id == other.group_id &&
145            self.time_format == other.time_format
146    }
147}
148
149#[derive(Serialize, Deserialize, Clone, Debug)]
150pub struct JsonEvent {
151    pub time: f32,
152
153    #[serde(skip)]
154    pub importance: EventImportance,
155
156    pub name: String,
157    pub data: serde_json::Value,
158}
159
160impl Eventable for JsonEvent {
161    fn importance(&self) -> EventImportance {
162        self.importance
163    }
164
165    fn set_time(&mut self, time: f32) {
166        self.time = time;
167    }
168}
169
170#[derive(Clone, Copy, Debug, Default)]
171pub enum EventImportance {
172    #[default]
173    Core,
174    Base,
175    Extra,
176}
177
178impl EventImportance {
179    /// Returns true if this importance level is included by `other`.
180    pub fn is_contained_in(&self, other: &EventImportance) -> bool {
181        match (other, self) {
182            (EventImportance::Core, EventImportance::Core) => true,
183
184            (EventImportance::Base, EventImportance::Core) |
185            (EventImportance::Base, EventImportance::Base) => true,
186
187            (EventImportance::Extra, EventImportance::Core) |
188            (EventImportance::Extra, EventImportance::Base) |
189            (EventImportance::Extra, EventImportance::Extra) => true,
190
191            (..) => false,
192        }
193    }
194}
195
196impl From<EventType> for EventImportance {
197    fn from(ty: EventType) -> Self {
198        match ty {
199            EventType::ConnectivityEventType(
200                ConnectivityEventType::ServerListening,
201            ) => EventImportance::Extra,
202            EventType::ConnectivityEventType(
203                ConnectivityEventType::ConnectionStarted,
204            ) => EventImportance::Base,
205            EventType::ConnectivityEventType(
206                ConnectivityEventType::ConnectionClosed,
207            ) => EventImportance::Base,
208            EventType::ConnectivityEventType(
209                ConnectivityEventType::ConnectionIdUpdated,
210            ) => EventImportance::Base,
211            EventType::ConnectivityEventType(
212                ConnectivityEventType::SpinBitUpdated,
213            ) => EventImportance::Base,
214            EventType::ConnectivityEventType(
215                ConnectivityEventType::ConnectionStateUpdated,
216            ) => EventImportance::Base,
217            EventType::ConnectivityEventType(
218                ConnectivityEventType::MtuUpdated,
219            ) => EventImportance::Extra,
220
221            EventType::SecurityEventType(SecurityEventType::KeyUpdated) =>
222                EventImportance::Base,
223            EventType::SecurityEventType(SecurityEventType::KeyDiscarded) =>
224                EventImportance::Base,
225
226            EventType::TransportEventType(
227                TransportEventType::VersionInformation,
228            ) => EventImportance::Core,
229            EventType::TransportEventType(
230                TransportEventType::AlpnInformation,
231            ) => EventImportance::Core,
232            EventType::TransportEventType(TransportEventType::ParametersSet) =>
233                EventImportance::Core,
234            EventType::TransportEventType(
235                TransportEventType::ParametersRestored,
236            ) => EventImportance::Base,
237            EventType::TransportEventType(
238                TransportEventType::DatagramsReceived,
239            ) => EventImportance::Extra,
240            EventType::TransportEventType(TransportEventType::DatagramsSent) =>
241                EventImportance::Extra,
242            EventType::TransportEventType(
243                TransportEventType::DatagramDropped,
244            ) => EventImportance::Extra,
245            EventType::TransportEventType(TransportEventType::PacketReceived) =>
246                EventImportance::Core,
247            EventType::TransportEventType(TransportEventType::PacketSent) =>
248                EventImportance::Core,
249            EventType::TransportEventType(TransportEventType::PacketDropped) =>
250                EventImportance::Base,
251            EventType::TransportEventType(TransportEventType::PacketBuffered) =>
252                EventImportance::Base,
253            EventType::TransportEventType(TransportEventType::PacketsAcked) =>
254                EventImportance::Extra,
255            EventType::TransportEventType(
256                TransportEventType::StreamStateUpdated,
257            ) => EventImportance::Base,
258            EventType::TransportEventType(
259                TransportEventType::FramesProcessed,
260            ) => EventImportance::Extra,
261            EventType::TransportEventType(TransportEventType::DataMoved) =>
262                EventImportance::Base,
263
264            EventType::RecoveryEventType(RecoveryEventType::ParametersSet) =>
265                EventImportance::Base,
266            EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated) =>
267                EventImportance::Core,
268            EventType::RecoveryEventType(
269                RecoveryEventType::CongestionStateUpdated,
270            ) => EventImportance::Base,
271            EventType::RecoveryEventType(RecoveryEventType::LossTimerUpdated) =>
272                EventImportance::Extra,
273            EventType::RecoveryEventType(RecoveryEventType::PacketLost) =>
274                EventImportance::Core,
275            EventType::RecoveryEventType(
276                RecoveryEventType::MarkedForRetransmit,
277            ) => EventImportance::Extra,
278
279            EventType::Http3EventType(Http3EventType::ParametersSet) =>
280                EventImportance::Base,
281            EventType::Http3EventType(Http3EventType::StreamTypeSet) =>
282                EventImportance::Base,
283            EventType::Http3EventType(Http3EventType::FrameCreated) =>
284                EventImportance::Core,
285            EventType::Http3EventType(Http3EventType::FrameParsed) =>
286                EventImportance::Core,
287            EventType::Http3EventType(Http3EventType::PushResolved) =>
288                EventImportance::Extra,
289
290            EventType::QpackEventType(QpackEventType::StateUpdated) =>
291                EventImportance::Base,
292            EventType::QpackEventType(QpackEventType::StreamStateUpdated) =>
293                EventImportance::Base,
294            EventType::QpackEventType(QpackEventType::DynamicTableUpdated) =>
295                EventImportance::Extra,
296            EventType::QpackEventType(QpackEventType::HeadersEncoded) =>
297                EventImportance::Base,
298            EventType::QpackEventType(QpackEventType::HeadersDecoded) =>
299                EventImportance::Base,
300            EventType::QpackEventType(QpackEventType::InstructionCreated) =>
301                EventImportance::Base,
302            EventType::QpackEventType(QpackEventType::InstructionParsed) =>
303                EventImportance::Base,
304
305            _ => unimplemented!(),
306        }
307    }
308}
309
310pub trait Eventable {
311    fn importance(&self) -> EventImportance;
312
313    fn set_time(&mut self, time: f32);
314}
315
316#[derive(Serialize, Deserialize, Clone, Debug)]
317#[serde(rename_all = "snake_case")]
318pub enum EventCategory {
319    Connectivity,
320    Security,
321    Transport,
322    Recovery,
323    Http,
324    Qpack,
325
326    Error,
327    Warning,
328    Info,
329    Debug,
330    Verbose,
331    Simulation,
332}
333
334impl std::fmt::Display for EventCategory {
335    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
336        let v = match self {
337            EventCategory::Connectivity => "connectivity",
338            EventCategory::Security => "security",
339            EventCategory::Transport => "transport",
340            EventCategory::Recovery => "recovery",
341            EventCategory::Http => "http",
342            EventCategory::Qpack => "qpack",
343            EventCategory::Error => "error",
344            EventCategory::Warning => "warning",
345            EventCategory::Info => "info",
346            EventCategory::Debug => "debug",
347            EventCategory::Verbose => "verbose",
348            EventCategory::Simulation => "simulation",
349        };
350
351        write!(f, "{v}",)
352    }
353}
354
355impl From<EventType> for EventCategory {
356    fn from(ty: EventType) -> Self {
357        match ty {
358            EventType::ConnectivityEventType(_) => EventCategory::Connectivity,
359            EventType::SecurityEventType(_) => EventCategory::Security,
360            EventType::TransportEventType(_) => EventCategory::Transport,
361            EventType::RecoveryEventType(_) => EventCategory::Recovery,
362            EventType::Http3EventType(_) => EventCategory::Http,
363            EventType::QpackEventType(_) => EventCategory::Qpack,
364
365            _ => unimplemented!(),
366        }
367    }
368}
369
370impl From<&EventData> for EventType {
371    fn from(event_data: &EventData) -> Self {
372        match event_data {
373            EventData::ServerListening { .. } =>
374                EventType::ConnectivityEventType(
375                    ConnectivityEventType::ServerListening,
376                ),
377            EventData::ConnectionStarted { .. } =>
378                EventType::ConnectivityEventType(
379                    ConnectivityEventType::ConnectionStarted,
380                ),
381            EventData::ConnectionClosed { .. } =>
382                EventType::ConnectivityEventType(
383                    ConnectivityEventType::ConnectionClosed,
384                ),
385            EventData::ConnectionIdUpdated { .. } =>
386                EventType::ConnectivityEventType(
387                    ConnectivityEventType::ConnectionIdUpdated,
388                ),
389            EventData::SpinBitUpdated { .. } => EventType::ConnectivityEventType(
390                ConnectivityEventType::SpinBitUpdated,
391            ),
392            EventData::ConnectionStateUpdated { .. } =>
393                EventType::ConnectivityEventType(
394                    ConnectivityEventType::ConnectionStateUpdated,
395                ),
396            EventData::MtuUpdated { .. } => EventType::ConnectivityEventType(
397                ConnectivityEventType::MtuUpdated,
398            ),
399
400            EventData::KeyUpdated { .. } =>
401                EventType::SecurityEventType(SecurityEventType::KeyUpdated),
402            EventData::KeyDiscarded { .. } =>
403                EventType::SecurityEventType(SecurityEventType::KeyDiscarded),
404
405            EventData::VersionInformation { .. } =>
406                EventType::TransportEventType(
407                    TransportEventType::VersionInformation,
408                ),
409            EventData::AlpnInformation { .. } =>
410                EventType::TransportEventType(TransportEventType::AlpnInformation),
411            EventData::TransportParametersSet { .. } =>
412                EventType::TransportEventType(TransportEventType::ParametersSet),
413            EventData::TransportParametersRestored { .. } =>
414                EventType::TransportEventType(
415                    TransportEventType::ParametersRestored,
416                ),
417            EventData::DatagramsReceived { .. } => EventType::TransportEventType(
418                TransportEventType::DatagramsReceived,
419            ),
420            EventData::DatagramsSent { .. } =>
421                EventType::TransportEventType(TransportEventType::DatagramsSent),
422            EventData::DatagramDropped { .. } =>
423                EventType::TransportEventType(TransportEventType::DatagramDropped),
424            EventData::PacketReceived { .. } =>
425                EventType::TransportEventType(TransportEventType::PacketReceived),
426            EventData::PacketSent { .. } =>
427                EventType::TransportEventType(TransportEventType::PacketSent),
428            EventData::PacketDropped { .. } =>
429                EventType::TransportEventType(TransportEventType::PacketDropped),
430            EventData::PacketBuffered { .. } =>
431                EventType::TransportEventType(TransportEventType::PacketBuffered),
432            EventData::PacketsAcked { .. } =>
433                EventType::TransportEventType(TransportEventType::PacketsAcked),
434            EventData::StreamStateUpdated { .. } =>
435                EventType::TransportEventType(
436                    TransportEventType::StreamStateUpdated,
437                ),
438            EventData::FramesProcessed { .. } =>
439                EventType::TransportEventType(TransportEventType::FramesProcessed),
440            EventData::DataMoved { .. } =>
441                EventType::TransportEventType(TransportEventType::DataMoved),
442
443            EventData::RecoveryParametersSet { .. } =>
444                EventType::RecoveryEventType(RecoveryEventType::ParametersSet),
445            EventData::MetricsUpdated { .. } =>
446                EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated),
447            EventData::CongestionStateUpdated { .. } =>
448                EventType::RecoveryEventType(
449                    RecoveryEventType::CongestionStateUpdated,
450                ),
451            EventData::LossTimerUpdated { .. } =>
452                EventType::RecoveryEventType(RecoveryEventType::LossTimerUpdated),
453            EventData::PacketLost { .. } =>
454                EventType::RecoveryEventType(RecoveryEventType::PacketLost),
455            EventData::MarkedForRetransmit { .. } =>
456                EventType::RecoveryEventType(
457                    RecoveryEventType::MarkedForRetransmit,
458                ),
459
460            EventData::H3ParametersSet { .. } =>
461                EventType::Http3EventType(Http3EventType::ParametersSet),
462            EventData::H3ParametersRestored { .. } =>
463                EventType::Http3EventType(Http3EventType::ParametersRestored),
464            EventData::H3StreamTypeSet { .. } =>
465                EventType::Http3EventType(Http3EventType::StreamTypeSet),
466            EventData::H3FrameCreated { .. } =>
467                EventType::Http3EventType(Http3EventType::FrameCreated),
468            EventData::H3FrameParsed { .. } =>
469                EventType::Http3EventType(Http3EventType::FrameParsed),
470            EventData::H3PushResolved { .. } =>
471                EventType::Http3EventType(Http3EventType::PushResolved),
472
473            EventData::QpackStateUpdated { .. } =>
474                EventType::QpackEventType(QpackEventType::StateUpdated),
475            EventData::QpackStreamStateUpdated { .. } =>
476                EventType::QpackEventType(QpackEventType::StreamStateUpdated),
477            EventData::QpackDynamicTableUpdated { .. } =>
478                EventType::QpackEventType(QpackEventType::DynamicTableUpdated),
479            EventData::QpackHeadersEncoded { .. } =>
480                EventType::QpackEventType(QpackEventType::HeadersEncoded),
481            EventData::QpackHeadersDecoded { .. } =>
482                EventType::QpackEventType(QpackEventType::HeadersDecoded),
483            EventData::QpackInstructionCreated { .. } =>
484                EventType::QpackEventType(QpackEventType::InstructionCreated),
485            EventData::QpackInstructionParsed { .. } =>
486                EventType::QpackEventType(QpackEventType::InstructionParsed),
487
488            EventData::ConnectionError { .. } =>
489                EventType::GenericEventType(GenericEventType::ConnectionError),
490            EventData::ApplicationError { .. } =>
491                EventType::GenericEventType(GenericEventType::ApplicationError),
492            EventData::InternalError { .. } =>
493                EventType::GenericEventType(GenericEventType::InternalError),
494            EventData::InternalWarning { .. } =>
495                EventType::GenericEventType(GenericEventType::InternalError),
496            EventData::Message { .. } =>
497                EventType::GenericEventType(GenericEventType::Message),
498            EventData::Marker { .. } =>
499                EventType::GenericEventType(GenericEventType::Marker),
500        }
501    }
502}
503
504#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
505#[serde(rename_all = "snake_case")]
506pub enum DataRecipient {
507    User,
508    Application,
509    Transport,
510    Network,
511    Dropped,
512}
513
514#[serde_with::skip_serializing_none]
515#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
516pub struct RawInfo {
517    pub length: Option<u64>,
518    pub payload_length: Option<u64>,
519
520    pub data: Option<Bytes>,
521}
522
523#[serde_with::skip_serializing_none]
524#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
525#[serde(tag = "name", content = "data")]
526#[allow(clippy::large_enum_variant)]
527pub enum EventData {
528    // Connectivity
529    #[serde(rename = "connectivity:server_listening")]
530    ServerListening(connectivity::ServerListening),
531
532    #[serde(rename = "connectivity:connection_started")]
533    ConnectionStarted(connectivity::ConnectionStarted),
534
535    #[serde(rename = "connectivity:connection_closed")]
536    ConnectionClosed(connectivity::ConnectionClosed),
537
538    #[serde(rename = "connectivity:connection_id_updated")]
539    ConnectionIdUpdated(connectivity::ConnectionIdUpdated),
540
541    #[serde(rename = "connectivity:spin_bit_updated")]
542    SpinBitUpdated(connectivity::SpinBitUpdated),
543
544    #[serde(rename = "connectivity:connection_state_updated")]
545    ConnectionStateUpdated(connectivity::ConnectionStateUpdated),
546
547    #[serde(rename = "connectivity:mtu_updated")]
548    MtuUpdated(connectivity::MtuUpdated),
549
550    // Security
551    #[serde(rename = "security:key_updated")]
552    KeyUpdated(security::KeyUpdated),
553
554    #[serde(rename = "security:key_retired")]
555    KeyDiscarded(security::KeyDiscarded),
556
557    // Transport
558    #[serde(rename = "transport:version_information")]
559    VersionInformation(quic::VersionInformation),
560
561    #[serde(rename = "transport:alpn_information")]
562    AlpnInformation(quic::AlpnInformation),
563
564    #[serde(rename = "transport:parameters_set")]
565    TransportParametersSet(quic::TransportParametersSet),
566
567    #[serde(rename = "transport:parameters_restored")]
568    TransportParametersRestored(quic::TransportParametersRestored),
569
570    #[serde(rename = "transport:datagrams_received")]
571    DatagramsReceived(quic::DatagramsReceived),
572
573    #[serde(rename = "transport:datagrams_sent")]
574    DatagramsSent(quic::DatagramsSent),
575
576    #[serde(rename = "transport:datagram_dropped")]
577    DatagramDropped(quic::DatagramDropped),
578
579    #[serde(rename = "transport:packet_received")]
580    PacketReceived(quic::PacketReceived),
581
582    #[serde(rename = "transport:packet_sent")]
583    PacketSent(quic::PacketSent),
584
585    #[serde(rename = "transport:packet_dropped")]
586    PacketDropped(quic::PacketDropped),
587
588    #[serde(rename = "transport:packet_buffered")]
589    PacketBuffered(quic::PacketBuffered),
590
591    #[serde(rename = "transport:packets_acked")]
592    PacketsAcked(quic::PacketsAcked),
593
594    #[serde(rename = "transport:stream_state_updated")]
595    StreamStateUpdated(quic::StreamStateUpdated),
596
597    #[serde(rename = "transport:frames_processed")]
598    FramesProcessed(quic::FramesProcessed),
599
600    #[serde(rename = "transport:data_moved")]
601    DataMoved(quic::DataMoved),
602
603    // Recovery
604    #[serde(rename = "recovery:parameters_set")]
605    RecoveryParametersSet(quic::RecoveryParametersSet),
606
607    #[serde(rename = "recovery:metrics_updated")]
608    MetricsUpdated(quic::MetricsUpdated),
609
610    #[serde(rename = "recovery:congestion_state_updated")]
611    CongestionStateUpdated(quic::CongestionStateUpdated),
612
613    #[serde(rename = "recovery:loss_timer_updated")]
614    LossTimerUpdated(quic::LossTimerUpdated),
615
616    #[serde(rename = "recovery:packet_lost")]
617    PacketLost(quic::PacketLost),
618
619    #[serde(rename = "recovery:marked_for_retransmit")]
620    MarkedForRetransmit(quic::MarkedForRetransmit),
621
622    // HTTP/3
623    #[serde(rename = "http:parameters_set")]
624    H3ParametersSet(h3::H3ParametersSet),
625
626    #[serde(rename = "http:parameters_restored")]
627    H3ParametersRestored(h3::H3ParametersRestored),
628
629    #[serde(rename = "http:stream_type_set")]
630    H3StreamTypeSet(h3::H3StreamTypeSet),
631
632    #[serde(rename = "http:frame_created")]
633    H3FrameCreated(h3::H3FrameCreated),
634
635    #[serde(rename = "http:frame_parsed")]
636    H3FrameParsed(h3::H3FrameParsed),
637
638    #[serde(rename = "http:push_resolved")]
639    H3PushResolved(h3::H3PushResolved),
640
641    // QPACK
642    #[serde(rename = "qpack:state_updated")]
643    QpackStateUpdated(qpack::QpackStateUpdated),
644
645    #[serde(rename = "qpack:stream_state_updated")]
646    QpackStreamStateUpdated(qpack::QpackStreamStateUpdated),
647
648    #[serde(rename = "qpack:dynamic_table_updated")]
649    QpackDynamicTableUpdated(qpack::QpackDynamicTableUpdated),
650
651    #[serde(rename = "qpack:headers_encoded")]
652    QpackHeadersEncoded(qpack::QpackHeadersEncoded),
653
654    #[serde(rename = "qpack:headers_decoded")]
655    QpackHeadersDecoded(qpack::QpackHeadersDecoded),
656
657    #[serde(rename = "qpack:instruction_created")]
658    QpackInstructionCreated(qpack::QpackInstructionCreated),
659
660    #[serde(rename = "qpack:instruction_parsed")]
661    QpackInstructionParsed(qpack::QpackInstructionParsed),
662
663    // Generic
664    #[serde(rename = "generic:connection_error")]
665    ConnectionError {
666        code: Option<ConnectionErrorCode>,
667        description: Option<String>,
668    },
669
670    #[serde(rename = "generic:application_error")]
671    ApplicationError {
672        code: Option<ApplicationErrorCode>,
673        description: Option<String>,
674    },
675
676    #[serde(rename = "generic:internal_error")]
677    InternalError {
678        code: Option<u64>,
679        description: Option<String>,
680    },
681
682    #[serde(rename = "generic:internal_warning")]
683    InternalWarning {
684        code: Option<u64>,
685        description: Option<String>,
686    },
687
688    #[serde(rename = "generic:message")]
689    Message { message: String },
690
691    #[serde(rename = "generic:marker")]
692    Marker {
693        marker_type: String,
694        message: Option<String>,
695    },
696}
697
698impl EventData {
699    /// Returns size of `EventData` array of `QuicFrame`s if it exists.
700    pub fn contains_quic_frames(&self) -> Option<usize> {
701        // For some EventData variants, the frame array is optional
702        // but for others it is mandatory.
703        match self {
704            EventData::PacketSent(pkt) => pkt.frames.as_ref().map(|f| f.len()),
705
706            EventData::PacketReceived(pkt) =>
707                pkt.frames.as_ref().map(|f| f.len()),
708
709            EventData::PacketLost(pkt) => pkt.frames.as_ref().map(|f| f.len()),
710
711            EventData::MarkedForRetransmit(ev) => Some(ev.frames.len()),
712            EventData::FramesProcessed(ev) => Some(ev.frames.len()),
713
714            _ => None,
715        }
716    }
717}
718
719#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
720#[serde(rename_all = "snake_case")]
721pub enum GenericEventType {
722    ConnectionError,
723    ApplicationError,
724    InternalError,
725    InternalWarning,
726
727    Message,
728    Marker,
729}
730
731#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
732#[serde(untagged)]
733pub enum ConnectionErrorCode {
734    TransportError(TransportError),
735    CryptoError(CryptoError),
736    Value(u64),
737}
738
739#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
740#[serde(untagged)]
741pub enum ApplicationErrorCode {
742    ApplicationError(ApplicationError),
743    Value(u64),
744}
745
746// TODO
747#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
748#[serde(rename_all = "snake_case")]
749pub enum CryptoError {
750    Prefix,
751}
752
753pub mod quic;
754
755pub mod connectivity;
756pub mod h3;
757pub mod qpack;
758pub mod security;