1use serde::Deserialize;
28use serde::Serialize;
29
30use super::EventHeader;
31
32#[derive(Debug)]
33pub enum Event {
34 QuicSession(QuicSessionEvent),
35 QuicSessionTransportParametersSent(QuicSessionTransportParametersSentEvent),
36 QuicSessionTransportParametersReceived(
37 QuicSessionTransportParametersReceivedEvent,
38 ),
39 QuicSessionUnauthenticatedPacketHeaderReceived(
40 QuicSessionUnauthenticatedPacketHeaderReceived,
41 ),
42 QuicSessionPacketSent(QuicSessionPacketSent),
43 QuicSessionAckFrameSent(QuicSessionAckFrameSent),
44 QuicSessionAckFrameReceived(QuicSessionAckFrameReceived),
45 QuicSessionStreamFrameReceived(QuicSessionStreamFrameReceivedEvent),
46 QuicSessionStopSendingFrameSent(QuicSessionStopSendingFrameSentEvent),
47 QuicSessionRstStreamFrameSent(QuicSessionRstStreamFrameSentEvent),
48 QuicSessionRstStreamFrameReceived(QuicSessionRstStreamFrameReceivedEvent),
49 QuicSessionBlockedFrameReceived(QuicSessionBlockedFrameReceivedEvent),
50 QuicSessionWindowUpdateFrameSent(QuicSessionWindowUpdateFrameSentEvent),
51 QuicSessionClosed(QuicSessionClosedEvent),
52}
53
54#[derive(Serialize, Deserialize, Debug, Default)]
55pub struct QuicSessionParams {
56 pub cert_verify_flags: u64,
57 pub connection_id: String,
58 pub host: String,
59 pub port: u16,
60 #[serde(alias = "network_anonymization_key")]
61 pub network_isolation_key: String,
62 pub privacy_mode: String,
63}
64
65#[derive(Serialize, Deserialize, Debug, Default)]
66pub struct QuicSessionEvent {
67 pub params: QuicSessionParams,
68}
69
70#[derive(Serialize, Deserialize, Debug, Default)]
71pub struct QuicSessionTransportParametersSentParams {
72 pub quic_transport_parameters: String,
73}
74
75#[derive(Serialize, Deserialize, Debug, Default)]
76pub struct QuicSessionTransportParametersSentEvent {
77 pub params: QuicSessionTransportParametersSentParams,
78}
79
80#[derive(Serialize, Deserialize, Debug, Default)]
81pub struct QuicSessionTransportParametersReceivedParams {
82 pub quic_transport_parameters: String,
83}
84
85#[derive(Serialize, Deserialize, Debug, Default)]
86pub struct QuicSessionTransportParametersReceivedEvent {
87 pub params: QuicSessionTransportParametersReceivedParams,
88}
89
90#[derive(Debug, Default)]
93pub struct TransportParameters {
94 pub versions: String,
95 pub max_idle_timeout: Option<u64>,
96 pub max_udp_payload_size: Option<u64>,
97 pub initial_max_data: Option<u64>,
98 pub initial_max_stream_data_bidi_local: Option<u64>,
99 pub initial_max_stream_data_bidi_remote: Option<u64>,
100 pub initial_max_stream_data_uni: Option<u64>,
101 pub initial_max_streams_bidi: Option<u64>,
102 pub initial_max_streams_uni: Option<u64>,
103 pub initial_source_connection_id: Option<String>,
104 pub max_datagram_frame_size: Option<u64>,
105}
106
107impl From<String> for TransportParameters {
108 fn from(value: String) -> Self {
116 if value.len() < 3 {
117 return Default::default();
119 }
120
121 let mut tp = TransportParameters::default();
122
123 let inner = &value[1..value.len() - 1];
126 let last_version_pos = inner.rfind(']').unwrap_or_default();
127 tp.versions = inner[0..last_version_pos + 1].to_string();
128 let rest = &inner[last_version_pos + 2..inner.len()];
129
130 let mut split = rest.split(' ').peekable();
131
132 while let Some(item) = split.next() {
133 if split.peek().is_none() {
134 break;
135 }
136
137 match item {
138 "max_idle_timeout" =>
139 tp.max_idle_timeout = split
140 .peek()
141 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
142 "max_udp_payload_size" =>
143 tp.max_udp_payload_size = split
144 .peek()
145 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
146 "initial_max_data" =>
147 tp.initial_max_data = split
148 .peek()
149 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
150 "initial_max_stream_data_bidi_local" =>
151 tp.initial_max_stream_data_bidi_local = split
152 .peek()
153 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
154 "initial_max_stream_data_bidi_remote" =>
155 tp.initial_max_stream_data_bidi_remote = split
156 .peek()
157 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
158 "initial_max_stream_data_uni" =>
159 tp.initial_max_stream_data_uni = split
160 .peek()
161 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
162 "initial_max_streams_bidi" =>
163 tp.initial_max_streams_bidi = split
164 .peek()
165 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
166 "initial_max_streams_uni" =>
167 tp.initial_max_streams_uni = split
168 .peek()
169 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
170 "initial_source_connection_id" =>
171 tp.initial_source_connection_id =
172 split.peek().map(|v| (*v).to_string()),
173 "max_datagram_frame_size" =>
174 tp.max_datagram_frame_size = split
175 .peek()
176 .map(|v| (*v).parse::<u64>().unwrap_or_default()),
177 _ => (),
178 }
179 }
180
181 tp
182 }
183}
184
185impl From<QuicSessionTransportParametersReceivedParams> for TransportParameters {
186 fn from(value: QuicSessionTransportParametersReceivedParams) -> Self {
187 value.quic_transport_parameters.into()
188 }
189}
190
191impl From<QuicSessionTransportParametersSentParams> for TransportParameters {
192 fn from(value: QuicSessionTransportParametersSentParams) -> Self {
193 value.quic_transport_parameters.into()
194 }
195}
196
197#[derive(Serialize, Deserialize, Debug, Default)]
198pub struct QuicSessionUnauthenticatedPacketHeaderReceivedParams {
199 pub connection_id: String,
200 pub header_format: String,
201 pub long_header_type: Option<String>,
202 pub packet_number: u64,
203}
204
205#[derive(Serialize, Deserialize, Debug, Default)]
206pub struct QuicSessionUnauthenticatedPacketHeaderReceived {
207 pub params: QuicSessionUnauthenticatedPacketHeaderReceivedParams,
208}
209
210#[derive(Serialize, Deserialize, Debug, Default)]
211pub struct QuicSessionPacketSentParams {
212 pub encryption_level: String,
213 pub packet_number: u64,
214 pub sent_time_us: u64,
215 transmission_type: String,
216}
217
218#[derive(Serialize, Deserialize, Debug, Default)]
219pub struct QuicSessionPacketSent {
220 pub params: QuicSessionPacketSentParams,
221}
222
223#[derive(Serialize, Deserialize, Debug, Default)]
224pub struct QuicSessionAckFrameSentParams {
225 pub delta_time_largest_observed_us: u64,
226 pub largest_observed: u64,
227 pub missing_packets: Vec<u64>,
228 pub received_packet_times: Vec<u64>,
229 pub smallest_observed: u64,
230}
231
232#[derive(Serialize, Deserialize, Debug, Default)]
233pub struct QuicSessionAckFrameSent {
234 pub params: QuicSessionAckFrameSentParams,
235}
236
237#[derive(Serialize, Deserialize, Debug, Default)]
238pub struct QuicSessionAckFrameReceivedParams {
239 pub delta_time_largest_observed_us: u64,
240 pub largest_observed: u64,
241 pub missing_packets: Vec<u64>,
242 pub received_packet_times: Vec<u64>,
243 pub smallest_observed: u64,
244}
245
246#[derive(Serialize, Deserialize, Debug, Default)]
247pub struct QuicSessionAckFrameReceived {
248 pub params: QuicSessionAckFrameReceivedParams,
249}
250
251#[derive(Serialize, Deserialize, Debug, Default)]
252pub struct QuicSessionStreamFrameReceivedParams {
253 pub stream_id: u64,
254 pub fin: bool,
255 pub offset: u64,
256 pub length: u64,
257}
258
259#[derive(Serialize, Deserialize, Debug, Default)]
260pub struct QuicSessionStreamFrameReceivedEvent {
261 pub params: QuicSessionStreamFrameReceivedParams,
262}
263
264#[derive(Serialize, Deserialize, Debug, Default)]
265pub struct QuicSessionStopSendingFrameSentParams {
266 pub stream_id: u64,
267 pub quic_rst_stream_error: u64,
268}
269
270#[derive(Serialize, Deserialize, Debug, Default)]
271pub struct QuicSessionStopSendingFrameSentEvent {
272 pub params: QuicSessionStopSendingFrameSentParams,
273}
274
275#[derive(Serialize, Deserialize, Debug, Default)]
276pub struct QuicSessionRstStreamFrameSentParams {
277 pub stream_id: u64,
278 pub quic_rst_stream_error: u64,
279 pub offset: u64,
280}
281
282#[derive(Serialize, Deserialize, Debug, Default)]
283pub struct QuicSessionRstStreamFrameSentEvent {
284 pub params: QuicSessionRstStreamFrameSentParams,
285}
286
287#[derive(Serialize, Deserialize, Debug, Default)]
288pub struct QuicSessionRstStreamFrameReceivedParams {
289 pub stream_id: u64,
290 pub quic_rst_stream_error: u64,
291 pub offset: u64,
292}
293
294#[derive(Serialize, Deserialize, Debug, Default)]
295pub struct QuicSessionRstStreamFrameReceivedEvent {
296 pub params: QuicSessionRstStreamFrameReceivedParams,
297}
298
299#[derive(Serialize, Deserialize, Debug, Default)]
300pub struct QuicSessionBlockedFrameReceivedParams {
301 pub stream_id: i64,
302}
303
304#[derive(Serialize, Deserialize, Debug, Default)]
305pub struct QuicSessionBlockedFrameReceivedEvent {
306 pub params: QuicSessionBlockedFrameReceivedParams,
307}
308
309#[derive(Serialize, Deserialize, Debug, Default)]
310pub struct QuicSessionWindowUpdateFrameSentParams {
311 pub byte_offset: u64,
312 pub stream_id: i64,
313}
314
315#[derive(Serialize, Deserialize, Debug, Default)]
316pub struct QuicSessionWindowUpdateFrameSentEvent {
317 pub params: QuicSessionWindowUpdateFrameSentParams,
318}
319
320#[derive(Serialize, Deserialize, Debug, Default)]
321pub struct QuicSessionClosedParams {
322 pub details: String,
323 pub from_peer: bool,
324 pub quic_error: i64,
325}
326
327#[derive(Serialize, Deserialize, Debug, Default)]
328pub struct QuicSessionClosedEvent {
329 pub params: QuicSessionClosedParams,
330}
331
332pub fn parse_event(
334 event_hdr: &EventHeader, event: &[u8],
335) -> Option<super::Event> {
336 match event_hdr.ty_string.as_str() {
337 "QUIC_SESSION" =>
338 if event_hdr.phase_string == "PHASE_BEGIN" {
339 let ev: QuicSessionEvent = serde_json::from_slice(event).unwrap();
340 return Some(super::Event::Quic(Event::QuicSession(ev)));
341 },
342
343 "QUIC_SESSION_TRANSPORT_PARAMETERS_SENT" => {
344 let ev: QuicSessionTransportParametersSentEvent =
345 serde_json::from_slice(event).unwrap();
346 return Some(super::Event::Quic(
347 Event::QuicSessionTransportParametersSent(ev),
348 ));
349 },
350
351 "QUIC_SESSION_TRANSPORT_PARAMETERS_RECEIVED" => {
352 let ev: QuicSessionTransportParametersReceivedEvent =
353 serde_json::from_slice(event).unwrap();
354 return Some(super::Event::Quic(
355 Event::QuicSessionTransportParametersReceived(ev),
356 ));
357 },
358
359 "QUIC_SESSION_STREAM_FRAME_RECEIVED" => {
360 let ev: QuicSessionStreamFrameReceivedEvent =
361 serde_json::from_slice(event).unwrap();
362 return Some(super::Event::Quic(
363 Event::QuicSessionStreamFrameReceived(ev),
364 ));
365 },
366
367 "QUIC_SESSION_STOP_SENDING_FRAME_SENT" => {
368 let ev: QuicSessionStopSendingFrameSentEvent =
369 serde_json::from_slice(event).unwrap();
370 return Some(super::Event::Quic(
371 Event::QuicSessionStopSendingFrameSent(ev),
372 ));
373 },
374
375 "QUIC_SESSION_STOP_SENDING_FRAME_RECEIVED" => {
376 },
378
379 "QUIC_SESSION_RST_STREAM_FRAME_SENT" => {
380 let ev: QuicSessionRstStreamFrameSentEvent =
381 serde_json::from_slice(event).unwrap();
382 return Some(super::Event::Quic(
383 Event::QuicSessionRstStreamFrameSent(ev),
384 ));
385 },
386
387 "QUIC_SESSION_RST_STREAM_FRAME_RECEIVED" => {
388 let ev: QuicSessionRstStreamFrameReceivedEvent =
389 serde_json::from_slice(event).unwrap();
390 return Some(super::Event::Quic(
391 Event::QuicSessionRstStreamFrameReceived(ev),
392 ));
393 },
394
395 "QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED" => {
396 let ev: QuicSessionUnauthenticatedPacketHeaderReceived =
397 serde_json::from_slice(event).unwrap();
398
399 return Some(super::Event::Quic(
400 Event::QuicSessionUnauthenticatedPacketHeaderReceived(ev),
401 ));
402 },
403
404 "QUIC_SESSION_PACKET_SENT" => {
405 let ev: QuicSessionPacketSent =
406 serde_json::from_slice(event).unwrap();
407
408 return Some(super::Event::Quic(Event::QuicSessionPacketSent(ev)));
409 },
410
411 "QUIC_SESSION_PACKET_RETRANSMITTED" => {
412 },
414
415 "QUIC_SESSION_ACK_FRAME_SENT" => {
416 let ev: QuicSessionAckFrameSent =
417 serde_json::from_slice(event).unwrap();
418
419 return Some(super::Event::Quic(Event::QuicSessionAckFrameSent(ev)));
420 },
421
422 "QUIC_SESSION_ACK_FRAME_RECEIVED" => {
423 let ev: QuicSessionAckFrameReceived =
424 serde_json::from_slice(event).unwrap();
425
426 return Some(super::Event::Quic(Event::QuicSessionAckFrameReceived(
427 ev,
428 )));
429 },
430
431 "QUIC_SESSION_PACKET_LOST" => {
432 },
434
435 "QUIC_SESSION_CLOSED" => {
436 let ev: QuicSessionClosedEvent =
437 serde_json::from_slice(event).unwrap();
438
439 return Some(super::Event::Quic(Event::QuicSessionClosed(ev)));
440 },
441
442 "QUIC_SESSION_BLOCKED_FRAME_RECEIVED" => {
443 let ev: QuicSessionBlockedFrameReceivedEvent =
444 serde_json::from_slice(event).unwrap();
445 return Some(super::Event::Quic(
446 Event::QuicSessionBlockedFrameReceived(ev),
447 ));
448 },
449
450 "QUIC_SESSION_STREAMS_BLOCKED_FRAME_RECEIVED" => {
451 },
453
454 "QUIC_SESSION_WINDOW_UPDATE_FRAME_SENT" => {
455 let ev: QuicSessionWindowUpdateFrameSentEvent =
456 serde_json::from_slice(event).unwrap();
457 return Some(super::Event::Quic(
458 Event::QuicSessionWindowUpdateFrameSent(ev),
459 ));
460 },
461
462 "QUIC_ACCEPT_CH_FRAME_RECEIVED" |
464 "QUIC_CHROMIUM_CLIENT_STREAM_READ_EARLY_HINTS_RESPONSE_HEADERS" |
465 "QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS" |
466 "QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS" |
467 "QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS" |
468 "QUIC_CONNECTION_MIGRATION_FAILURE" |
469 "QUIC_CONNECTION_MIGRATION_FAILURE_AFTER_PROBING" |
470 "QUIC_CONNECTION_MIGRATION_ON_MIGRATE_BACK" |
471 "QUIC_CONNECTION_MIGRATION_ON_NETWORK_CONNECTED" |
472 "QUIC_CONNECTION_MIGRATION_ON_NETWORK_DISCONNECTED" |
473 "QUIC_CONNECTION_MIGRATION_ON_NETWORK_MADE_DEFAULT" |
474 "QUIC_CONNECTION_MIGRATION_ON_PATH_DEGRADING" |
475 "QUIC_CONNECTION_MIGRATION_ON_WRITE_ERROR" |
476 "QUIC_CONNECTION_MIGRATION_PLATFORM_NOTIFICATION" |
477 "QUIC_CONNECTION_MIGRATION_SUCCESS" |
478 "QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING" |
479 "QUIC_CONNECTION_MIGRATION_TRIGGERED" |
480 "QUIC_CONNECTIVITY_PROBING_MANAGER_CANCEL_PROBING" |
481 "QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_RECEIVED" |
482 "QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_SENT" |
483 "QUIC_CONNECTIVITY_PROBING_MANAGER_START_PROBING" |
484 "QUIC_CONNECTIVITY_PROBING_MANAGER_STATELESS_RESET_RECEIVED" |
485 "QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM" |
486 "QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS" |
487 "QUIC_PORT_MIGRATION_FAILURE" |
488 "QUIC_PORT_MIGRATION_SUCCESS" |
489 "QUIC_PORT_MIGRATION_TRIGGERED" |
490 "QUIC_READ_ERROR" |
491 "QUIC_SESSION_ATTEMPTING_TO_PROCESS_UNDECRYPTABLE_PACKET" |
492 "QUIC_SESSION_BLOCKED_FRAME_SENT" |
493 "QUIC_SESSION_BUFFERED_UNDECRYPTABLE_PACKET" |
494 "QUIC_SESSION_CLIENT_GOAWAY_ON_PATH_DEGRADING" |
495 "QUIC_SESSION_CLOSE_ON_ERROR" |
496 "QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED" |
497 "QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT" |
498 "QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED" |
499 "QUIC_SESSION_DROPPED_UNDECRYPTABLE_PACKET" |
500 "QUIC_SESSION_DUPLICATE_PACKET_RECEIVED" |
501 "QUIC_SESSION_GOAWAY_FRAME_RECEIVED" |
502 "QUIC_SESSION_GOAWAY_FRAME_SENT" |
503 "QUIC_SESSION_KEY_UPDATE" |
504 "QUIC_SESSION_MAX_STREAMS_FRAME_RECEIVED" |
505 "QUIC_SESSION_MAX_STREAMS_FRAME_SENT" |
506 "QUIC_SESSION_MESSAGE_FRAME_RECEIVED" |
507 "QUIC_SESSION_MESSAGE_FRAME_SENT" |
508 "QUIC_SESSION_MTU_DISCOVERY_FRAME_SENT" |
509 "QUIC_SESSION_NEW_CONNECTION_ID_FRAME_RECEIVED" |
510 "QUIC_SESSION_NEW_CONNECTION_ID_FRAME_SENT" |
511 "QUIC_SESSION_NEW_TOKEN_FRAME_RECEIVED" |
512 "QUIC_SESSION_NEW_TOKEN_FRAME_SENT" |
513 "QUIC_SESSION_PATH_CHALLENGE_FRAME_RECEIVED" |
514 "QUIC_SESSION_PATH_CHALLENGE_FRAME_SENT" |
515 "QUIC_SESSION_PATH_RESPONSE_FRAME_RECEIVED" |
516 "QUIC_SESSION_PATH_RESPONSE_FRAME_SENT" |
517 "QUIC_SESSION_PING_FRAME_RECEIVED" |
518 "QUIC_SESSION_PING_FRAME_SENT" |
519 "QUIC_SESSION_PUBLIC_RESET_PACKET_RECEIVED" |
520 "QUIC_SESSION_PUSH_PROMISE_RECEIVED" |
521 "QUIC_SESSION_RETIRE_CONNECTION_ID_FRAME_RECEIVED" |
522 "QUIC_SESSION_RETIRE_CONNECTION_ID_FRAME_SENT" |
523 "QUIC_SESSION_STOP_WAITING_FRAME_RECEIVED" |
524 "QUIC_SESSION_STOP_WAITING_FRAME_SENT" |
525 "QUIC_SESSION_TRANSPORT_PARAMETERS_RESUMED" |
526 "QUIC_SESSION_WEBTRANSPORT_CLIENT_ALIVE" |
527 "QUIC_SESSION_WEBTRANSPORT_CLIENT_STATE_CHANGED" |
528 "QUIC_SESSION_WINDOW_UPDATE_FRAME_RECEIVED" |
529 "QUIC_SESSION_ZERO_RTT_REJECTED" |
530 "QUIC_SESSION_CERTIFICATE_VERIFIED" |
531 "QUIC_SESSION_CERTIFICATE_VERIFY_FAILED" |
532 "QUIC_SESSION_COALESCED_PACKET_SENT" |
533 "QUIC_SESSION_CRYPTO_FRAME_RECEIVED" |
534 "QUIC_SESSION_CRYPTO_FRAME_SENT" |
535 "QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_RECEIVED" |
536 "QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT" |
537 "QUIC_SESSION_HANDSHAKE_DONE_FRAME_RECEIVED" |
538 "QUIC_SESSION_PACKET_HEADER_REVIVED" |
539 "QUIC_SESSION_PADDING_FRAME_RECEIVED" |
540 "QUIC_SESSION_PADDING_FRAME_SENT" |
541 "QUIC_SESSION_STREAMS_BLOCKED_FRAME_SENT" |
542 "QUIC_SESSION_STREAM_FRAME_COALESCED" |
543 "QUIC_SESSION_STREAM_FRAME_SENT" |
544 "QUIC_SESSION_VERSION_NEGOTIATED" |
545 "QUIC_SESSION_VERSION_NEGOTIATION_PACKET_RECEIVED" => (),
546
547 "QUIC_SESSION_PACKET_RECEIVED" |
549 "QUIC_CONNECTION_MIGRATION_MODE" |
550 "QUIC_STREAM_FACTORY_JOB" |
551 "QUIC_STREAM_FACTORY_JOB_BOUND_TO_HTTP_STREAM_JOB" |
552 "QUIC_STREAM_FACTORY_JOB_CONNECT" |
553 "QUIC_STREAM_FACTORY_JOB_RETRY_ON_ALTERNATE_NETWORK" |
554 "QUIC_STREAM_FACTORY_JOB_STALE_HOST_NOT_USED_ON_CONNECTION" |
555 "QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_MATCHED" |
556 "QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_NO_MATCH" |
557 "QUIC_STREAM_FACTORY_JOB_STALE_HOST_TRIED_ON_CONNECTION" => (),
558
559 "QUIC_SESSION_PACKET_AUTHENTICATED" => (),
561
562 _ => log::trace!("skipping unknown QUIC type....{}", event_hdr.ty_string),
565 }
566
567 None
568}