Skip to main content

qlog/events/
http3.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::Deserialize;
28use serde::Serialize;
29
30use crate::events::RawInfo;
31
32#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
33#[serde(rename_all = "snake_case")]
34pub enum Initiator {
35    Local,
36    Remote,
37}
38
39#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
40#[serde(rename_all = "snake_case")]
41pub enum StreamType {
42    Request,
43    Control,
44    Push,
45    Reserved,
46    #[default]
47    Unknown,
48    QpackEncode,
49    QpackDecode,
50}
51
52#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
53#[serde(rename_all = "snake_case")]
54pub enum PushDecision {
55    Claimed,
56    Abandoned,
57}
58
59#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
60#[serde(rename_all = "snake_case")]
61pub enum Http3EventType {
62    ParametersSet,
63    ParametersRestored,
64    StreamTypeSet,
65    PriorityUpdated,
66    FrameCreated,
67    FrameParsed,
68    DatagramCreated,
69    DatagramParsed,
70    PushResolved,
71}
72
73#[serde_with::skip_serializing_none]
74#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
75pub struct HttpHeader {
76    pub name: Option<String>,
77    pub name_bytes: Option<String>,
78    pub value: Option<String>,
79    pub value_bytes: Option<String>,
80}
81
82#[serde_with::skip_serializing_none]
83#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
84pub struct Setting {
85    pub name: Option<String>,
86    pub name_bytes: Option<u64>,
87    pub value: u64,
88}
89
90#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
91#[serde(rename_all = "snake_case")]
92pub enum Http3FrameTypeName {
93    Data,
94    Headers,
95    CancelPush,
96    Settings,
97    PushPromise,
98    Goaway,
99    MaxPushId,
100    DuplicatePush,
101    Reserved,
102    Unknown,
103}
104
105#[serde_with::skip_serializing_none]
106#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
107#[serde(tag = "frame_type")]
108#[serde(rename_all = "snake_case")]
109// Strictly, the qlog spec says that all these frame types have a frame_type
110// field. But instead of making that a rust object property, just use serde to
111// ensure it goes out on the wire. This means that deserialization of frames
112// also works automatically.
113pub enum Http3Frame {
114    Data {
115        raw: Option<RawInfo>,
116    },
117
118    Headers {
119        headers: Vec<HttpHeader>,
120        raw: Option<RawInfo>,
121    },
122
123    CancelPush {
124        push_id: u64,
125        raw: Option<RawInfo>,
126    },
127
128    Settings {
129        settings: Vec<Setting>,
130        raw: Option<RawInfo>,
131    },
132
133    PushPromise {
134        push_id: u64,
135        headers: Vec<HttpHeader>,
136        raw: Option<RawInfo>,
137    },
138
139    Goaway {
140        id: u64,
141        raw: Option<RawInfo>,
142    },
143
144    MaxPushId {
145        push_id: u64,
146        raw: Option<RawInfo>,
147    },
148
149    PriorityUpdate {
150        stream_id: Option<u64>,
151        push_id: Option<u64>,
152        priority_field_value: String,
153        raw: Option<RawInfo>,
154    },
155
156    Reserved {
157        frame_type_bytes: u64,
158        raw: Option<RawInfo>,
159    },
160
161    Unknown {
162        frame_type_bytes: u64,
163        raw: Option<RawInfo>,
164    },
165}
166
167impl Default for Http3Frame {
168    fn default() -> Self {
169        Self::Unknown {
170            frame_type_bytes: 0,
171            raw: None,
172        }
173    }
174}
175
176#[serde_with::skip_serializing_none]
177#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
178pub struct ParametersSet {
179    pub initiator: Option<Initiator>,
180
181    #[serde(alias = "max_header_list_size")]
182    pub max_field_section_size: Option<u64>,
183    pub max_table_capacity: Option<u64>,
184    pub blocked_streams_count: Option<u64>,
185    pub extended_connect: Option<u16>,
186    pub h3_datagram: Option<u16>,
187
188    // qlog-defined
189    pub waits_for_settings: Option<bool>,
190}
191
192#[serde_with::skip_serializing_none]
193#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
194pub struct ParametersRestored {
195    #[serde(alias = "max_header_list_size")]
196    pub max_field_section_size: Option<u64>,
197    pub max_table_capacity: Option<u64>,
198    pub blocked_streams_count: Option<u64>,
199    pub extended_connect: Option<u16>,
200    pub h3_datagram: Option<u16>,
201}
202
203#[serde_with::skip_serializing_none]
204#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
205pub struct StreamTypeSet {
206    pub initiator: Option<Initiator>,
207    pub stream_id: u64,
208    pub stream_type: StreamType,
209    pub stream_type_bytes: Option<u64>,
210    pub associated_push_id: Option<u64>,
211}
212
213#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
214#[serde(rename_all = "snake_case")]
215pub enum PriorityUpdatedTrigger {
216    ClientSignalReceived,
217    Local,
218    Other,
219}
220
221#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
222#[serde(rename_all = "snake_case")]
223pub enum PriorityUpdatedReason {
224    ClientSignalOnly,
225    ClientServerMerged,
226    LocalPolicy,
227    Other,
228}
229
230#[serde_with::skip_serializing_none]
231#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
232pub struct PriorityUpdated {
233    pub stream_id: Option<u64>,
234    pub push_id: Option<u64>,
235    pub old: Option<String>,
236    pub new: String,
237    pub trigger: Option<PriorityUpdatedTrigger>,
238    pub reason: Option<PriorityUpdatedReason>,
239}
240
241#[serde_with::skip_serializing_none]
242#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
243pub struct FrameCreated {
244    pub stream_id: u64,
245    pub length: Option<u64>,
246    pub frame: Http3Frame,
247
248    pub raw: Option<RawInfo>,
249}
250
251#[serde_with::skip_serializing_none]
252#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
253pub struct FrameParsed {
254    pub stream_id: u64,
255    pub length: Option<u64>,
256    pub frame: Http3Frame,
257
258    pub raw: Option<RawInfo>,
259}
260
261#[serde_with::skip_serializing_none]
262#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
263pub struct DatagramCreated {
264    pub quarter_stream_id: u64,
265    pub datagram: Option<Vec<String>>,
266    pub raw: Option<RawInfo>,
267}
268
269#[serde_with::skip_serializing_none]
270#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
271pub struct DatagramParsed {
272    pub quarter_stream_id: u64,
273    pub datagram: Option<Vec<String>>,
274    pub raw: Option<RawInfo>,
275}
276
277#[serde_with::skip_serializing_none]
278#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
279pub struct PushResolved {
280    pub push_id: Option<u64>,
281    pub stream_id: Option<u64>,
282
283    pub decision: PushDecision,
284}