| // Copyright (C) 2020, Cloudflare, Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // |
| // * Redistributions in binary form must reproduce the above copyright |
| // notice, this list of conditions and the following disclaimer in the |
| // documentation and/or other materials provided with the distribution. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| //! Module-defined Event and functions to work with qlog data structures. |
| //! |
| //! The Qlog data structures are very flexible, which makes working with them |
| //! liable to simple semantic errors. This module provides some helper functions |
| //! that focus on creating valid types, while also reducing some of the |
| //! verbosity of using the raw data structures. |
| |
| use super::*; |
| |
| /// A representation of qlog events that couple EventCategory, EventType and |
| /// EventData. |
| /// |
| /// Functions are provided to help construct valid events. Most events consist |
| /// of several optional fields, so minimal versions of these functions are |
| /// provided, which accept only mandatory qlog parameters. Minimal functions are |
| /// identified by a `_min` suffix. |
| #[derive(Clone)] |
| pub struct Event { |
| pub category: EventCategory, |
| pub ty: EventType, |
| pub data: EventData, |
| } |
| |
| #[allow(clippy::too_many_arguments)] |
| impl Event { |
| // Connectivity events. |
| |
| /// Returns: |
| /// * `EventCategory`=`Connectivity` |
| /// * `EventType`=`ConnectivityEventType::ServerListening` |
| /// * `EventData`=`ServerListening`. |
| pub fn server_listening( |
| ip_v4: Option<String>, ip_v6: Option<String>, port_v4: u64, port_v6: u64, |
| quic_versions: Option<Vec<String>>, alpn_values: Option<Vec<String>>, |
| stateless_reset_required: Option<bool>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::ConnectivityEventType( |
| ConnectivityEventType::ServerListening, |
| ), |
| data: EventData::ServerListening { |
| ip_v4, |
| ip_v6, |
| port_v4, |
| port_v6, |
| quic_versions, |
| alpn_values, |
| stateless_reset_required, |
| }, |
| } |
| } |
| |
| pub fn server_listening_min(port_v4: u64, port_v6: u64) -> Self { |
| Event::server_listening(None, None, port_v4, port_v6, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Connectivity` |
| /// * `EventType`=`ConnectivityEventType::ConnectionStarted` |
| /// * `EventData`=`ConnectionStarted`. |
| pub fn connection_started( |
| ip_version: String, src_ip: String, dst_ip: String, |
| protocol: Option<String>, src_port: u64, dst_port: u64, |
| quic_version: Option<String>, src_cid: Option<String>, |
| dst_cid: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::ConnectivityEventType( |
| ConnectivityEventType::ConnectionStarted, |
| ), |
| data: EventData::ConnectionStarted { |
| ip_version, |
| src_ip, |
| dst_ip, |
| protocol, |
| src_port, |
| dst_port, |
| quic_version, |
| src_cid, |
| dst_cid, |
| }, |
| } |
| } |
| |
| pub fn connection_started_min( |
| ip_version: String, src_ip: String, dst_ip: String, src_port: u64, |
| dst_port: u64, |
| ) -> Self { |
| Event::connection_started( |
| ip_version, src_ip, dst_ip, None, src_port, dst_port, None, None, |
| None, |
| ) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Connectivity` |
| /// * `EventType`=`ConnectivityEventType::ConnectionIdUpdated` |
| /// * `EventData`=`ConnectionIdUpdated`. |
| pub fn connection_id_updated( |
| src_old: Option<String>, src_new: Option<String>, |
| dst_old: Option<String>, dst_new: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::ConnectivityEventType( |
| ConnectivityEventType::ConnectionIdUpdated, |
| ), |
| data: EventData::ConnectionIdUpdated { |
| src_old, |
| src_new, |
| dst_old, |
| dst_new, |
| }, |
| } |
| } |
| |
| pub fn connection_id_updated_min() -> Self { |
| Event::connection_id_updated(None, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Connectivity` |
| /// * `EventType`=`ConnectivityEventType::SpinBitUpdated` |
| /// * `EventData`=`SpinBitUpdated`. |
| pub fn spinbit_updated(state: bool) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::ConnectivityEventType( |
| ConnectivityEventType::SpinBitUpdated, |
| ), |
| data: EventData::SpinBitUpdated { state }, |
| } |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Connectivity` |
| /// * `EventType`=`ConnectivityEventType::ConnectionState` |
| /// * `EventData`=`ConnectionState`. |
| pub fn connection_state_updated( |
| old: Option<ConnectionState>, new: ConnectionState, |
| ) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::ConnectivityEventType( |
| ConnectivityEventType::ConnectionStateUpdated, |
| ), |
| data: EventData::ConnectionStateUpdated { old, new }, |
| } |
| } |
| |
| pub fn connection_state_updated_min(new: ConnectionState) -> Self { |
| Event::connection_state_updated(None, new) |
| } |
| |
| // Transport events. |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::ParametersSet` |
| /// * `EventData`=`ParametersSet`. |
| pub fn transport_parameters_set( |
| owner: Option<TransportOwner>, resumption_allowed: Option<bool>, |
| early_data_enabled: Option<bool>, alpn: Option<String>, |
| version: Option<String>, tls_cipher: Option<String>, |
| original_connection_id: Option<String>, |
| stateless_reset_token: Option<String>, |
| disable_active_migration: Option<bool>, idle_timeout: Option<u64>, |
| max_packet_size: Option<u64>, ack_delay_exponent: Option<u64>, |
| max_ack_delay: Option<u64>, active_connection_id_limit: Option<u64>, |
| initial_max_data: Option<String>, |
| initial_max_stream_data_bidi_local: Option<String>, |
| initial_max_stream_data_bidi_remote: Option<String>, |
| initial_max_stream_data_uni: Option<String>, |
| initial_max_streams_bidi: Option<String>, |
| initial_max_streams_uni: Option<String>, |
| preferred_address: Option<PreferredAddress>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::ParametersSet), |
| data: EventData::TransportParametersSet { |
| owner, |
| |
| resumption_allowed, |
| early_data_enabled, |
| alpn, |
| version, |
| tls_cipher, |
| |
| original_connection_id, |
| stateless_reset_token, |
| disable_active_migration, |
| |
| idle_timeout, |
| max_packet_size, |
| ack_delay_exponent, |
| max_ack_delay, |
| active_connection_id_limit, |
| |
| initial_max_data, |
| initial_max_stream_data_bidi_local, |
| initial_max_stream_data_bidi_remote, |
| initial_max_stream_data_uni, |
| initial_max_streams_bidi, |
| initial_max_streams_uni, |
| |
| preferred_address, |
| }, |
| } |
| } |
| |
| pub fn transport_parameters_set_min() -> Self { |
| Event::transport_parameters_set( |
| None, None, None, None, None, None, None, None, None, None, None, |
| None, None, None, None, None, None, None, None, None, None, |
| ) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::DatagramsReceived` |
| /// * `EventData`=`DatagramsReceived`. |
| pub fn datagrams_received( |
| count: Option<u64>, byte_length: Option<u64>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType( |
| TransportEventType::DatagramsReceived, |
| ), |
| data: EventData::DatagramsReceived { count, byte_length }, |
| } |
| } |
| |
| pub fn datagrams_received_min() -> Self { |
| Event::datagrams_received(None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::DatagramsSent` |
| /// * `EventData`=`DatagramsSent`. |
| pub fn datagrams_sent(count: Option<u64>, byte_length: Option<u64>) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::DatagramsSent), |
| data: EventData::DatagramsSent { count, byte_length }, |
| } |
| } |
| |
| pub fn datagrams_sent_min() -> Self { |
| Event::datagrams_sent(None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::DatagramDropped` |
| /// * `EventData`=`DatagramDropped`. |
| pub fn datagram_dropped(byte_length: Option<u64>) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType( |
| TransportEventType::DatagramDropped, |
| ), |
| data: EventData::DatagramDropped { byte_length }, |
| } |
| } |
| |
| pub fn datagram_dropped_min() -> Self { |
| Event::datagram_dropped(None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::PacketReceived` |
| /// * `EventData`=`PacketReceived`. |
| pub fn packet_received( |
| packet_type: PacketType, header: PacketHeader, |
| frames: Option<Vec<QuicFrame>>, is_coalesced: Option<bool>, |
| raw_encrypted: Option<String>, raw_decrypted: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::PacketReceived), |
| data: EventData::PacketReceived { |
| packet_type, |
| header, |
| frames, |
| |
| is_coalesced, |
| |
| raw_encrypted, |
| raw_decrypted, |
| }, |
| } |
| } |
| |
| pub fn packet_received_min( |
| packet_type: PacketType, header: PacketHeader, |
| ) -> Self { |
| Event::packet_received(packet_type, header, None, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::PacketSent` |
| /// * `EventData`=`PacketSent`. |
| pub fn packet_sent( |
| packet_type: PacketType, header: PacketHeader, |
| frames: Option<Vec<QuicFrame>>, is_coalesced: Option<bool>, |
| raw_encrypted: Option<String>, raw_decrypted: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::PacketSent), |
| data: EventData::PacketSent { |
| packet_type, |
| header, |
| frames, |
| |
| is_coalesced, |
| |
| raw_encrypted, |
| raw_decrypted, |
| }, |
| } |
| } |
| |
| pub fn packet_sent_min( |
| packet_type: PacketType, header: PacketHeader, |
| frames: Option<Vec<QuicFrame>>, |
| ) -> Self { |
| Event::packet_sent(packet_type, header, frames, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::PacketDropped` |
| /// * `EventData`=`PacketDropped`. |
| pub fn packet_dropped( |
| packet_type: Option<PacketType>, packet_size: Option<u64>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::PacketDropped), |
| data: EventData::PacketDropped { |
| packet_type, |
| packet_size, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn packet_dropped_min() -> Self { |
| Event::packet_dropped(None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::PacketBuffered` |
| /// * `EventData`=`PacketBuffered`. |
| pub fn packet_buffered( |
| packet_type: PacketType, packet_number: String, |
| ) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType(TransportEventType::PacketBuffered), |
| data: EventData::PacketBuffered { |
| packet_type, |
| packet_number, |
| }, |
| } |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::StreamStateUpdated` |
| /// * `EventData`=`StreamStateUpdated`. |
| pub fn stream_state_updated( |
| stream_id: String, stream_type: Option<StreamType>, |
| old: Option<StreamState>, new: StreamState, |
| stream_side: Option<StreamSide>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Connectivity, |
| ty: EventType::TransportEventType( |
| TransportEventType::StreamStateUpdated, |
| ), |
| data: EventData::StreamStateUpdated { |
| stream_id, |
| stream_type, |
| old, |
| new, |
| stream_side, |
| }, |
| } |
| } |
| |
| pub fn stream_state_updated_min(stream_id: String, new: StreamState) -> Self { |
| Event::stream_state_updated(stream_id, None, None, new, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Transport` |
| /// * `EventType`=`TransportEventType::FramesProcessed` |
| /// * `EventData`=`FramesProcessed`. |
| pub fn frames_processed(frames: Vec<QuicFrame>) -> Self { |
| Event { |
| category: EventCategory::Transport, |
| ty: EventType::TransportEventType( |
| TransportEventType::FramesProcessed, |
| ), |
| data: EventData::FramesProcessed { frames }, |
| } |
| } |
| |
| // Recovery events. |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::ParametersSet` |
| /// * `EventData`=`RecoveryParametersSet`. |
| pub fn recovery_parameters_set( |
| reordering_threshold: Option<u64>, time_threshold: Option<u64>, |
| timer_granularity: Option<u64>, initial_rtt: Option<u64>, |
| max_datagram_size: Option<u64>, initial_congestion_window: Option<u64>, |
| minimum_congestion_window: Option<u64>, |
| loss_reduction_factor: Option<u64>, |
| persistent_congestion_threshold: Option<u64>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType(RecoveryEventType::ParametersSet), |
| data: EventData::RecoveryParametersSet { |
| reordering_threshold, |
| time_threshold, |
| timer_granularity, |
| initial_rtt, |
| max_datagram_size, |
| initial_congestion_window, |
| minimum_congestion_window, |
| loss_reduction_factor, |
| persistent_congestion_threshold, |
| }, |
| } |
| } |
| |
| pub fn recovery_parameters_set_min() -> Self { |
| Event::recovery_parameters_set( |
| None, None, None, None, None, None, None, None, None, |
| ) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::MetricsUpdated` |
| /// * `EventData`=`MetricsUpdated`. |
| pub fn metrics_updated( |
| min_rtt: Option<u64>, smoothed_rtt: Option<u64>, latest_rtt: Option<u64>, |
| rtt_variance: Option<u64>, max_ack_delay: Option<u64>, |
| pto_count: Option<u64>, congestion_window: Option<u64>, |
| bytes_in_flight: Option<u64>, ssthresh: Option<u64>, |
| packets_in_flight: Option<u64>, in_recovery: Option<bool>, |
| pacing_rate: Option<u64>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated), |
| data: EventData::MetricsUpdated { |
| min_rtt, |
| smoothed_rtt, |
| latest_rtt, |
| rtt_variance, |
| max_ack_delay, |
| pto_count, |
| congestion_window, |
| bytes_in_flight, |
| ssthresh, |
| packets_in_flight, |
| in_recovery, |
| pacing_rate, |
| }, |
| } |
| } |
| |
| pub fn metrics_updated_min() -> Self { |
| Event::metrics_updated( |
| None, None, None, None, None, None, None, None, None, None, None, |
| None, |
| ) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::CongestionStateUpdated` |
| /// * `EventData`=`CongestionStateUpdated`. |
| pub fn congestion_state_updated(old: Option<String>, new: String) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType( |
| RecoveryEventType::CongestionStateUpdated, |
| ), |
| data: EventData::CongestionStateUpdated { old, new }, |
| } |
| } |
| |
| pub fn congestion_state_updated_min(new: String) -> Self { |
| Event::congestion_state_updated(None, new) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::LossTimerSet` |
| /// * `EventData`=`LossTimerSet`. |
| pub fn loss_timer_set( |
| timer_type: Option<TimerType>, timeout: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType(RecoveryEventType::LossTimerSet), |
| data: EventData::LossTimerSet { |
| timer_type, |
| timeout, |
| }, |
| } |
| } |
| |
| pub fn loss_timer_set_min() -> Self { |
| Event::loss_timer_set(None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::PacketLost` |
| /// * `EventData`=`PacketLost`. |
| pub fn packet_lost( |
| packet_type: PacketType, packet_number: String, |
| header: Option<PacketHeader>, frames: Vec<QuicFrame>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType(RecoveryEventType::PacketLost), |
| data: EventData::PacketLost { |
| packet_type, |
| packet_number, |
| header, |
| frames, |
| }, |
| } |
| } |
| |
| pub fn packet_lost_min( |
| packet_type: PacketType, packet_number: String, frames: Vec<QuicFrame>, |
| ) -> Self { |
| Event::packet_lost(packet_type, packet_number, None, frames) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Recovery` |
| /// * `EventType`=`RecoveryEventType::MarkedForRetransmit` |
| /// * `EventData`=`MarkedForRetransmit`. |
| pub fn marked_for_retransmit(frames: Vec<QuicFrame>) -> Self { |
| Event { |
| category: EventCategory::Recovery, |
| ty: EventType::RecoveryEventType( |
| RecoveryEventType::MarkedForRetransmit, |
| ), |
| data: EventData::MarkedForRetransmit { frames }, |
| } |
| } |
| |
| // HTTP/3 events. |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::ParametersSet` |
| /// * `EventData`=`H3ParametersSet`. |
| pub fn h3_parameters_set( |
| owner: Option<H3Owner>, max_header_list_size: Option<u64>, |
| max_table_capacity: Option<u64>, blocked_streams_count: Option<u64>, |
| push_allowed: Option<bool>, waits_for_settings: Option<bool>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::ParametersSet), |
| data: EventData::H3ParametersSet { |
| owner, |
| max_header_list_size, |
| max_table_capacity, |
| blocked_streams_count, |
| push_allowed, |
| waits_for_settings, |
| }, |
| } |
| } |
| |
| pub fn h3_parameters_set_min() -> Self { |
| Event::h3_parameters_set(None, None, None, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::StreamTypeSet` |
| /// * `EventData`=`H3StreamTypeSet`. |
| pub fn h3_stream_type_set( |
| stream_id: String, owner: Option<H3Owner>, old: Option<H3StreamType>, |
| new: H3StreamType, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::StreamTypeSet), |
| data: EventData::H3StreamTypeSet { |
| stream_id, |
| owner, |
| old, |
| new, |
| }, |
| } |
| } |
| |
| pub fn h3_stream_type_set_min(stream_id: String, new: H3StreamType) -> Self { |
| Event::h3_stream_type_set(stream_id, None, None, new) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::FrameCreated` |
| /// * `EventData`=`H3FrameCreated`. |
| pub fn h3_frame_created( |
| stream_id: String, frame: Http3Frame, byte_length: Option<String>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::FrameCreated), |
| data: EventData::H3FrameCreated { |
| stream_id, |
| frame, |
| byte_length, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn h3_frame_created_min(stream_id: String, frame: Http3Frame) -> Self { |
| Event::h3_frame_created(stream_id, frame, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::FrameParsed` |
| /// * `EventData`=`H3FrameParsed`. |
| pub fn h3_frame_parsed( |
| stream_id: String, frame: Http3Frame, byte_length: Option<String>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::FrameParsed), |
| data: EventData::H3FrameParsed { |
| stream_id, |
| frame, |
| byte_length, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn h3_frame_parsed_min(stream_id: String, frame: Http3Frame) -> Self { |
| Event::h3_frame_parsed(stream_id, frame, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::DataMoved` |
| /// * `EventData`=`H3DataMoved`. |
| pub fn h3_data_moved( |
| stream_id: String, offset: Option<String>, length: Option<u64>, |
| from: Option<H3DataRecipient>, to: Option<H3DataRecipient>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::DataMoved), |
| data: EventData::H3DataMoved { |
| stream_id, |
| offset, |
| length, |
| from, |
| to, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn h3_data_moved_min(stream_id: String) -> Self { |
| Event::h3_data_moved(stream_id, None, None, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Http` |
| /// * `EventType`=`Http3EventType::PushResolved` |
| /// * `EventData`=`H3PushResolved`. |
| pub fn h3_push_resolved( |
| push_id: Option<String>, stream_id: Option<String>, |
| decision: Option<H3PushDecision>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Http, |
| ty: EventType::Http3EventType(Http3EventType::PushResolved), |
| data: EventData::H3PushResolved { |
| push_id, |
| stream_id, |
| decision, |
| }, |
| } |
| } |
| |
| pub fn h3_push_resolved_min() -> Self { |
| Event::h3_push_resolved(None, None, None) |
| } |
| |
| // QPACK events. |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::StateUpdated` |
| /// * `EventData`=`QpackStateUpdated`. |
| pub fn qpack_state_updated( |
| owner: Option<QpackOwner>, dynamic_table_capacity: Option<u64>, |
| dynamic_table_size: Option<u64>, known_received_count: Option<u64>, |
| current_insert_count: Option<u64>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::StateUpdated), |
| data: EventData::QpackStateUpdated { |
| owner, |
| dynamic_table_capacity, |
| dynamic_table_size, |
| known_received_count, |
| current_insert_count, |
| }, |
| } |
| } |
| |
| pub fn qpack_state_updated_min() -> Self { |
| Event::qpack_state_updated(None, None, None, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::StreamStateUpdated` |
| /// * `EventData`=`QpackStreamStateUpdated`. |
| pub fn qpack_stream_state_updated( |
| stream_id: String, state: QpackStreamState, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::StreamStateUpdated), |
| data: EventData::QpackStreamStateUpdated { stream_id, state }, |
| } |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::DynamicTableUpdated` |
| /// * `EventData`=`QpackDynamicTableUpdated`. |
| pub fn qpack_dynamic_table_updated( |
| update_type: QpackUpdateType, entries: Vec<QpackDynamicTableEntry>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::DynamicTableUpdated), |
| data: EventData::QpackDynamicTableUpdated { |
| update_type, |
| entries, |
| }, |
| } |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::HeadersEncoded` |
| /// * `EventData`=`QpackHeadersEncoded`. |
| pub fn qpack_headers_encoded( |
| stream_id: Option<String>, headers: Option<HttpHeader>, |
| block_prefix: QpackHeaderBlockPrefix, |
| header_block: Vec<QpackHeaderBlockRepresentation>, raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::HeadersEncoded), |
| data: EventData::QpackHeadersEncoded { |
| stream_id, |
| headers, |
| block_prefix, |
| header_block, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn qpack_headers_encoded_min( |
| block_prefix: QpackHeaderBlockPrefix, |
| header_block: Vec<QpackHeaderBlockRepresentation>, |
| ) -> Self { |
| Event::qpack_headers_encoded(None, None, block_prefix, header_block, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::HeadersDecoded` |
| /// * `EventData`=`QpackHeadersDecoded`. |
| pub fn qpack_headers_decoded( |
| stream_id: Option<String>, headers: Option<HttpHeader>, |
| block_prefix: QpackHeaderBlockPrefix, |
| header_block: Vec<QpackHeaderBlockRepresentation>, raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::HeadersDecoded), |
| data: EventData::QpackHeadersDecoded { |
| stream_id, |
| headers, |
| block_prefix, |
| header_block, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn qpack_headers_decoded_min( |
| block_prefix: QpackHeaderBlockPrefix, |
| header_block: Vec<QpackHeaderBlockRepresentation>, |
| ) -> Self { |
| Event::qpack_headers_decoded(None, None, block_prefix, header_block, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::InstructionSent` |
| /// * `EventData`=`QpackInstructionSent`. |
| pub fn qpack_instruction_sent( |
| instruction: QPackInstruction, byte_length: Option<String>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::InstructionSent), |
| data: EventData::QpackInstructionSent { |
| instruction, |
| byte_length, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn qpack_instruction_sent_min(instruction: QPackInstruction) -> Self { |
| Event::qpack_instruction_sent(instruction, None, None) |
| } |
| |
| /// Returns: |
| /// * `EventCategory`=`Qpack` |
| /// * `EventType`=`QpackEventType::InstructionReceived` |
| /// * `EventData`=`QpackInstructionReceived`. |
| pub fn qpack_instruction_received( |
| instruction: QPackInstruction, byte_length: Option<String>, |
| raw: Option<String>, |
| ) -> Self { |
| Event { |
| category: EventCategory::Qpack, |
| ty: EventType::QpackEventType(QpackEventType::InstructionReceived), |
| data: EventData::QpackInstructionReceived { |
| instruction, |
| byte_length, |
| raw, |
| }, |
| } |
| } |
| |
| pub fn qpack_instruction_received_min(instruction: QPackInstruction) -> Self { |
| Event::qpack_instruction_received(instruction, None, None) |
| } |
| |
| /// Checks if the the combination of `EventCategory`, `EventType` and |
| /// `EventData` is valid. |
| pub fn is_valid(&self) -> bool { |
| match (&self.category, &self.ty) { |
| ( |
| EventCategory::Connectivity, |
| EventType::ConnectivityEventType(_), |
| ) => matches!(&self.data, |
| EventData::ServerListening { .. } | |
| EventData::ConnectionStarted { .. } | |
| EventData::ConnectionIdUpdated { .. } | |
| EventData::SpinBitUpdated { .. } | |
| EventData::ConnectionStateUpdated { .. }), |
| |
| (EventCategory::Transport, EventType::TransportEventType(_)) => |
| matches!(&self.data, |
| EventData::TransportParametersSet { .. } | |
| EventData::DatagramsReceived { .. } | |
| EventData::DatagramsSent { .. } | |
| EventData::DatagramDropped { .. } | |
| EventData::PacketReceived { .. } | |
| EventData::PacketSent { .. } | |
| EventData::PacketDropped { .. } | |
| EventData::PacketBuffered { .. } | |
| EventData::StreamStateUpdated { .. } | |
| EventData::FramesProcessed { .. }), |
| |
| (EventCategory::Security, EventType::SecurityEventType(_)) => |
| matches!(&self.data, |
| EventData::KeyUpdated { .. } | |
| EventData::KeyRetired { .. }), |
| |
| (EventCategory::Recovery, EventType::RecoveryEventType(_)) => |
| matches!(&self.data, |
| EventData::RecoveryParametersSet { .. } | |
| EventData::MetricsUpdated { .. } | |
| EventData::CongestionStateUpdated { .. } | |
| EventData::LossTimerSet { .. } | |
| EventData::PacketLost { .. } | |
| EventData::MarkedForRetransmit { .. }), |
| |
| (EventCategory::Http, EventType::Http3EventType(_)) => |
| matches!(&self.data, |
| EventData::H3ParametersSet { .. } | |
| EventData::H3StreamTypeSet { .. } | |
| EventData::H3FrameCreated { .. } | |
| EventData::H3FrameParsed { .. } | |
| EventData::H3DataMoved { .. } | |
| EventData::H3PushResolved { .. }), |
| |
| (EventCategory::Qpack, EventType::QpackEventType(_)) => |
| matches!(&self.data, |
| EventData::QpackStateUpdated { .. } | |
| EventData::QpackStreamStateUpdated { .. } | |
| EventData::QpackDynamicTableUpdated { .. } | |
| EventData::QpackHeadersEncoded { .. } | |
| EventData::QpackHeadersDecoded { .. } | |
| EventData::QpackInstructionSent { .. } | |
| EventData::QpackInstructionReceived { .. }), |
| |
| // TODO: in qlog-01 there is no sane default category defined for |
| // GenericEventType |
| (_, EventType::GenericEventType(_)) => matches!(&self.data, |
| EventData::ConnectionError { .. } | |
| EventData::ApplicationError { .. } | |
| EventData::InternalError { .. } | |
| EventData::InternalWarning { .. } | |
| EventData::Message { .. } | |
| EventData::Marker { .. }), |
| |
| _ => false, |
| } |
| } |
| } |