diff --git a/dc/s2n-quic-dc/events/map.rs b/dc/s2n-quic-dc/events/map.rs index 162218c8e..674225163 100644 --- a/dc/s2n-quic-dc/events/map.rs +++ b/dc/s2n-quic-dc/events/map.rs @@ -31,6 +31,7 @@ struct PathSecretMapBackgroundHandshakeRequested<'a> { struct PathSecretMapEntryInserted<'a> { peer_address: SocketAddress<'a>, + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -40,6 +41,7 @@ struct PathSecretMapEntryInserted<'a> { struct PathSecretMapEntryReady<'a> { peer_address: SocketAddress<'a>, + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -49,8 +51,10 @@ struct PathSecretMapEntryReady<'a> { struct PathSecretMapEntryReplaced<'a> { peer_address: SocketAddress<'a>, + #[snapshot("[HIDDEN]")] new_credential_id: &'a [u8], + #[snapshot("[HIDDEN]")] previous_credential_id: &'a [u8], } @@ -59,6 +63,8 @@ struct PathSecretMapEntryReplaced<'a> { /// Emitted when an UnknownPathSecret packet was sent struct UnknownPathSecretPacketSent<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -67,6 +73,8 @@ struct UnknownPathSecretPacketSent<'a> { /// Emitted when an UnknownPathSecret packet was received struct UnknownPathSecretPacketReceived<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -75,6 +83,8 @@ struct UnknownPathSecretPacketReceived<'a> { /// Emitted when an UnknownPathSecret packet was authentic and processed struct UnknownPathSecretPacketAccepted<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -83,6 +93,8 @@ struct UnknownPathSecretPacketAccepted<'a> { /// Emitted when an UnknownPathSecret packet was rejected as invalid struct UnknownPathSecretPacketRejected<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -91,6 +103,8 @@ struct UnknownPathSecretPacketRejected<'a> { /// Emitted when an UnknownPathSecret packet was dropped due to a missing entry struct UnknownPathSecretPacketDropped<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -98,7 +112,9 @@ struct UnknownPathSecretPacketDropped<'a> { #[subject(endpoint)] /// Emitted when credential replay was definitely detected struct ReplayDefinitelyDetected<'a> { + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], + key_id: u64, } @@ -107,8 +123,11 @@ struct ReplayDefinitelyDetected<'a> { /// Emitted when credential replay was potentially detected, but could not be verified /// due to a limiting tracking window struct ReplayPotentiallyDetected<'a> { + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], + key_id: u64, + gap: u64, } @@ -117,6 +136,8 @@ struct ReplayPotentiallyDetected<'a> { /// Emitted when an ReplayDetected packet was sent struct ReplayDetectedPacketSent<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -125,6 +146,8 @@ struct ReplayDetectedPacketSent<'a> { /// Emitted when an ReplayDetected packet was received struct ReplayDetectedPacketReceived<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -133,7 +156,10 @@ struct ReplayDetectedPacketReceived<'a> { /// Emitted when an StaleKey packet was authentic and processed struct ReplayDetectedPacketAccepted<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], + key_id: u64, } @@ -142,6 +168,8 @@ struct ReplayDetectedPacketAccepted<'a> { /// Emitted when an ReplayDetected packet was rejected as invalid struct ReplayDetectedPacketRejected<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -150,6 +178,8 @@ struct ReplayDetectedPacketRejected<'a> { /// Emitted when an ReplayDetected packet was dropped due to a missing entry struct ReplayDetectedPacketDropped<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -158,6 +188,8 @@ struct ReplayDetectedPacketDropped<'a> { /// Emitted when an StaleKey packet was sent struct StaleKeyPacketSent<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -166,6 +198,8 @@ struct StaleKeyPacketSent<'a> { /// Emitted when an StaleKey packet was received struct StaleKeyPacketReceived<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -174,6 +208,8 @@ struct StaleKeyPacketReceived<'a> { /// Emitted when an StaleKey packet was authentic and processed struct StaleKeyPacketAccepted<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -182,6 +218,8 @@ struct StaleKeyPacketAccepted<'a> { /// Emitted when an StaleKey packet was rejected as invalid struct StaleKeyPacketRejected<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } @@ -190,5 +228,7 @@ struct StaleKeyPacketRejected<'a> { /// Emitted when an StaleKey packet was dropped due to a missing entry struct StaleKeyPacketDropped<'a> { peer_address: SocketAddress<'a>, + + #[snapshot("[HIDDEN]")] credential_id: &'a [u8], } diff --git a/dc/s2n-quic-dc/src/event/generated.rs b/dc/s2n-quic-dc/src/event/generated.rs index 7656279a8..e821d89d0 100644 --- a/dc/s2n-quic-dc/src/event/generated.rs +++ b/dc/s2n-quic-dc/src/event/generated.rs @@ -16,12 +16,34 @@ pub mod api { pub struct ConnectionMeta { pub id: u64, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionMeta { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionMeta"); + fmt.field("id", &self.id); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct EndpointMeta {} + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointMeta { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointMeta"); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct ConnectionInfo {} + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionInfo { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionInfo"); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct ApplicationWrite { @@ -30,6 +52,15 @@ pub mod api { #[doc = " The amount that was written"] pub write_len: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ApplicationWrite { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ApplicationWrite"); + fmt.field("total_len", &self.total_len); + fmt.field("write_len", &self.write_len); + fmt.finish() + } + } impl Event for ApplicationWrite { const NAME: &'static str = "application:write"; } @@ -41,6 +72,15 @@ pub mod api { #[doc = " The amount that was read"] pub read_len: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ApplicationRead { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ApplicationRead"); + fmt.field("capacity", &self.capacity); + fmt.field("read_len", &self.read_len); + fmt.finish() + } + } impl Event for ApplicationRead { const NAME: &'static str = "application:read"; } @@ -52,6 +92,17 @@ pub mod api { pub tcp: bool, pub udp: bool, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for EndpointInitialized<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointInitialized"); + fmt.field("acceptor_addr", &self.acceptor_addr); + fmt.field("handshake_addr", &self.handshake_addr); + fmt.field("tcp", &self.tcp); + fmt.field("udp", &self.udp); + fmt.finish() + } + } impl<'a> Event for EndpointInitialized<'a> { const NAME: &'static str = "endpoint:initialized"; } @@ -61,6 +112,14 @@ pub mod api { #[doc = " The capacity of the path secret map"] pub capacity: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PathSecretMapInitialized { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapInitialized"); + fmt.field("capacity", &self.capacity); + fmt.finish() + } + } impl Event for PathSecretMapInitialized { const NAME: &'static str = "path_secret_map:initialized"; } @@ -72,6 +131,15 @@ pub mod api { #[doc = " The number of entries in the map"] pub entries: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PathSecretMapUninitialized { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapUninitialized"); + fmt.field("capacity", &self.capacity); + fmt.field("entries", &self.entries); + fmt.finish() + } + } impl Event for PathSecretMapUninitialized { const NAME: &'static str = "path_secret_map:uninitialized"; } @@ -81,6 +149,14 @@ pub mod api { pub struct PathSecretMapBackgroundHandshakeRequested<'a> { pub peer_address: SocketAddress<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathSecretMapBackgroundHandshakeRequested<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapBackgroundHandshakeRequested"); + fmt.field("peer_address", &self.peer_address); + fmt.finish() + } + } impl<'a> Event for PathSecretMapBackgroundHandshakeRequested<'a> { const NAME: &'static str = "path_secret_map:background_handshake_requested"; } @@ -91,6 +167,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathSecretMapEntryInserted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapEntryInserted"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for PathSecretMapEntryInserted<'a> { const NAME: &'static str = "path_secret_map:entry_replaced"; } @@ -101,6 +186,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathSecretMapEntryReady<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapEntryReady"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for PathSecretMapEntryReady<'a> { const NAME: &'static str = "path_secret_map:entry_replaced"; } @@ -112,6 +206,16 @@ pub mod api { pub new_credential_id: &'a [u8], pub previous_credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathSecretMapEntryReplaced<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathSecretMapEntryReplaced"); + fmt.field("peer_address", &self.peer_address); + fmt.field("new_credential_id", &"[HIDDEN]"); + fmt.field("previous_credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for PathSecretMapEntryReplaced<'a> { const NAME: &'static str = "path_secret_map:entry_replaced"; } @@ -122,6 +226,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for UnknownPathSecretPacketSent<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("UnknownPathSecretPacketSent"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for UnknownPathSecretPacketSent<'a> { const NAME: &'static str = "path_secret_map:unknown_path_secret_packet_sent"; } @@ -132,6 +245,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for UnknownPathSecretPacketReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("UnknownPathSecretPacketReceived"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for UnknownPathSecretPacketReceived<'a> { const NAME: &'static str = "path_secret_map:unknown_path_secret_packet_received"; } @@ -142,6 +264,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for UnknownPathSecretPacketAccepted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("UnknownPathSecretPacketAccepted"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for UnknownPathSecretPacketAccepted<'a> { const NAME: &'static str = "path_secret_map:unknown_path_secret_packet_accepted"; } @@ -152,6 +283,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for UnknownPathSecretPacketRejected<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("UnknownPathSecretPacketRejected"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for UnknownPathSecretPacketRejected<'a> { const NAME: &'static str = "path_secret_map:unknown_path_secret_packet_rejected"; } @@ -162,6 +302,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for UnknownPathSecretPacketDropped<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("UnknownPathSecretPacketDropped"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for UnknownPathSecretPacketDropped<'a> { const NAME: &'static str = "path_secret_map:unknown_path_secret_packet_dropped"; } @@ -172,6 +321,15 @@ pub mod api { pub credential_id: &'a [u8], pub key_id: u64, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDefinitelyDetected<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDefinitelyDetected"); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.field("key_id", &self.key_id); + fmt.finish() + } + } impl<'a> Event for ReplayDefinitelyDetected<'a> { const NAME: &'static str = "path_secret_map:replay_definitely_detected"; } @@ -184,6 +342,16 @@ pub mod api { pub key_id: u64, pub gap: u64, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayPotentiallyDetected<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayPotentiallyDetected"); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.field("key_id", &self.key_id); + fmt.field("gap", &self.gap); + fmt.finish() + } + } impl<'a> Event for ReplayPotentiallyDetected<'a> { const NAME: &'static str = "path_secret_map:replay_potentially_detected"; } @@ -194,6 +362,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDetectedPacketSent<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDetectedPacketSent"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for ReplayDetectedPacketSent<'a> { const NAME: &'static str = "path_secret_map:replay_detected_packet_sent"; } @@ -204,6 +381,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDetectedPacketReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDetectedPacketReceived"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for ReplayDetectedPacketReceived<'a> { const NAME: &'static str = "path_secret_map:replay_detected_packet_received"; } @@ -215,6 +401,16 @@ pub mod api { pub credential_id: &'a [u8], pub key_id: u64, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDetectedPacketAccepted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDetectedPacketAccepted"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.field("key_id", &self.key_id); + fmt.finish() + } + } impl<'a> Event for ReplayDetectedPacketAccepted<'a> { const NAME: &'static str = "path_secret_map:replay_detected_packet_accepted"; } @@ -225,6 +421,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDetectedPacketRejected<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDetectedPacketRejected"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for ReplayDetectedPacketRejected<'a> { const NAME: &'static str = "path_secret_map:replay_detected_packet_rejected"; } @@ -235,6 +440,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ReplayDetectedPacketDropped<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ReplayDetectedPacketDropped"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for ReplayDetectedPacketDropped<'a> { const NAME: &'static str = "path_secret_map:replay_detected_packet_dropped"; } @@ -245,6 +459,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for StaleKeyPacketSent<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("StaleKeyPacketSent"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for StaleKeyPacketSent<'a> { const NAME: &'static str = "path_secret_map:stale_key_packet_sent"; } @@ -255,6 +478,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for StaleKeyPacketReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("StaleKeyPacketReceived"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for StaleKeyPacketReceived<'a> { const NAME: &'static str = "path_secret_map:stale_key_packet_received"; } @@ -265,6 +497,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for StaleKeyPacketAccepted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("StaleKeyPacketAccepted"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for StaleKeyPacketAccepted<'a> { const NAME: &'static str = "path_secret_map:stale_key_packet_accepted"; } @@ -275,6 +516,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for StaleKeyPacketRejected<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("StaleKeyPacketRejected"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for StaleKeyPacketRejected<'a> { const NAME: &'static str = "path_secret_map:stale_key_packet_rejected"; } @@ -285,6 +535,15 @@ pub mod api { pub peer_address: SocketAddress<'a>, pub credential_id: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for StaleKeyPacketDropped<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("StaleKeyPacketDropped"); + fmt.field("peer_address", &self.peer_address); + fmt.field("credential_id", &"[HIDDEN]"); + fmt.finish() + } + } impl<'a> Event for StaleKeyPacketDropped<'a> { const NAME: &'static str = "path_secret_map:stale_key_packet_dropped"; } @@ -1540,6 +1799,249 @@ mod traits { query.execute(context) } } + impl Subscriber for std::sync::Arc { + type ConnectionContext = T::ConnectionContext; + #[inline] + fn create_connection_context( + &self, + meta: &api::ConnectionMeta, + info: &api::ConnectionInfo, + ) -> Self::ConnectionContext { + self.as_ref().create_connection_context(meta, info) + } + #[inline] + fn on_application_write( + &self, + context: &Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &api::ApplicationWrite, + ) { + self.as_ref().on_application_write(context, meta, event); + } + #[inline] + fn on_application_read( + &self, + context: &Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &api::ApplicationRead, + ) { + self.as_ref().on_application_read(context, meta, event); + } + #[inline] + fn on_endpoint_initialized( + &self, + meta: &api::EndpointMeta, + event: &api::EndpointInitialized, + ) { + self.as_ref().on_endpoint_initialized(meta, event); + } + #[inline] + fn on_path_secret_map_initialized( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapInitialized, + ) { + self.as_ref().on_path_secret_map_initialized(meta, event); + } + #[inline] + fn on_path_secret_map_uninitialized( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapUninitialized, + ) { + self.as_ref().on_path_secret_map_uninitialized(meta, event); + } + #[inline] + fn on_path_secret_map_background_handshake_requested( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapBackgroundHandshakeRequested, + ) { + self.as_ref() + .on_path_secret_map_background_handshake_requested(meta, event); + } + #[inline] + fn on_path_secret_map_entry_inserted( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapEntryInserted, + ) { + self.as_ref().on_path_secret_map_entry_inserted(meta, event); + } + #[inline] + fn on_path_secret_map_entry_ready( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapEntryReady, + ) { + self.as_ref().on_path_secret_map_entry_ready(meta, event); + } + #[inline] + fn on_path_secret_map_entry_replaced( + &self, + meta: &api::EndpointMeta, + event: &api::PathSecretMapEntryReplaced, + ) { + self.as_ref().on_path_secret_map_entry_replaced(meta, event); + } + #[inline] + fn on_unknown_path_secret_packet_sent( + &self, + meta: &api::EndpointMeta, + event: &api::UnknownPathSecretPacketSent, + ) { + self.as_ref() + .on_unknown_path_secret_packet_sent(meta, event); + } + #[inline] + fn on_unknown_path_secret_packet_received( + &self, + meta: &api::EndpointMeta, + event: &api::UnknownPathSecretPacketReceived, + ) { + self.as_ref() + .on_unknown_path_secret_packet_received(meta, event); + } + #[inline] + fn on_unknown_path_secret_packet_accepted( + &self, + meta: &api::EndpointMeta, + event: &api::UnknownPathSecretPacketAccepted, + ) { + self.as_ref() + .on_unknown_path_secret_packet_accepted(meta, event); + } + #[inline] + fn on_unknown_path_secret_packet_rejected( + &self, + meta: &api::EndpointMeta, + event: &api::UnknownPathSecretPacketRejected, + ) { + self.as_ref() + .on_unknown_path_secret_packet_rejected(meta, event); + } + #[inline] + fn on_unknown_path_secret_packet_dropped( + &self, + meta: &api::EndpointMeta, + event: &api::UnknownPathSecretPacketDropped, + ) { + self.as_ref() + .on_unknown_path_secret_packet_dropped(meta, event); + } + #[inline] + fn on_replay_definitely_detected( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDefinitelyDetected, + ) { + self.as_ref().on_replay_definitely_detected(meta, event); + } + #[inline] + fn on_replay_potentially_detected( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayPotentiallyDetected, + ) { + self.as_ref().on_replay_potentially_detected(meta, event); + } + #[inline] + fn on_replay_detected_packet_sent( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDetectedPacketSent, + ) { + self.as_ref().on_replay_detected_packet_sent(meta, event); + } + #[inline] + fn on_replay_detected_packet_received( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDetectedPacketReceived, + ) { + self.as_ref() + .on_replay_detected_packet_received(meta, event); + } + #[inline] + fn on_replay_detected_packet_accepted( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDetectedPacketAccepted, + ) { + self.as_ref() + .on_replay_detected_packet_accepted(meta, event); + } + #[inline] + fn on_replay_detected_packet_rejected( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDetectedPacketRejected, + ) { + self.as_ref() + .on_replay_detected_packet_rejected(meta, event); + } + #[inline] + fn on_replay_detected_packet_dropped( + &self, + meta: &api::EndpointMeta, + event: &api::ReplayDetectedPacketDropped, + ) { + self.as_ref().on_replay_detected_packet_dropped(meta, event); + } + #[inline] + fn on_stale_key_packet_sent( + &self, + meta: &api::EndpointMeta, + event: &api::StaleKeyPacketSent, + ) { + self.as_ref().on_stale_key_packet_sent(meta, event); + } + #[inline] + fn on_stale_key_packet_received( + &self, + meta: &api::EndpointMeta, + event: &api::StaleKeyPacketReceived, + ) { + self.as_ref().on_stale_key_packet_received(meta, event); + } + #[inline] + fn on_stale_key_packet_accepted( + &self, + meta: &api::EndpointMeta, + event: &api::StaleKeyPacketAccepted, + ) { + self.as_ref().on_stale_key_packet_accepted(meta, event); + } + #[inline] + fn on_stale_key_packet_rejected( + &self, + meta: &api::EndpointMeta, + event: &api::StaleKeyPacketRejected, + ) { + self.as_ref().on_stale_key_packet_rejected(meta, event); + } + #[inline] + fn on_stale_key_packet_dropped( + &self, + meta: &api::EndpointMeta, + event: &api::StaleKeyPacketDropped, + ) { + self.as_ref().on_stale_key_packet_dropped(meta, event); + } + #[inline] + fn on_event(&self, meta: &M, event: &E) { + self.as_ref().on_event(meta, event); + } + #[inline] + fn on_connection_event( + &self, + context: &Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &E, + ) { + self.as_ref().on_connection_event(context, meta, event); + } + } #[doc = r" Subscriber is implemented for a 2-element tuple to make it easy to compose multiple"] #[doc = r" subscribers."] impl Subscriber for (A, B) @@ -2354,10 +2856,10 @@ pub mod testing { event: &api::EndpointInitialized, ) { self.endpoint_initialized.fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_initialized( &self, @@ -2366,10 +2868,10 @@ pub mod testing { ) { self.path_secret_map_initialized .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_uninitialized( &self, @@ -2378,10 +2880,10 @@ pub mod testing { ) { self.path_secret_map_uninitialized .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_background_handshake_requested( &self, @@ -2390,10 +2892,10 @@ pub mod testing { ) { self.path_secret_map_background_handshake_requested .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_inserted( &self, @@ -2402,10 +2904,10 @@ pub mod testing { ) { self.path_secret_map_entry_inserted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_ready( &self, @@ -2414,10 +2916,10 @@ pub mod testing { ) { self.path_secret_map_entry_ready .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_replaced( &self, @@ -2426,10 +2928,10 @@ pub mod testing { ) { self.path_secret_map_entry_replaced .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_sent( &self, @@ -2438,10 +2940,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_sent .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_received( &self, @@ -2450,10 +2952,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_accepted( &self, @@ -2462,10 +2964,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_rejected( &self, @@ -2474,10 +2976,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_dropped( &self, @@ -2486,10 +2988,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_definitely_detected( &self, @@ -2498,10 +3000,10 @@ pub mod testing { ) { self.replay_definitely_detected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_potentially_detected( &self, @@ -2510,10 +3012,10 @@ pub mod testing { ) { self.replay_potentially_detected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_sent( &self, @@ -2522,10 +3024,10 @@ pub mod testing { ) { self.replay_detected_packet_sent .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_received( &self, @@ -2534,10 +3036,10 @@ pub mod testing { ) { self.replay_detected_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_accepted( &self, @@ -2546,10 +3048,10 @@ pub mod testing { ) { self.replay_detected_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_rejected( &self, @@ -2558,10 +3060,10 @@ pub mod testing { ) { self.replay_detected_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_dropped( &self, @@ -2570,10 +3072,10 @@ pub mod testing { ) { self.replay_detected_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_sent( &self, @@ -2581,10 +3083,10 @@ pub mod testing { event: &api::StaleKeyPacketSent, ) { self.stale_key_packet_sent.fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_received( &self, @@ -2593,10 +3095,10 @@ pub mod testing { ) { self.stale_key_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_accepted( &self, @@ -2605,10 +3107,10 @@ pub mod testing { ) { self.stale_key_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_rejected( &self, @@ -2617,10 +3119,10 @@ pub mod testing { ) { self.stale_key_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_dropped( &self, @@ -2629,10 +3131,10 @@ pub mod testing { ) { self.stale_key_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } } } @@ -2742,10 +3244,10 @@ pub mod testing { ) { self.application_write.fetch_add(1, Ordering::Relaxed); if self.location.is_some() { - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } } fn on_application_read( @@ -2756,10 +3258,10 @@ pub mod testing { ) { self.application_read.fetch_add(1, Ordering::Relaxed); if self.location.is_some() { - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } } fn on_endpoint_initialized( @@ -2768,10 +3270,10 @@ pub mod testing { event: &api::EndpointInitialized, ) { self.endpoint_initialized.fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_initialized( &self, @@ -2780,10 +3282,10 @@ pub mod testing { ) { self.path_secret_map_initialized .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_uninitialized( &self, @@ -2792,10 +3294,10 @@ pub mod testing { ) { self.path_secret_map_uninitialized .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_background_handshake_requested( &self, @@ -2804,10 +3306,10 @@ pub mod testing { ) { self.path_secret_map_background_handshake_requested .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_inserted( &self, @@ -2816,10 +3318,10 @@ pub mod testing { ) { self.path_secret_map_entry_inserted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_ready( &self, @@ -2828,10 +3330,10 @@ pub mod testing { ) { self.path_secret_map_entry_ready .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_replaced( &self, @@ -2840,10 +3342,10 @@ pub mod testing { ) { self.path_secret_map_entry_replaced .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_sent( &self, @@ -2852,10 +3354,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_sent .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_received( &self, @@ -2864,10 +3366,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_accepted( &self, @@ -2876,10 +3378,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_rejected( &self, @@ -2888,10 +3390,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_dropped( &self, @@ -2900,10 +3402,10 @@ pub mod testing { ) { self.unknown_path_secret_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_definitely_detected( &self, @@ -2912,10 +3414,10 @@ pub mod testing { ) { self.replay_definitely_detected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_potentially_detected( &self, @@ -2924,10 +3426,10 @@ pub mod testing { ) { self.replay_potentially_detected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_sent( &self, @@ -2936,10 +3438,10 @@ pub mod testing { ) { self.replay_detected_packet_sent .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_received( &self, @@ -2948,10 +3450,10 @@ pub mod testing { ) { self.replay_detected_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_accepted( &self, @@ -2960,10 +3462,10 @@ pub mod testing { ) { self.replay_detected_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_rejected( &self, @@ -2972,10 +3474,10 @@ pub mod testing { ) { self.replay_detected_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_dropped( &self, @@ -2984,10 +3486,10 @@ pub mod testing { ) { self.replay_detected_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_sent( &self, @@ -2995,10 +3497,10 @@ pub mod testing { event: &api::StaleKeyPacketSent, ) { self.stale_key_packet_sent.fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_received( &self, @@ -3007,10 +3509,10 @@ pub mod testing { ) { self.stale_key_packet_received .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_accepted( &self, @@ -3019,10 +3521,10 @@ pub mod testing { ) { self.stale_key_packet_accepted .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_rejected( &self, @@ -3031,10 +3533,10 @@ pub mod testing { ) { self.stale_key_packet_rejected .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_dropped( &self, @@ -3043,10 +3545,10 @@ pub mod testing { ) { self.stale_key_packet_dropped .fetch_add(1, Ordering::Relaxed); - self.output - .lock() - .unwrap() - .push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.lock().unwrap().push(out); } } #[derive(Debug)] @@ -3133,19 +3635,25 @@ pub mod testing { fn on_endpoint_initialized(&self, event: builder::EndpointInitialized) { self.endpoint_initialized.fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_initialized(&self, event: builder::PathSecretMapInitialized) { self.path_secret_map_initialized .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_uninitialized(&self, event: builder::PathSecretMapUninitialized) { self.path_secret_map_uninitialized .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_background_handshake_requested( &self, @@ -3154,31 +3662,41 @@ pub mod testing { self.path_secret_map_background_handshake_requested .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_inserted(&self, event: builder::PathSecretMapEntryInserted) { self.path_secret_map_entry_inserted .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_ready(&self, event: builder::PathSecretMapEntryReady) { self.path_secret_map_entry_ready .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_path_secret_map_entry_replaced(&self, event: builder::PathSecretMapEntryReplaced) { self.path_secret_map_entry_replaced .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_sent(&self, event: builder::UnknownPathSecretPacketSent) { self.unknown_path_secret_packet_sent .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_received( &self, @@ -3187,7 +3705,9 @@ pub mod testing { self.unknown_path_secret_packet_received .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_accepted( &self, @@ -3196,7 +3716,9 @@ pub mod testing { self.unknown_path_secret_packet_accepted .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_rejected( &self, @@ -3205,7 +3727,9 @@ pub mod testing { self.unknown_path_secret_packet_rejected .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_unknown_path_secret_packet_dropped( &self, @@ -3214,78 +3738,104 @@ pub mod testing { self.unknown_path_secret_packet_dropped .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_definitely_detected(&self, event: builder::ReplayDefinitelyDetected) { self.replay_definitely_detected .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_potentially_detected(&self, event: builder::ReplayPotentiallyDetected) { self.replay_potentially_detected .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_sent(&self, event: builder::ReplayDetectedPacketSent) { self.replay_detected_packet_sent .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_received(&self, event: builder::ReplayDetectedPacketReceived) { self.replay_detected_packet_received .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_accepted(&self, event: builder::ReplayDetectedPacketAccepted) { self.replay_detected_packet_accepted .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_rejected(&self, event: builder::ReplayDetectedPacketRejected) { self.replay_detected_packet_rejected .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_replay_detected_packet_dropped(&self, event: builder::ReplayDetectedPacketDropped) { self.replay_detected_packet_dropped .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_sent(&self, event: builder::StaleKeyPacketSent) { self.stale_key_packet_sent.fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_received(&self, event: builder::StaleKeyPacketReceived) { self.stale_key_packet_received .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_accepted(&self, event: builder::StaleKeyPacketAccepted) { self.stale_key_packet_accepted .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_rejected(&self, event: builder::StaleKeyPacketRejected) { self.stale_key_packet_rejected .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn on_stale_key_packet_dropped(&self, event: builder::StaleKeyPacketDropped) { self.stale_key_packet_dropped .fetch_add(1, Ordering::Relaxed); let event = event.into_event(); - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } fn quic_version(&self) -> Option { Some(1) @@ -3296,14 +3846,18 @@ pub mod testing { self.application_write.fetch_add(1, Ordering::Relaxed); let event = event.into_event(); if self.location.is_some() { - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } } fn on_application_read(&self, event: builder::ApplicationRead) { self.application_read.fetch_add(1, Ordering::Relaxed); let event = event.into_event(); if self.location.is_some() { - self.output.lock().unwrap().push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.lock().unwrap().push(out); } } fn quic_version(&self) -> u32 { diff --git a/dc/s2n-quic-dc/src/path/secret/map.rs b/dc/s2n-quic-dc/src/path/secret/map.rs index 09f36a8c3..eb488535b 100644 --- a/dc/s2n-quic-dc/src/path/secret/map.rs +++ b/dc/s2n-quic-dc/src/path/secret/map.rs @@ -19,6 +19,9 @@ mod state; mod status; mod store; +#[cfg(test)] +mod event_tests; + use entry::Entry; use store::Store; @@ -203,4 +206,50 @@ impl Map { let entry = Entry::fake(peer, Some(receiver)); self.store.test_insert(entry); } + + #[cfg(test)] + fn test_insert_pair( + &self, + local_addr: SocketAddr, + peer: &Self, + peer_addr: SocketAddr, + ) -> crate::credentials::Id { + use crate::path::secret::{schedule, sender}; + use s2n_quic_core::endpoint::Type; + + let ciphersuite = schedule::Ciphersuite::AES_GCM_128_SHA256; + + let mut secret = [0; 32]; + aws_lc_rs::rand::fill(&mut secret).unwrap(); + + let insert = |map: &Self, peer: &Self, peer_addr, endpoint| { + let secret = + schedule::Secret::new(ciphersuite, dc::SUPPORTED_VERSIONS[0], endpoint, &secret); + let id = *secret.id(); + + let srt = peer.store.signer().sign(&id); + + let sender = sender::State::new(srt); + + let entry = Entry::new( + peer_addr, + secret, + sender, + map.store.receiver().clone().new_receiver(), + dc::testing::TEST_APPLICATION_PARAMS, + dc::testing::TEST_REHANDSHAKE_PERIOD, + ); + let entry = Arc::new(entry); + map.store.test_insert(entry); + + id + }; + + let client_id = insert(self, peer, peer_addr, Type::Client); + let server_id = insert(peer, self, local_addr, Type::Server); + + assert_eq!(client_id, server_id); + + client_id + } } diff --git a/dc/s2n-quic-dc/src/path/secret/map/entry.rs b/dc/s2n-quic-dc/src/path/secret/map/entry.rs index 59c22ae8e..6bf292a33 100644 --- a/dc/s2n-quic-dc/src/path/secret/map/entry.rs +++ b/dc/s2n-quic-dc/src/path/secret/map/entry.rs @@ -230,9 +230,13 @@ impl Entry { &self.sender } - pub fn control_secret(&self) -> crate::crypto::awslc::open::control::Secret { + pub fn control_opener(&self) -> crate::crypto::awslc::open::control::Secret { self.sender.control_secret(&self.secret) } + + pub fn control_sealer(&self) -> crate::crypto::awslc::seal::control::Secret { + self.secret.control_sealer() + } } impl receiver::Error { @@ -250,13 +254,13 @@ impl receiver::Error { credential_id: credentials.id, rejected_key_id: credentials.key_id, } - .encode(encoder, &entry.secret.control_sealer()), + .encode(encoder, &entry.control_sealer()), receiver::Error::Unknown => control::StaleKey { wire_version: WireVersion::ZERO, credential_id: credentials.id, min_key_id: entry.receiver.minimum_unseen_key_id(), } - .encode(encoder, &entry.secret.control_sealer()), + .encode(encoder, &entry.control_sealer()), }; &buffer[..length] } diff --git a/dc/s2n-quic-dc/src/path/secret/map/event_tests.rs b/dc/s2n-quic-dc/src/path/secret/map/event_tests.rs new file mode 100644 index 000000000..0c7c8177d --- /dev/null +++ b/dc/s2n-quic-dc/src/path/secret/map/event_tests.rs @@ -0,0 +1,112 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + event::testing::Subscriber, + packet::{secret_control as control, WireVersion}, + path::secret::{stateless_reset, Map}, +}; +use s2n_codec::{DecoderBufferMut, EncoderBuffer}; +use std::sync::Arc; + +#[track_caller] +fn sub() -> Arc { + Arc::new(Subscriber::snapshot()) +} + +#[track_caller] +fn map(capacity: usize) -> Map { + map_sub(capacity, sub()) +} + +fn map_sub(capacity: usize, sub: Arc) -> Map { + let signer = stateless_reset::Signer::random(); + Map::new(signer, capacity, sub) +} + +#[test] +fn init_uninit() { + let _ = map(10); +} + +#[test] +fn insert_one() { + let map = map(10); + map.test_insert("127.0.0.1:4567".parse().unwrap()); +} + +#[test] +fn control_packets() { + let sub = sub(); + let client = map_sub(10, sub.clone()); + let server = map_sub(10, sub); + + let client_addr = "127.0.0.1:1234".parse().unwrap(); + let server_addr = "127.0.0.1:5678".parse().unwrap(); + + let id = client.test_insert_pair(client_addr, &server, server_addr); + + let mut out = [0; 128]; + + macro_rules! packet { + ($expr:expr, $crypto:expr) => { + let v = $expr; + let len = v.encode(EncoderBuffer::new(&mut out), $crypto); + let buf = &mut out[..len]; + let (pkt, _) = control::Packet::decode(DecoderBufferMut::new(buf)).unwrap(); + client.handle_control_packet(&pkt, &server_addr); + }; + } + + let server_entry = server.store.get_by_id(&id).unwrap().clone(); + let client_entry = client.store.get_by_id(&id).unwrap().clone(); + + let fake_secret = + crate::path::secret::seal::control::Secret::new(&[0; 32], &aws_lc_rs::hmac::HMAC_SHA256); + let fake_srt = [0; 16]; + let fake_id = [0; 16].into(); + + // make sure control packets can't be reflected back + let client_secret = client_entry.control_sealer(); + let client_srt = client_entry.sender().stateless_reset; + + let real_secret = server_entry.control_sealer(); + let real_id = *server_entry.id(); + let real_srt = server_entry.sender().stateless_reset; + + // try to send a series of packet types from the server to the client + let attempts = [ + (&fake_secret, fake_srt, fake_id), + (&fake_secret, fake_srt, real_id), + (&client_secret, client_srt, real_id), + (&real_secret, real_srt, real_id), + ]; + + for (secret, stateless_reset, credential_id) in attempts { + packet!( + control::UnknownPathSecret { + wire_version: WireVersion::ZERO, + credential_id, + }, + &stateless_reset + ); + + packet!( + control::StaleKey { + wire_version: WireVersion::ZERO, + credential_id, + min_key_id: 123u16.into(), + }, + secret + ); + + packet!( + control::ReplayDetected { + wire_version: WireVersion::ZERO, + credential_id, + rejected_key_id: 123u16.into(), + }, + secret + ); + } +} diff --git a/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__control_packets__events.snap b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__control_packets__events.snap new file mode 100644 index 000000000..0a2d46705 --- /dev/null +++ b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__control_packets__events.snap @@ -0,0 +1,38 @@ +--- +source: quic/s2n-quic-core/src/event/snapshot.rs +input_file: dc/s2n-quic-dc/src/path/secret/map/event_tests.rs +--- +EndpointMeta PathSecretMapInitialized { capacity: 10 } +EndpointMeta PathSecretMapInitialized { capacity: 10 } +EndpointMeta PathSecretMapEntryInserted { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapEntryReady { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapEntryInserted { peer_address: 127.0.0.1:1234, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapEntryReady { peer_address: 127.0.0.1:1234, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketDropped { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketDropped { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketDropped { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketAccepted { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapBackgroundHandshakeRequested { peer_address: 127.0.0.1:5678 } +EndpointMeta StaleKeyPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta UnknownPathSecretPacketRejected { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta StaleKeyPacketAccepted { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketReceived { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]" } +EndpointMeta ReplayDetectedPacketAccepted { peer_address: 127.0.0.1:5678, credential_id: "[HIDDEN]", key_id: 123 } +EndpointMeta PathSecretMapBackgroundHandshakeRequested { peer_address: 127.0.0.1:5678 } +EndpointMeta PathSecretMapUninitialized { capacity: 10, entries: 1 } +EndpointMeta PathSecretMapUninitialized { capacity: 10, entries: 1 } diff --git a/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__init_uninit__events.snap b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__init_uninit__events.snap new file mode 100644 index 000000000..a5f7749cb --- /dev/null +++ b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__init_uninit__events.snap @@ -0,0 +1,6 @@ +--- +source: quic/s2n-quic-core/src/event/snapshot.rs +input_file: dc/s2n-quic-dc/src/path/secret/map/event_tests.rs +--- +EndpointMeta PathSecretMapInitialized { capacity: 10 } +EndpointMeta PathSecretMapUninitialized { capacity: 10, entries: 0 } diff --git a/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__insert_one__events.snap b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__insert_one__events.snap new file mode 100644 index 000000000..4c0a828c7 --- /dev/null +++ b/dc/s2n-quic-dc/src/path/secret/map/snapshots/path__secret__map__event_tests__insert_one__events.snap @@ -0,0 +1,8 @@ +--- +source: quic/s2n-quic-core/src/event/snapshot.rs +input_file: dc/s2n-quic-dc/src/path/secret/map/event_tests.rs +--- +EndpointMeta PathSecretMapInitialized { capacity: 10 } +EndpointMeta PathSecretMapEntryInserted { peer_address: 127.0.0.1:4567, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapEntryReady { peer_address: 127.0.0.1:4567, credential_id: "[HIDDEN]" } +EndpointMeta PathSecretMapUninitialized { capacity: 10, entries: 1 } diff --git a/dc/s2n-quic-dc/src/path/secret/map/state.rs b/dc/s2n-quic-dc/src/path/secret/map/state.rs index 51da6823b..6e3bc490d 100644 --- a/dc/s2n-quic-dc/src/path/secret/map/state.rs +++ b/dc/s2n-quic-dc/src/path/secret/map/state.rs @@ -202,7 +202,7 @@ impl State { return; }; - let key = entry.control_secret(); + let key = entry.control_opener(); let Some(packet) = packet.authenticate(&key) else { self.subscriber().on_stale_key_packet_rejected( @@ -248,7 +248,7 @@ impl State { return; }; - let key = entry.control_secret(); + let key = entry.control_opener(); let Some(packet) = packet.authenticate(&key) else { self.subscriber().on_replay_detected_packet_rejected( diff --git a/quic/s2n-quic-core/src/event/generated.rs b/quic/s2n-quic-core/src/event/generated.rs index 805fadd1a..2fd6ff90d 100644 --- a/quic/s2n-quic-core/src/event/generated.rs +++ b/quic/s2n-quic-core/src/event/generated.rs @@ -17,15 +17,41 @@ pub mod api { pub id: u64, pub timestamp: crate::event::Timestamp, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionMeta { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionMeta"); + fmt.field("endpoint_type", &self.endpoint_type); + fmt.field("id", &self.id); + fmt.field("timestamp", &self.timestamp); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct EndpointMeta { pub endpoint_type: EndpointType, pub timestamp: crate::event::Timestamp, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointMeta { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointMeta"); + fmt.field("endpoint_type", &self.endpoint_type); + fmt.field("timestamp", &self.timestamp); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct ConnectionInfo {} + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionInfo { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionInfo"); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct TransportParameters<'a> { @@ -48,6 +74,52 @@ pub mod api { pub max_datagram_frame_size: u64, pub dc_supported_versions: &'a [u32], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for TransportParameters<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TransportParameters"); + fmt.field( + "original_destination_connection_id", + &self.original_destination_connection_id, + ); + fmt.field( + "initial_source_connection_id", + &self.initial_source_connection_id, + ); + fmt.field( + "retry_source_connection_id", + &self.retry_source_connection_id, + ); + fmt.field("stateless_reset_token", &self.stateless_reset_token); + fmt.field("preferred_address", &self.preferred_address); + fmt.field("migration_support", &self.migration_support); + fmt.field("max_idle_timeout", &self.max_idle_timeout); + fmt.field("ack_delay_exponent", &self.ack_delay_exponent); + fmt.field("max_ack_delay", &self.max_ack_delay); + fmt.field("max_udp_payload_size", &self.max_udp_payload_size); + fmt.field( + "active_connection_id_limit", + &self.active_connection_id_limit, + ); + fmt.field( + "initial_max_stream_data_bidi_local", + &self.initial_max_stream_data_bidi_local, + ); + fmt.field( + "initial_max_stream_data_bidi_remote", + &self.initial_max_stream_data_bidi_remote, + ); + fmt.field( + "initial_max_stream_data_uni", + &self.initial_max_stream_data_uni, + ); + fmt.field("initial_max_streams_bidi", &self.initial_max_streams_bidi); + fmt.field("initial_max_streams_uni", &self.initial_max_streams_uni); + fmt.field("max_datagram_frame_size", &self.max_datagram_frame_size); + fmt.field("dc_supported_versions", &self.dc_supported_versions); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct PreferredAddress<'a> { @@ -56,6 +128,17 @@ pub mod api { pub connection_id: ConnectionId<'a>, pub stateless_reset_token: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PreferredAddress<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PreferredAddress"); + fmt.field("ipv4_address", &self.ipv4_address); + fmt.field("ipv6_address", &self.ipv6_address); + fmt.field("connection_id", &self.connection_id); + fmt.field("stateless_reset_token", &self.stateless_reset_token); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct Path<'a> { @@ -66,11 +149,32 @@ pub mod api { pub id: u64, pub is_active: bool, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for Path<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("Path"); + fmt.field("local_addr", &self.local_addr); + fmt.field("local_cid", &self.local_cid); + fmt.field("remote_addr", &self.remote_addr); + fmt.field("remote_cid", &self.remote_cid); + fmt.field("id", &self.id); + fmt.field("is_active", &self.is_active); + fmt.finish() + } + } #[non_exhaustive] #[derive(Clone)] pub struct ConnectionId<'a> { pub bytes: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ConnectionId<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionId"); + fmt.field("bytes", &self.bytes); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct EcnCounts { @@ -84,6 +188,16 @@ pub mod api { #[doc = " received with the CE codepoint."] pub ce_count: u64, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EcnCounts { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EcnCounts"); + fmt.field("ect_0_count", &self.ect_0_count); + fmt.field("ect_1_count", &self.ect_1_count); + fmt.field("ce_count", &self.ce_count); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub struct MtuConfig { @@ -91,6 +205,16 @@ pub mod api { pub base_mtu: u16, pub max_mtu: u16, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for MtuConfig { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("MtuConfig"); + fmt.field("initial_mtu", &self.initial_mtu); + fmt.field("base_mtu", &self.base_mtu); + fmt.field("max_mtu", &self.max_mtu); + fmt.finish() + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " A bandwidth delivery rate estimate with associated metadata"] @@ -116,6 +240,26 @@ pub mod api { #[doc = " The delivery rate for this rate sample"] pub delivery_rate_bytes_per_second: u64, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for RateSample { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("RateSample"); + fmt.field("interval", &self.interval); + fmt.field("delivered_bytes", &self.delivered_bytes); + fmt.field("lost_bytes", &self.lost_bytes); + fmt.field("ecn_ce_count", &self.ecn_ce_count); + fmt.field("is_app_limited", &self.is_app_limited); + fmt.field("prior_delivered_bytes", &self.prior_delivered_bytes); + fmt.field("bytes_in_flight", &self.bytes_in_flight); + fmt.field("prior_lost_bytes", &self.prior_lost_bytes); + fmt.field("prior_ecn_ce_count", &self.prior_ecn_ce_count); + fmt.field( + "delivery_rate_bytes_per_second", + &self.delivery_rate_bytes_per_second, + ); + fmt.finish() + } + } #[non_exhaustive] #[derive(Clone)] pub enum SocketAddress<'a> { @@ -624,6 +768,17 @@ pub mod api { pub struct ApplicationProtocolInformation<'a> { pub chosen_application_protocol: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ApplicationProtocolInformation<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ApplicationProtocolInformation"); + fmt.field( + "chosen_application_protocol", + &self.chosen_application_protocol, + ); + fmt.finish() + } + } impl<'a> Event for ApplicationProtocolInformation<'a> { const NAME: &'static str = "transport:application_protocol_information"; } @@ -633,6 +788,14 @@ pub mod api { pub struct ServerNameInformation<'a> { pub chosen_server_name: &'a str, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ServerNameInformation<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ServerNameInformation"); + fmt.field("chosen_server_name", &self.chosen_server_name); + fmt.finish() + } + } impl<'a> Event for ServerNameInformation<'a> { const NAME: &'static str = "transport:server_name_information"; } @@ -644,6 +807,16 @@ pub mod api { pub space: KeySpace, pub reason: PacketSkipReason, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PacketSkipped { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacketSkipped"); + fmt.field("number", &self.number); + fmt.field("space", &self.space); + fmt.field("reason", &self.reason); + fmt.finish() + } + } impl Event for PacketSkipped { const NAME: &'static str = "transport:packet_skipped"; } @@ -654,6 +827,15 @@ pub mod api { pub packet_header: PacketHeader, pub packet_len: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PacketSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacketSent"); + fmt.field("packet_header", &self.packet_header); + fmt.field("packet_len", &self.packet_len); + fmt.finish() + } + } impl Event for PacketSent { const NAME: &'static str = "transport:packet_sent"; } @@ -663,6 +845,14 @@ pub mod api { pub struct PacketReceived { pub packet_header: PacketHeader, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PacketReceived { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacketReceived"); + fmt.field("packet_header", &self.packet_header); + fmt.finish() + } + } impl Event for PacketReceived { const NAME: &'static str = "transport:packet_received"; } @@ -673,6 +863,15 @@ pub mod api { pub previous: Path<'a>, pub active: Path<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ActivePathUpdated<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ActivePathUpdated"); + fmt.field("previous", &self.previous); + fmt.field("active", &self.active); + fmt.finish() + } + } impl<'a> Event for ActivePathUpdated<'a> { const NAME: &'static str = "connectivity:active_path_updated"; } @@ -683,6 +882,15 @@ pub mod api { pub active: Path<'a>, pub new: Path<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathCreated<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathCreated"); + fmt.field("active", &self.active); + fmt.field("new", &self.new); + fmt.finish() + } + } impl<'a> Event for PathCreated<'a> { const NAME: &'static str = "transport:path_created"; } @@ -694,6 +902,16 @@ pub mod api { pub path_id: u64, pub frame: Frame, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for FrameSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("FrameSent"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path_id", &self.path_id); + fmt.field("frame", &self.frame); + fmt.finish() + } + } impl Event for FrameSent { const NAME: &'static str = "transport:frame_sent"; } @@ -705,6 +923,16 @@ pub mod api { pub path: Path<'a>, pub frame: Frame, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for FrameReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("FrameReceived"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path", &self.path); + fmt.field("frame", &self.frame); + fmt.finish() + } + } impl<'a> Event for FrameReceived<'a> { const NAME: &'static str = "transport:frame_received"; } @@ -717,6 +945,17 @@ pub mod api { pub bytes_lost: u16, pub is_mtu_probe: bool, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PacketLost<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacketLost"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path", &self.path); + fmt.field("bytes_lost", &self.bytes_lost); + fmt.field("is_mtu_probe", &self.is_mtu_probe); + fmt.finish() + } + } impl<'a> Event for PacketLost<'a> { const NAME: &'static str = "recovery:packet_lost"; } @@ -735,6 +974,23 @@ pub mod api { pub bytes_in_flight: u32, pub congestion_limited: bool, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for RecoveryMetrics<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("RecoveryMetrics"); + fmt.field("path", &self.path); + fmt.field("min_rtt", &self.min_rtt); + fmt.field("smoothed_rtt", &self.smoothed_rtt); + fmt.field("latest_rtt", &self.latest_rtt); + fmt.field("rtt_variance", &self.rtt_variance); + fmt.field("max_ack_delay", &self.max_ack_delay); + fmt.field("pto_count", &self.pto_count); + fmt.field("congestion_window", &self.congestion_window); + fmt.field("bytes_in_flight", &self.bytes_in_flight); + fmt.field("congestion_limited", &self.congestion_limited); + fmt.finish() + } + } impl<'a> Event for RecoveryMetrics<'a> { const NAME: &'static str = "recovery:metrics_updated"; } @@ -745,6 +1001,15 @@ pub mod api { pub path: Path<'a>, pub source: CongestionSource, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for Congestion<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("Congestion"); + fmt.field("path", &self.path); + fmt.field("source", &self.source); + fmt.finish() + } + } impl<'a> Event for Congestion<'a> { const NAME: &'static str = "recovery:congestion"; } @@ -757,6 +1022,16 @@ pub mod api { pub action: AckAction, pub path: Path<'a>, } + #[cfg(any(test, feature = "testing"))] + #[allow(deprecated)] + impl<'a> crate::event::snapshot::Fmt for AckProcessed<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("AckProcessed"); + fmt.field("action", &self.action); + fmt.field("path", &self.path); + fmt.finish() + } + } #[allow(deprecated)] impl<'a> Event for AckProcessed<'a> { const NAME: &'static str = "recovery:ack_processed"; @@ -780,6 +1055,17 @@ pub mod api { #[doc = " The store packet_number range in the IntervalSet"] pub stored_range: core::ops::RangeInclusive, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for RxAckRangeDropped<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("RxAckRangeDropped"); + fmt.field("path", &self.path); + fmt.field("packet_number_range", &self.packet_number_range); + fmt.field("capacity", &self.capacity); + fmt.field("stored_range", &self.stored_range); + fmt.finish() + } + } impl<'a> Event for RxAckRangeDropped<'a> { const NAME: &'static str = "recovery:rx_ack_range_dropped"; } @@ -791,6 +1077,16 @@ pub mod api { pub path: Path<'a>, pub ack_range: RangeInclusive, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for AckRangeReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("AckRangeReceived"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path", &self.path); + fmt.field("ack_range", &self.ack_range); + fmt.finish() + } + } impl<'a> Event for AckRangeReceived<'a> { const NAME: &'static str = "recovery:ack_range_received"; } @@ -802,6 +1098,16 @@ pub mod api { pub path_id: u64, pub ack_range: RangeInclusive, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for AckRangeSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("AckRangeSent"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path_id", &self.path_id); + fmt.field("ack_range", &self.ack_range); + fmt.finish() + } + } impl Event for AckRangeSent { const NAME: &'static str = "recovery:ack_range_sent"; } @@ -811,6 +1117,14 @@ pub mod api { pub struct PacketDropped<'a> { pub reason: PacketDropReason<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PacketDropped<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacketDropped"); + fmt.field("reason", &self.reason); + fmt.finish() + } + } impl<'a> Event for PacketDropped<'a> { const NAME: &'static str = "transport:packet_dropped"; } @@ -821,6 +1135,15 @@ pub mod api { pub key_type: KeyType, pub cipher_suite: CipherSuite, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for KeyUpdate { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("KeyUpdate"); + fmt.field("key_type", &self.key_type); + fmt.field("cipher_suite", &self.cipher_suite); + fmt.finish() + } + } impl Event for KeyUpdate { const NAME: &'static str = "security:key_update"; } @@ -829,6 +1152,14 @@ pub mod api { pub struct KeySpaceDiscarded { pub space: KeySpace, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for KeySpaceDiscarded { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("KeySpaceDiscarded"); + fmt.field("space", &self.space); + fmt.finish() + } + } impl Event for KeySpaceDiscarded { const NAME: &'static str = "security:key_space_discarded"; } @@ -838,6 +1169,14 @@ pub mod api { pub struct ConnectionStarted<'a> { pub path: Path<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ConnectionStarted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionStarted"); + fmt.field("path", &self.path); + fmt.finish() + } + } impl<'a> Event for ConnectionStarted<'a> { const NAME: &'static str = "connectivity:connection_started"; } @@ -847,6 +1186,14 @@ pub mod api { pub struct ConnectionClosed { pub error: crate::connection::Error, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionClosed { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionClosed"); + fmt.field("error", &self.error); + fmt.finish() + } + } impl Event for ConnectionClosed { const NAME: &'static str = "connectivity:connection_closed"; } @@ -858,6 +1205,16 @@ pub mod api { pub path: Path<'a>, pub error: DuplicatePacketError, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for DuplicatePacket<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DuplicatePacket"); + fmt.field("packet_header", &self.packet_header); + fmt.field("path", &self.path); + fmt.field("error", &self.error); + fmt.finish() + } + } impl<'a> Event for DuplicatePacket<'a> { const NAME: &'static str = "transport:duplicate_packet"; } @@ -867,6 +1224,14 @@ pub mod api { pub struct TransportParametersReceived<'a> { pub transport_parameters: TransportParameters<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for TransportParametersReceived<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TransportParametersReceived"); + fmt.field("transport_parameters", &self.transport_parameters); + fmt.finish() + } + } impl<'a> Event for TransportParametersReceived<'a> { const NAME: &'static str = "transport:transport_parameters_received"; } @@ -883,6 +1248,15 @@ pub mod api { #[doc = " See the [Linux kernel documentation](https://www.kernel.org/doc/html/latest/networking/segmentation-offloads.html#generic-segmentation-offload) for more details."] pub gso_offset: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for DatagramSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DatagramSent"); + fmt.field("len", &self.len); + fmt.field("gso_offset", &self.gso_offset); + fmt.finish() + } + } impl Event for DatagramSent { const NAME: &'static str = "transport:datagram_sent"; } @@ -892,6 +1266,14 @@ pub mod api { pub struct DatagramReceived { pub len: u16, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for DatagramReceived { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DatagramReceived"); + fmt.field("len", &self.len); + fmt.finish() + } + } impl Event for DatagramReceived { const NAME: &'static str = "transport:datagram_received"; } @@ -902,6 +1284,15 @@ pub mod api { pub len: u16, pub reason: DatagramDropReason, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for DatagramDropped { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DatagramDropped"); + fmt.field("len", &self.len); + fmt.field("reason", &self.reason); + fmt.finish() + } + } impl Event for DatagramDropped { const NAME: &'static str = "transport:datagram_dropped"; } @@ -915,6 +1306,17 @@ pub mod api { pub previous: ConnectionId<'a>, pub current: ConnectionId<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for ConnectionIdUpdated<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionIdUpdated"); + fmt.field("path_id", &self.path_id); + fmt.field("cid_consumer", &self.cid_consumer); + fmt.field("previous", &self.previous); + fmt.field("current", &self.current); + fmt.finish() + } + } impl<'a> Event for ConnectionIdUpdated<'a> { const NAME: &'static str = "connectivity:connection_id_updated"; } @@ -924,6 +1326,15 @@ pub mod api { pub path: Path<'a>, pub state: EcnState, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for EcnStateChanged<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EcnStateChanged"); + fmt.field("path", &self.path); + fmt.field("state", &self.state); + fmt.finish() + } + } impl<'a> Event for EcnStateChanged<'a> { const NAME: &'static str = "recovery:ecn_state_changed"; } @@ -932,6 +1343,14 @@ pub mod api { pub struct ConnectionMigrationDenied { pub reason: MigrationDenyReason, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for ConnectionMigrationDenied { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("ConnectionMigrationDenied"); + fmt.field("reason", &self.reason); + fmt.finish() + } + } impl Event for ConnectionMigrationDenied { const NAME: &'static str = "connectivity:connection_migration_denied"; } @@ -940,6 +1359,14 @@ pub mod api { pub struct HandshakeStatusUpdated { pub status: HandshakeStatus, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for HandshakeStatusUpdated { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("HandshakeStatusUpdated"); + fmt.field("status", &self.status); + fmt.finish() + } + } impl Event for HandshakeStatusUpdated { const NAME: &'static str = "connectivity:handshake_status_updated"; } @@ -948,6 +1375,14 @@ pub mod api { pub struct TlsExporterReady<'a> { pub session: crate::event::TlsSession<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for TlsExporterReady<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TlsExporterReady"); + fmt.field("session", &self.session); + fmt.finish() + } + } impl<'a> Event for TlsExporterReady<'a> { const NAME: &'static str = "connectivity:tls_exporter_ready"; } @@ -959,6 +1394,16 @@ pub mod api { pub path: Path<'a>, pub challenge_data: &'a [u8], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PathChallengeUpdated<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PathChallengeUpdated"); + fmt.field("path_challenge_status", &self.path_challenge_status); + fmt.field("path", &self.path); + fmt.field("challenge_data", &self.challenge_data); + fmt.finish() + } + } impl<'a> Event for PathChallengeUpdated<'a> { const NAME: &'static str = "connectivity:path_challenge_updated"; } @@ -967,6 +1412,14 @@ pub mod api { pub struct TlsClientHello<'a> { pub payload: &'a [&'a [u8]], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for TlsClientHello<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TlsClientHello"); + fmt.field("payload", &self.payload); + fmt.finish() + } + } impl<'a> Event for TlsClientHello<'a> { const NAME: &'static str = "tls:client_hello"; } @@ -975,6 +1428,14 @@ pub mod api { pub struct TlsServerHello<'a> { pub payload: &'a [&'a [u8]], } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for TlsServerHello<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TlsServerHello"); + fmt.field("payload", &self.payload); + fmt.finish() + } + } impl<'a> Event for TlsServerHello<'a> { const NAME: &'static str = "tls:server_hello"; } @@ -983,6 +1444,14 @@ pub mod api { pub struct RxStreamProgress { pub bytes: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for RxStreamProgress { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("RxStreamProgress"); + fmt.field("bytes", &self.bytes); + fmt.finish() + } + } impl Event for RxStreamProgress { const NAME: &'static str = "transport:rx_stream_progress"; } @@ -991,6 +1460,14 @@ pub mod api { pub struct TxStreamProgress { pub bytes: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for TxStreamProgress { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("TxStreamProgress"); + fmt.field("bytes", &self.bytes); + fmt.finish() + } + } impl Event for TxStreamProgress { const NAME: &'static str = "transport:tx_stream_progress"; } @@ -999,6 +1476,14 @@ pub mod api { pub struct KeepAliveTimerExpired { pub timeout: Duration, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for KeepAliveTimerExpired { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("KeepAliveTimerExpired"); + fmt.field("timeout", &self.timeout); + fmt.finish() + } + } impl Event for KeepAliveTimerExpired { const NAME: &'static str = "connectivity::keep_alive_timer_expired"; } @@ -1013,6 +1498,17 @@ pub mod api { #[doc = " The search for the maximum MTU has completed for now"] pub search_complete: bool, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for MtuUpdated { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("MtuUpdated"); + fmt.field("path_id", &self.path_id); + fmt.field("mtu", &self.mtu); + fmt.field("cause", &self.cause); + fmt.field("search_complete", &self.search_complete); + fmt.finish() + } + } impl Event for MtuUpdated { const NAME: &'static str = "connectivity:mtu_updated"; } @@ -1024,6 +1520,16 @@ pub mod api { pub cause: SlowStartExitCause, pub congestion_window: u32, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for SlowStartExited { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("SlowStartExited"); + fmt.field("path_id", &self.path_id); + fmt.field("cause", &self.cause); + fmt.field("congestion_window", &self.congestion_window); + fmt.finish() + } + } impl Event for SlowStartExited { const NAME: &'static str = "recovery:slow_start_exited"; } @@ -1036,6 +1542,15 @@ pub mod api { pub path_id: u64, pub rate_sample: RateSample, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for DeliveryRateSampled { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DeliveryRateSampled"); + fmt.field("path_id", &self.path_id); + fmt.field("rate_sample", &self.rate_sample); + fmt.finish() + } + } impl Event for DeliveryRateSampled { const NAME: &'static str = "recovery:delivery_rate_sampled"; } @@ -1048,6 +1563,17 @@ pub mod api { pub burst_size: u32, pub pacing_gain: f32, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PacingRateUpdated { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PacingRateUpdated"); + fmt.field("path_id", &self.path_id); + fmt.field("bytes_per_second", &self.bytes_per_second); + fmt.field("burst_size", &self.burst_size); + fmt.field("pacing_gain", &self.pacing_gain); + fmt.finish() + } + } impl Event for PacingRateUpdated { const NAME: &'static str = "recovery:pacing_rate_updated"; } @@ -1058,6 +1584,15 @@ pub mod api { pub path_id: u64, pub state: BbrState, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for BbrStateChanged { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("BbrStateChanged"); + fmt.field("path_id", &self.path_id); + fmt.field("state", &self.state); + fmt.finish() + } + } impl Event for BbrStateChanged { const NAME: &'static str = "recovery:bbr_state_changed"; } @@ -1067,6 +1602,14 @@ pub mod api { pub struct DcStateChanged { pub state: DcState, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for DcStateChanged { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("DcStateChanged"); + fmt.field("state", &self.state); + fmt.finish() + } + } impl Event for DcStateChanged { const NAME: &'static str = "transport:dc_state_changed"; } @@ -1078,6 +1621,16 @@ pub mod api { pub client_versions: &'a [u32], pub chosen_version: Option, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for VersionInformation<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("VersionInformation"); + fmt.field("server_versions", &self.server_versions); + fmt.field("client_versions", &self.client_versions); + fmt.field("chosen_version", &self.chosen_version); + fmt.finish() + } + } impl<'a> Event for VersionInformation<'a> { const NAME: &'static str = "transport::version_information"; } @@ -1087,6 +1640,14 @@ pub mod api { pub struct EndpointPacketSent { pub packet_header: PacketHeader, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointPacketSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointPacketSent"); + fmt.field("packet_header", &self.packet_header); + fmt.finish() + } + } impl Event for EndpointPacketSent { const NAME: &'static str = "transport:packet_sent"; } @@ -1096,6 +1657,14 @@ pub mod api { pub struct EndpointPacketReceived { pub packet_header: PacketHeader, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointPacketReceived { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointPacketReceived"); + fmt.field("packet_header", &self.packet_header); + fmt.finish() + } + } impl Event for EndpointPacketReceived { const NAME: &'static str = "transport:packet_received"; } @@ -1112,6 +1681,15 @@ pub mod api { #[doc = " See the [Linux kernel documentation](https://www.kernel.org/doc/html/latest/networking/segmentation-offloads.html#generic-segmentation-offload) for more details."] pub gso_offset: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointDatagramSent { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointDatagramSent"); + fmt.field("len", &self.len); + fmt.field("gso_offset", &self.gso_offset); + fmt.finish() + } + } impl Event for EndpointDatagramSent { const NAME: &'static str = "transport:datagram_sent"; } @@ -1121,6 +1699,14 @@ pub mod api { pub struct EndpointDatagramReceived { pub len: u16, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointDatagramReceived { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointDatagramReceived"); + fmt.field("len", &self.len); + fmt.finish() + } + } impl Event for EndpointDatagramReceived { const NAME: &'static str = "transport:datagram_received"; } @@ -1131,6 +1717,15 @@ pub mod api { pub len: u16, pub reason: DatagramDropReason, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointDatagramDropped { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointDatagramDropped"); + fmt.field("len", &self.len); + fmt.field("reason", &self.reason); + fmt.finish() + } + } impl Event for EndpointDatagramDropped { const NAME: &'static str = "transport:datagram_dropped"; } @@ -1139,6 +1734,14 @@ pub mod api { pub struct EndpointConnectionAttemptFailed { pub error: crate::connection::Error, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for EndpointConnectionAttemptFailed { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("EndpointConnectionAttemptFailed"); + fmt.field("error", &self.error); + fmt.finish() + } + } impl Event for EndpointConnectionAttemptFailed { const NAME: &'static str = "transport:connection_attempt_failed"; } @@ -1159,6 +1762,18 @@ pub mod api { #[doc = " This can happen when a burst of errors exceeds the capacity of the recorder"] pub dropped_errors: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformTx { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformTx"); + fmt.field("count", &self.count); + fmt.field("syscalls", &self.syscalls); + fmt.field("blocked_syscalls", &self.blocked_syscalls); + fmt.field("total_errors", &self.total_errors); + fmt.field("dropped_errors", &self.dropped_errors); + fmt.finish() + } + } impl Event for PlatformTx { const NAME: &'static str = "platform:tx"; } @@ -1169,6 +1784,14 @@ pub mod api { #[doc = " The error code returned by the platform"] pub errno: i32, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformTxError { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformTxError"); + fmt.field("errno", &self.errno); + fmt.finish() + } + } impl Event for PlatformTxError { const NAME: &'static str = "platform:tx_error"; } @@ -1189,6 +1812,18 @@ pub mod api { #[doc = " This can happen when a burst of errors exceeds the capacity of the recorder"] pub dropped_errors: usize, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformRx { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformRx"); + fmt.field("count", &self.count); + fmt.field("syscalls", &self.syscalls); + fmt.field("blocked_syscalls", &self.blocked_syscalls); + fmt.field("total_errors", &self.total_errors); + fmt.field("dropped_errors", &self.dropped_errors); + fmt.finish() + } + } impl Event for PlatformRx { const NAME: &'static str = "platform:rx"; } @@ -1199,6 +1834,14 @@ pub mod api { #[doc = " The error code returned by the platform"] pub errno: i32, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformRxError { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformRxError"); + fmt.field("errno", &self.errno); + fmt.finish() + } + } impl Event for PlatformRxError { const NAME: &'static str = "platform:rx_error"; } @@ -1208,6 +1851,14 @@ pub mod api { pub struct PlatformFeatureConfigured { pub configuration: PlatformFeatureConfiguration, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformFeatureConfigured { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformFeatureConfigured"); + fmt.field("configuration", &self.configuration); + fmt.finish() + } + } impl Event for PlatformFeatureConfigured { const NAME: &'static str = "platform:feature_configured"; } @@ -1219,6 +1870,17 @@ pub mod api { pub tx_ready: bool, pub application_wakeup: bool, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformEventLoopWakeup { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformEventLoopWakeup"); + fmt.field("timeout_expired", &self.timeout_expired); + fmt.field("rx_ready", &self.rx_ready); + fmt.field("tx_ready", &self.tx_ready); + fmt.field("application_wakeup", &self.application_wakeup); + fmt.finish() + } + } impl Event for PlatformEventLoopWakeup { const NAME: &'static str = "platform:event_loop_wakeup"; } @@ -1230,6 +1892,15 @@ pub mod api { #[doc = " The amount of time spent processing endpoint events in a single event loop"] pub processing_duration: core::time::Duration, } + #[cfg(any(test, feature = "testing"))] + impl crate::event::snapshot::Fmt for PlatformEventLoopSleep { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformEventLoopSleep"); + fmt.field("timeout", &self.timeout); + fmt.field("processing_duration", &self.processing_duration); + fmt.finish() + } + } impl Event for PlatformEventLoopSleep { const NAME: &'static str = "platform:event_loop_sleep"; } @@ -1239,6 +1910,14 @@ pub mod api { #[doc = " The local address of the socket"] pub local_address: SocketAddress<'a>, } + #[cfg(any(test, feature = "testing"))] + impl<'a> crate::event::snapshot::Fmt for PlatformEventLoopStarted<'a> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct("PlatformEventLoopStarted"); + fmt.field("local_address", &self.local_address); + fmt.finish() + } + } impl<'a> Event for PlatformEventLoopStarted<'a> { const NAME: &'static str = "platform:started"; } @@ -7704,7 +8383,10 @@ pub mod testing { event: &api::VersionInformation, ) { self.version_information += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_packet_sent( &mut self, @@ -7712,7 +8394,10 @@ pub mod testing { event: &api::EndpointPacketSent, ) { self.endpoint_packet_sent += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_packet_received( &mut self, @@ -7720,7 +8405,10 @@ pub mod testing { event: &api::EndpointPacketReceived, ) { self.endpoint_packet_received += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_sent( &mut self, @@ -7728,7 +8416,10 @@ pub mod testing { event: &api::EndpointDatagramSent, ) { self.endpoint_datagram_sent += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_received( &mut self, @@ -7736,7 +8427,10 @@ pub mod testing { event: &api::EndpointDatagramReceived, ) { self.endpoint_datagram_received += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_dropped( &mut self, @@ -7744,7 +8438,10 @@ pub mod testing { event: &api::EndpointDatagramDropped, ) { self.endpoint_datagram_dropped += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_connection_attempt_failed( &mut self, @@ -7752,11 +8449,17 @@ pub mod testing { event: &api::EndpointConnectionAttemptFailed, ) { self.endpoint_connection_attempt_failed += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_tx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformTx) { self.platform_tx += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_tx_error( &mut self, @@ -7764,11 +8467,17 @@ pub mod testing { event: &api::PlatformTxError, ) { self.platform_tx_error += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_rx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformRx) { self.platform_rx += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_rx_error( &mut self, @@ -7776,7 +8485,10 @@ pub mod testing { event: &api::PlatformRxError, ) { self.platform_rx_error += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_feature_configured( &mut self, @@ -7784,7 +8496,10 @@ pub mod testing { event: &api::PlatformFeatureConfigured, ) { self.platform_feature_configured += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_wakeup( &mut self, @@ -7792,7 +8507,10 @@ pub mod testing { event: &api::PlatformEventLoopWakeup, ) { self.platform_event_loop_wakeup += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_sleep( &mut self, @@ -7800,7 +8518,10 @@ pub mod testing { event: &api::PlatformEventLoopSleep, ) { self.platform_event_loop_sleep += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_started( &mut self, @@ -7808,7 +8529,10 @@ pub mod testing { event: &api::PlatformEventLoopStarted, ) { self.platform_event_loop_started += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } } @@ -7982,7 +8706,10 @@ pub mod testing { ) { self.application_protocol_information += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_server_name_information( @@ -7993,7 +8720,10 @@ pub mod testing { ) { self.server_name_information += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_packet_skipped( @@ -8004,7 +8734,10 @@ pub mod testing { ) { self.packet_skipped += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_packet_sent( @@ -8015,7 +8748,10 @@ pub mod testing { ) { self.packet_sent += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_packet_received( @@ -8026,7 +8762,10 @@ pub mod testing { ) { self.packet_received += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_active_path_updated( @@ -8037,7 +8776,10 @@ pub mod testing { ) { self.active_path_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_path_created( @@ -8048,7 +8790,10 @@ pub mod testing { ) { self.path_created += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_frame_sent( @@ -8059,7 +8804,10 @@ pub mod testing { ) { self.frame_sent += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_frame_received( @@ -8070,7 +8818,10 @@ pub mod testing { ) { self.frame_received += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_packet_lost( @@ -8081,7 +8832,10 @@ pub mod testing { ) { self.packet_lost += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_recovery_metrics( @@ -8092,7 +8846,10 @@ pub mod testing { ) { self.recovery_metrics += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_congestion( @@ -8103,7 +8860,10 @@ pub mod testing { ) { self.congestion += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } #[allow(deprecated)] @@ -8115,7 +8875,10 @@ pub mod testing { ) { self.ack_processed += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_rx_ack_range_dropped( @@ -8126,7 +8889,10 @@ pub mod testing { ) { self.rx_ack_range_dropped += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_ack_range_received( @@ -8137,7 +8903,10 @@ pub mod testing { ) { self.ack_range_received += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_ack_range_sent( @@ -8148,7 +8917,10 @@ pub mod testing { ) { self.ack_range_sent += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_packet_dropped( @@ -8159,7 +8931,10 @@ pub mod testing { ) { self.packet_dropped += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_key_update( @@ -8170,7 +8945,10 @@ pub mod testing { ) { self.key_update += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_key_space_discarded( @@ -8181,7 +8959,10 @@ pub mod testing { ) { self.key_space_discarded += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_connection_started( @@ -8192,7 +8973,10 @@ pub mod testing { ) { self.connection_started += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_connection_closed( @@ -8203,7 +8987,10 @@ pub mod testing { ) { self.connection_closed += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_duplicate_packet( @@ -8214,7 +9001,10 @@ pub mod testing { ) { self.duplicate_packet += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_transport_parameters_received( @@ -8225,7 +9015,10 @@ pub mod testing { ) { self.transport_parameters_received += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_datagram_sent( @@ -8236,7 +9029,10 @@ pub mod testing { ) { self.datagram_sent += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_datagram_received( @@ -8247,7 +9043,10 @@ pub mod testing { ) { self.datagram_received += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_datagram_dropped( @@ -8258,7 +9057,10 @@ pub mod testing { ) { self.datagram_dropped += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_connection_id_updated( @@ -8269,7 +9071,10 @@ pub mod testing { ) { self.connection_id_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_ecn_state_changed( @@ -8280,7 +9085,10 @@ pub mod testing { ) { self.ecn_state_changed += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_connection_migration_denied( @@ -8291,7 +9099,10 @@ pub mod testing { ) { self.connection_migration_denied += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_handshake_status_updated( @@ -8302,7 +9113,10 @@ pub mod testing { ) { self.handshake_status_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_tls_exporter_ready( @@ -8313,7 +9127,10 @@ pub mod testing { ) { self.tls_exporter_ready += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_path_challenge_updated( @@ -8324,7 +9141,10 @@ pub mod testing { ) { self.path_challenge_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_tls_client_hello( @@ -8335,7 +9155,10 @@ pub mod testing { ) { self.tls_client_hello += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_tls_server_hello( @@ -8346,7 +9169,10 @@ pub mod testing { ) { self.tls_server_hello += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_rx_stream_progress( @@ -8357,7 +9183,10 @@ pub mod testing { ) { self.rx_stream_progress += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_tx_stream_progress( @@ -8368,7 +9197,10 @@ pub mod testing { ) { self.tx_stream_progress += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_keep_alive_timer_expired( @@ -8379,7 +9211,10 @@ pub mod testing { ) { self.keep_alive_timer_expired += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_mtu_updated( @@ -8390,7 +9225,10 @@ pub mod testing { ) { self.mtu_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_slow_start_exited( @@ -8401,7 +9239,10 @@ pub mod testing { ) { self.slow_start_exited += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_delivery_rate_sampled( @@ -8412,7 +9253,10 @@ pub mod testing { ) { self.delivery_rate_sampled += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_pacing_rate_updated( @@ -8423,7 +9267,10 @@ pub mod testing { ) { self.pacing_rate_updated += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_bbr_state_changed( @@ -8434,7 +9281,10 @@ pub mod testing { ) { self.bbr_state_changed += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_dc_state_changed( @@ -8445,7 +9295,10 @@ pub mod testing { ) { self.dc_state_changed += 1; if self.location.is_some() { - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } fn on_version_information( @@ -8454,7 +9307,10 @@ pub mod testing { event: &api::VersionInformation, ) { self.version_information += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_packet_sent( &mut self, @@ -8462,7 +9318,10 @@ pub mod testing { event: &api::EndpointPacketSent, ) { self.endpoint_packet_sent += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_packet_received( &mut self, @@ -8470,7 +9329,10 @@ pub mod testing { event: &api::EndpointPacketReceived, ) { self.endpoint_packet_received += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_sent( &mut self, @@ -8478,7 +9340,10 @@ pub mod testing { event: &api::EndpointDatagramSent, ) { self.endpoint_datagram_sent += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_received( &mut self, @@ -8486,7 +9351,10 @@ pub mod testing { event: &api::EndpointDatagramReceived, ) { self.endpoint_datagram_received += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_datagram_dropped( &mut self, @@ -8494,7 +9362,10 @@ pub mod testing { event: &api::EndpointDatagramDropped, ) { self.endpoint_datagram_dropped += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_endpoint_connection_attempt_failed( &mut self, @@ -8502,23 +9373,38 @@ pub mod testing { event: &api::EndpointConnectionAttemptFailed, ) { self.endpoint_connection_attempt_failed += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_tx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformTx) { self.platform_tx += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_tx_error(&mut self, meta: &api::EndpointMeta, event: &api::PlatformTxError) { self.platform_tx_error += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_rx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformRx) { self.platform_rx += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_rx_error(&mut self, meta: &api::EndpointMeta, event: &api::PlatformRxError) { self.platform_rx_error += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_feature_configured( &mut self, @@ -8526,7 +9412,10 @@ pub mod testing { event: &api::PlatformFeatureConfigured, ) { self.platform_feature_configured += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_wakeup( &mut self, @@ -8534,7 +9423,10 @@ pub mod testing { event: &api::PlatformEventLoopWakeup, ) { self.platform_event_loop_wakeup += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_sleep( &mut self, @@ -8542,7 +9434,10 @@ pub mod testing { event: &api::PlatformEventLoopSleep, ) { self.platform_event_loop_sleep += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } fn on_platform_event_loop_started( &mut self, @@ -8550,7 +9445,10 @@ pub mod testing { event: &api::PlatformEventLoopStarted, ) { self.platform_event_loop_started += 1; - self.output.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output.push(out); } } #[derive(Debug)] @@ -8701,32 +9599,44 @@ pub mod testing { fn on_version_information(&mut self, event: builder::VersionInformation) { self.version_information += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_packet_sent(&mut self, event: builder::EndpointPacketSent) { self.endpoint_packet_sent += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_packet_received(&mut self, event: builder::EndpointPacketReceived) { self.endpoint_packet_received += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_datagram_sent(&mut self, event: builder::EndpointDatagramSent) { self.endpoint_datagram_sent += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_datagram_received(&mut self, event: builder::EndpointDatagramReceived) { self.endpoint_datagram_received += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_datagram_dropped(&mut self, event: builder::EndpointDatagramDropped) { self.endpoint_datagram_dropped += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_endpoint_connection_attempt_failed( &mut self, @@ -8734,47 +9644,65 @@ pub mod testing { ) { self.endpoint_connection_attempt_failed += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_tx(&mut self, event: builder::PlatformTx) { self.platform_tx += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_tx_error(&mut self, event: builder::PlatformTxError) { self.platform_tx_error += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_rx(&mut self, event: builder::PlatformRx) { self.platform_rx += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_rx_error(&mut self, event: builder::PlatformRxError) { self.platform_rx_error += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_feature_configured(&mut self, event: builder::PlatformFeatureConfigured) { self.platform_feature_configured += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_event_loop_wakeup(&mut self, event: builder::PlatformEventLoopWakeup) { self.platform_event_loop_wakeup += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_event_loop_sleep(&mut self, event: builder::PlatformEventLoopSleep) { self.platform_event_loop_sleep += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn on_platform_event_loop_started(&mut self, event: builder::PlatformEventLoopStarted) { self.platform_event_loop_started += 1; let event = event.into_event(); - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } fn quic_version(&self) -> Option { Some(1) @@ -8788,84 +9716,108 @@ pub mod testing { self.application_protocol_information += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_server_name_information(&mut self, event: builder::ServerNameInformation) { self.server_name_information += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_packet_skipped(&mut self, event: builder::PacketSkipped) { self.packet_skipped += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_packet_sent(&mut self, event: builder::PacketSent) { self.packet_sent += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_packet_received(&mut self, event: builder::PacketReceived) { self.packet_received += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_active_path_updated(&mut self, event: builder::ActivePathUpdated) { self.active_path_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_path_created(&mut self, event: builder::PathCreated) { self.path_created += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_frame_sent(&mut self, event: builder::FrameSent) { self.frame_sent += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_frame_received(&mut self, event: builder::FrameReceived) { self.frame_received += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_packet_lost(&mut self, event: builder::PacketLost) { self.packet_lost += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_recovery_metrics(&mut self, event: builder::RecoveryMetrics) { self.recovery_metrics += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_congestion(&mut self, event: builder::Congestion) { self.congestion += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } #[allow(deprecated)] @@ -8873,70 +9825,90 @@ pub mod testing { self.ack_processed += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_rx_ack_range_dropped(&mut self, event: builder::RxAckRangeDropped) { self.rx_ack_range_dropped += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_ack_range_received(&mut self, event: builder::AckRangeReceived) { self.ack_range_received += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_ack_range_sent(&mut self, event: builder::AckRangeSent) { self.ack_range_sent += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_packet_dropped(&mut self, event: builder::PacketDropped) { self.packet_dropped += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_key_update(&mut self, event: builder::KeyUpdate) { self.key_update += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_key_space_discarded(&mut self, event: builder::KeySpaceDiscarded) { self.key_space_discarded += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_connection_started(&mut self, event: builder::ConnectionStarted) { self.connection_started += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_connection_closed(&mut self, event: builder::ConnectionClosed) { self.connection_closed += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_duplicate_packet(&mut self, event: builder::DuplicatePacket) { self.duplicate_packet += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_transport_parameters_received( @@ -8946,147 +9918,189 @@ pub mod testing { self.transport_parameters_received += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_datagram_sent(&mut self, event: builder::DatagramSent) { self.datagram_sent += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_datagram_received(&mut self, event: builder::DatagramReceived) { self.datagram_received += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_datagram_dropped(&mut self, event: builder::DatagramDropped) { self.datagram_dropped += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_connection_id_updated(&mut self, event: builder::ConnectionIdUpdated) { self.connection_id_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_ecn_state_changed(&mut self, event: builder::EcnStateChanged) { self.ecn_state_changed += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_connection_migration_denied(&mut self, event: builder::ConnectionMigrationDenied) { self.connection_migration_denied += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_handshake_status_updated(&mut self, event: builder::HandshakeStatusUpdated) { self.handshake_status_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_tls_exporter_ready(&mut self, event: builder::TlsExporterReady) { self.tls_exporter_ready += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_path_challenge_updated(&mut self, event: builder::PathChallengeUpdated) { self.path_challenge_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_tls_client_hello(&mut self, event: builder::TlsClientHello) { self.tls_client_hello += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_tls_server_hello(&mut self, event: builder::TlsServerHello) { self.tls_server_hello += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_rx_stream_progress(&mut self, event: builder::RxStreamProgress) { self.rx_stream_progress += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_tx_stream_progress(&mut self, event: builder::TxStreamProgress) { self.tx_stream_progress += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_keep_alive_timer_expired(&mut self, event: builder::KeepAliveTimerExpired) { self.keep_alive_timer_expired += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_mtu_updated(&mut self, event: builder::MtuUpdated) { self.mtu_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_slow_start_exited(&mut self, event: builder::SlowStartExited) { self.slow_start_exited += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_delivery_rate_sampled(&mut self, event: builder::DeliveryRateSampled) { self.delivery_rate_sampled += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_pacing_rate_updated(&mut self, event: builder::PacingRateUpdated) { self.pacing_rate_updated += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_bbr_state_changed(&mut self, event: builder::BbrStateChanged) { self.bbr_state_changed += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn on_dc_state_changed(&mut self, event: builder::DcStateChanged) { self.dc_state_changed += 1; let event = event.into_event(); if self.location.is_some() { - self.output.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output.push(out); } } fn quic_version(&self) -> u32 { diff --git a/quic/s2n-quic-core/src/event/snapshot.rs b/quic/s2n-quic-core/src/event/snapshot.rs index 291541bac..2c7ba1258 100644 --- a/quic/s2n-quic-core/src/event/snapshot.rs +++ b/quic/s2n-quic-core/src/event/snapshot.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use core::panic; +use core::{fmt, panic}; use std::path::{Path, PathBuf}; #[derive(Clone, Debug)] @@ -77,3 +77,19 @@ impl Location { .join("snapshots") } } + +pub trait Fmt { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result; + + fn to_snapshot(&self) -> ToSnapshot { + ToSnapshot(self) + } +} + +pub struct ToSnapshot<'a, T: ?Sized>(&'a T); + +impl fmt::Debug for ToSnapshot<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} diff --git a/quic/s2n-quic-events/src/main.rs b/quic/s2n-quic-events/src/main.rs index d424eba00..d5e73dbe0 100644 --- a/quic/s2n-quic-events/src/main.rs +++ b/quic/s2n-quic-events/src/main.rs @@ -7,914 +7,12 @@ use quote::{quote, ToTokens}; type Error = Box; type Result = core::result::Result; +mod output; +mod output_mode; mod parser; -#[derive(Debug, Default)] -enum OutputMode { - Ref, - #[default] - Mut, -} - -impl OutputMode { - fn receiver(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!(mut), - } - } - fn counter_type(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(AtomicU32), - OutputMode::Mut => quote!(u32), - } - } - - fn counter_init(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(AtomicU32::new(0)), - OutputMode::Mut => quote!(0), - } - } - - fn counter_increment(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(.fetch_add(1, Ordering::Relaxed)), - OutputMode::Mut => quote!(+= 1), - } - } - - fn counter_load(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(.load(Ordering::Relaxed)), - OutputMode::Mut => quote!(), - } - } - - fn lock(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(.lock().unwrap()), - OutputMode::Mut => quote!(), - } - } - - fn imports(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!( - use core::sync::atomic::{AtomicU32, Ordering}; - ), - OutputMode::Mut => quote!(), - } - } - - fn mutex(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!( - use std::sync::Mutex; - ), - OutputMode::Mut => quote!(), - } - } - - fn testing_output_type(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(Mutex>), - OutputMode::Mut => quote!(Vec), - } - } - - fn target_crate(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!("s2n_quic_dc"), - OutputMode::Mut => quote!("s2n_quic"), - } - } - - fn trait_constraints(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!('static + Send + Sync), - OutputMode::Mut => quote!('static + Send), - } - } - - fn query_mut(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!( - /// Used for querying and mutating the `Subscriber::ConnectionContext` on a Subscriber - #[inline] - fn query_mut( - context: &mut Self::ConnectionContext, - query: &mut dyn query::QueryMut, - ) -> query::ControlFlow { - query.execute_mut(context) - } - ), - } - } - - fn query_mut_tuple(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!( - #[inline] - fn query_mut( - context: &mut Self::ConnectionContext, - query: &mut dyn query::QueryMut, - ) -> query::ControlFlow { - query - .execute_mut(context) - .and_then(|| A::query_mut(&mut context.0, query)) - .and_then(|| B::query_mut(&mut context.1, query)) - } - ), - } - } - - fn supervisor(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!( - pub mod supervisor { - //! This module contains the `supervisor::Outcome` and `supervisor::Context` for use - //! when implementing [`Subscriber::supervisor_timeout`](crate::event::Subscriber::supervisor_timeout) and - //! [`Subscriber::on_supervisor_timeout`](crate::event::Subscriber::on_supervisor_timeout) - //! on a Subscriber. - - use crate::{ - application, - event::{builder::SocketAddress, IntoEvent}, - }; - - #[non_exhaustive] - #[derive(Clone, Debug, Eq, PartialEq)] - pub enum Outcome { - /// Allow the connection to remain open - Continue, - - /// Close the connection and notify the peer - Close { error_code: application::Error }, - - /// Close the connection without notifying the peer - ImmediateClose { reason: &'static str }, - } - - impl Default for Outcome { - fn default() -> Self { - Self::Continue - } - } - - #[non_exhaustive] - #[derive(Debug)] - pub struct Context<'a> { - /// Number of handshakes that have begun but not completed - pub inflight_handshakes: usize, - - /// Number of open connections - pub connection_count: usize, - - /// The address of the peer - pub remote_address: SocketAddress<'a>, - - /// True if the connection is in the handshake state, false otherwise - pub is_handshaking: bool, - } - - impl<'a> Context<'a> { - pub fn new( - inflight_handshakes: usize, - connection_count: usize, - remote_address: &'a crate::inet::SocketAddress, - is_handshaking: bool, - ) -> Self { - Self { - inflight_handshakes, - connection_count, - remote_address: remote_address.into_event(), - is_handshaking, - } - } - } - } - ), - } - } - - fn supervisor_timeout(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!( - /// The period at which `on_supervisor_timeout` is called - /// - /// If multiple `event::Subscriber`s are composed together, the minimum `supervisor_timeout` - /// across all `event::Subscriber`s will be used. - /// - /// If the `supervisor_timeout()` is `None` across all `event::Subscriber`s, connection supervision - /// will cease for the remaining lifetime of the connection and `on_supervisor_timeout` will no longer - /// be called. - /// - /// It is recommended to avoid setting this value less than ~100ms, as short durations - /// may lead to higher CPU utilization. - #[allow(unused_variables)] - fn supervisor_timeout( - &mut self, - conn_context: &mut Self::ConnectionContext, - meta: &api::ConnectionMeta, - context: &supervisor::Context, - ) -> Option { - None - } - - /// Called for each `supervisor_timeout` to determine any action to take on the connection based on the `supervisor::Outcome` - /// - /// If multiple `event::Subscriber`s are composed together, the minimum `supervisor_timeout` - /// across all `event::Subscriber`s will be used, and thus `on_supervisor_timeout` may be called - /// earlier than the `supervisor_timeout` for a given `event::Subscriber` implementation. - #[allow(unused_variables)] - fn on_supervisor_timeout( - &mut self, - conn_context: &mut Self::ConnectionContext, - meta: &api::ConnectionMeta, - context: &supervisor::Context, - ) -> supervisor::Outcome { - supervisor::Outcome::default() - } - ), - } - } - - fn supervisor_timeout_tuple(&self) -> TokenStream { - match self { - OutputMode::Ref => quote!(), - OutputMode::Mut => quote!( - #[inline] - fn supervisor_timeout( - &mut self, - conn_context: &mut Self::ConnectionContext, - meta: &api::ConnectionMeta, - context: &supervisor::Context, - ) -> Option { - let timeout_a = self - .0 - .supervisor_timeout(&mut conn_context.0, meta, context); - let timeout_b = self - .1 - .supervisor_timeout(&mut conn_context.1, meta, context); - match (timeout_a, timeout_b) { - (None, None) => None, - (None, Some(timeout)) | (Some(timeout), None) => Some(timeout), - (Some(a), Some(b)) => Some(a.min(b)), - } - } - - #[inline] - fn on_supervisor_timeout( - &mut self, - conn_context: &mut Self::ConnectionContext, - meta: &api::ConnectionMeta, - context: &supervisor::Context, - ) -> supervisor::Outcome { - let outcome_a = - self.0 - .on_supervisor_timeout(&mut conn_context.0, meta, context); - let outcome_b = - self.1 - .on_supervisor_timeout(&mut conn_context.1, meta, context); - match (outcome_a, outcome_b) { - (supervisor::Outcome::ImmediateClose { reason }, _) - | (_, supervisor::Outcome::ImmediateClose { reason }) => { - supervisor::Outcome::ImmediateClose { reason } - } - (supervisor::Outcome::Close { error_code }, _) - | (_, supervisor::Outcome::Close { error_code }) => { - supervisor::Outcome::Close { error_code } - } - _ => supervisor::Outcome::Continue, - } - } - ), - } - } -} - -impl ToTokens for OutputMode { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.extend(self.receiver()); - } -} - -#[derive(Debug, Default)] -struct Output { - pub subscriber: TokenStream, - pub endpoint_publisher: TokenStream, - pub endpoint_publisher_subscriber: TokenStream, - pub connection_publisher: TokenStream, - pub connection_publisher_subscriber: TokenStream, - pub tuple_subscriber: TokenStream, - pub tracing_subscriber: TokenStream, - pub tracing_subscriber_attr: TokenStream, - pub tracing_subscriber_def: TokenStream, - pub builders: TokenStream, - pub api: TokenStream, - pub testing_fields: TokenStream, - pub testing_fields_init: TokenStream, - pub subscriber_testing: TokenStream, - pub endpoint_subscriber_testing: TokenStream, - pub endpoint_testing_fields: TokenStream, - pub endpoint_testing_fields_init: TokenStream, - pub endpoint_publisher_testing: TokenStream, - pub connection_publisher_testing: TokenStream, - pub metrics_fields: TokenStream, - pub metrics_fields_init: TokenStream, - pub metrics_record: TokenStream, - pub subscriber_metrics: TokenStream, - pub extra: TokenStream, - pub mode: OutputMode, - pub s2n_quic_core_path: TokenStream, -} - -impl ToTokens for Output { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Output { - subscriber, - endpoint_publisher, - endpoint_publisher_subscriber, - connection_publisher, - connection_publisher_subscriber, - tuple_subscriber, - tracing_subscriber, - tracing_subscriber_attr, - tracing_subscriber_def, - builders, - api, - testing_fields, - testing_fields_init, - subscriber_testing, - endpoint_subscriber_testing, - endpoint_testing_fields, - endpoint_testing_fields_init, - endpoint_publisher_testing, - connection_publisher_testing, - metrics_fields, - metrics_fields_init, - metrics_record, - subscriber_metrics, - extra, - mode, - s2n_quic_core_path, - } = self; - - let imports = self.mode.imports(); - let mutex = self.mode.mutex(); - let testing_output_type = self.mode.testing_output_type(); - let lock = self.mode.lock(); - let target_crate = self.mode.target_crate(); - let supervisor = self.mode.supervisor(); - let supervisor_timeout = self.mode.supervisor_timeout(); - let supervisor_timeout_tuple = self.mode.supervisor_timeout_tuple(); - let query_mut = self.mode.query_mut(); - let query_mut_tuple = self.mode.query_mut_tuple(); - let trait_constraints = self.mode.trait_constraints(); - - tokens.extend(quote!( - use super::*; - - pub mod api { - //! This module contains events that are emitted to the [`Subscriber`](crate::event::Subscriber) - use super::*; - - pub use traits::Subscriber; - - #api - - #extra - } - - #tracing_subscriber_attr - pub mod tracing { - //! This module contains event integration with [`tracing`](https://docs.rs/tracing) - use super::api; - - #tracing_subscriber_def - - impl super::Subscriber for Subscriber { - type ConnectionContext = tracing::Span; - - fn create_connection_context( - &#mode self, - meta: &api::ConnectionMeta, - _info: &api::ConnectionInfo - ) -> Self::ConnectionContext { - let parent = self.parent(meta); - tracing::span!(target: #target_crate, parent: parent, tracing::Level::DEBUG, "conn", id = meta.id) - } - - #tracing_subscriber - } - } - - pub mod builder { - use super::*; - - #builders - } - - #supervisor - - pub use traits::*; - mod traits { - use super::*; - use core::fmt; - use #s2n_quic_core_path::query; - use crate::event::Meta; - - /// Allows for events to be subscribed to - pub trait Subscriber: #trait_constraints { - - /// An application provided type associated with each connection. - /// - /// The context provides a mechanism for applications to provide a custom type - /// and update it on each event, e.g. computing statistics. Each event - /// invocation (e.g. [`Subscriber::on_packet_sent`]) also provides mutable - /// access to the context `&mut ConnectionContext` and allows for updating the - /// context. - /// - /// ```no_run - /// # mod s2n_quic { pub mod provider { pub mod event { - /// # pub use s2n_quic_core::event::{api as events, api::ConnectionInfo, api::ConnectionMeta, Subscriber}; - /// # }}} - /// use s2n_quic::provider::event::{ - /// ConnectionInfo, ConnectionMeta, Subscriber, events::PacketSent - /// }; - /// - /// pub struct MyEventSubscriber; - /// - /// pub struct MyEventContext { - /// packet_sent: u64, - /// } - /// - /// impl Subscriber for MyEventSubscriber { - /// type ConnectionContext = MyEventContext; - /// - /// fn create_connection_context( - /// &mut self, _meta: &ConnectionMeta, - /// _info: &ConnectionInfo, - /// ) -> Self::ConnectionContext { - /// MyEventContext { packet_sent: 0 } - /// } - /// - /// fn on_packet_sent( - /// &mut self, - /// context: &mut Self::ConnectionContext, - /// _meta: &ConnectionMeta, - /// _event: &PacketSent, - /// ) { - /// context.packet_sent += 1; - /// } - /// } - /// ``` - type ConnectionContext: 'static + Send; - - /// Creates a context to be passed to each connection-related event - fn create_connection_context( - &#mode self, - meta: &api::ConnectionMeta, - info: &api::ConnectionInfo - ) -> Self::ConnectionContext; - - #supervisor_timeout - - #subscriber - - /// Called for each event that relates to the endpoint and all connections - #[inline] - fn on_event(&#mode self, meta: &M, event: &E) { - let _ = meta; - let _ = event; - } - - /// Called for each event that relates to a connection - #[inline] - fn on_connection_event( - &#mode self, - context: &#mode Self::ConnectionContext, - meta: &api::ConnectionMeta, - event: &E - ) { - let _ = context; - let _ = meta; - let _ = event; - } - - /// Used for querying the `Subscriber::ConnectionContext` on a Subscriber - #[inline] - fn query(context: &Self::ConnectionContext, query: &mut dyn query::Query) -> query::ControlFlow { - query.execute(context) - } - - #query_mut - } - - /// Subscriber is implemented for a 2-element tuple to make it easy to compose multiple - /// subscribers. - impl Subscriber for (A, B) - where - A: Subscriber, - B: Subscriber, - { - type ConnectionContext = (A::ConnectionContext, B::ConnectionContext); - - #[inline] - fn create_connection_context( - &#mode self, - meta: &api::ConnectionMeta, - info: &api::ConnectionInfo - ) -> Self::ConnectionContext { - (self.0.create_connection_context(meta, info), self.1.create_connection_context(meta, info)) - } - - #supervisor_timeout_tuple - - #tuple_subscriber - - #[inline] - fn on_event(&#mode self, meta: &M, event: &E) { - self.0.on_event(meta, event); - self.1.on_event(meta, event); - } - - #[inline] - fn on_connection_event( - &#mode self, - context: &#mode Self::ConnectionContext, - meta: &api::ConnectionMeta, - event: &E - ) { - self.0.on_connection_event(&#mode context.0, meta, event); - self.1.on_connection_event(&#mode context.1, meta, event); - } - - #[inline] - fn query(context: &Self::ConnectionContext, query: &mut dyn query::Query) -> query::ControlFlow { - query.execute(context) - .and_then(|| A::query(&context.0, query)) - .and_then(|| B::query(&context.1, query)) - } - - #query_mut_tuple - } - - pub trait EndpointPublisher { - #endpoint_publisher - - /// Returns the QUIC version, if any - fn quic_version(&self) -> Option; - } - - pub struct EndpointPublisherSubscriber<'a, Sub: Subscriber> { - meta: api::EndpointMeta, - quic_version: Option, - subscriber: &'a #mode Sub, - } - - impl<'a, Sub: Subscriber> fmt::Debug for EndpointPublisherSubscriber<'a, Sub> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("ConnectionPublisherSubscriber") - .field("meta", &self.meta) - .field("quic_version", &self.quic_version) - .finish() - } - } - - impl<'a, Sub: Subscriber> EndpointPublisherSubscriber<'a, Sub> { - #[inline] - pub fn new( - meta: builder::EndpointMeta, - quic_version: Option, - subscriber: &'a #mode Sub, - ) -> Self { - Self { - meta: meta.into_event(), - quic_version, - subscriber, - } - } - } - - impl<'a, Sub: Subscriber> EndpointPublisher for EndpointPublisherSubscriber<'a, Sub> { - #endpoint_publisher_subscriber - - #[inline] - fn quic_version(&self) -> Option { - self.quic_version - } - } - - pub trait ConnectionPublisher { - #connection_publisher - - /// Returns the QUIC version negotiated for the current connection, if any - fn quic_version(&self) -> u32; - - /// Returns the [`Subject`] for the current publisher - fn subject(&self) -> api::Subject; - } - - pub struct ConnectionPublisherSubscriber<'a, Sub: Subscriber> { - meta: api::ConnectionMeta, - quic_version: u32, - subscriber: &'a #mode Sub, - context: &'a #mode Sub::ConnectionContext, - } - - impl<'a, Sub: Subscriber> fmt::Debug for ConnectionPublisherSubscriber<'a, Sub> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("ConnectionPublisherSubscriber") - .field("meta", &self.meta) - .field("quic_version", &self.quic_version) - .finish() - } - } - - impl<'a, Sub: Subscriber> ConnectionPublisherSubscriber<'a, Sub> { - #[inline] - pub fn new( - meta: builder::ConnectionMeta, - quic_version: u32, - subscriber: &'a #mode Sub, - context: &'a #mode Sub::ConnectionContext - ) -> Self { - Self { - meta: meta.into_event(), - quic_version, - subscriber, - context, - } - } - } - - impl<'a, Sub: Subscriber> ConnectionPublisher for ConnectionPublisherSubscriber<'a, Sub> { - #connection_publisher_subscriber - - #[inline] - fn quic_version(&self) -> u32 { - self.quic_version - } - - #[inline] - fn subject(&self) -> api::Subject { - self.meta.subject() - } - } - } - - pub mod metrics { - use super::*; - #imports - use #s2n_quic_core_path::event::metrics::Recorder; - - #[derive(Debug)] - pub struct Subscriber - where S::ConnectionContext: Recorder { - subscriber: S, - } - - impl Subscriber - where S::ConnectionContext: Recorder { - pub fn new(subscriber: S) -> Self { - Self { subscriber } - } - } - - pub struct Context { - recorder: R, - #metrics_fields - } - - impl super::Subscriber for Subscriber - where S::ConnectionContext: Recorder { - type ConnectionContext = Context; - - fn create_connection_context( - &#mode self, - meta: &api::ConnectionMeta, - info: &api::ConnectionInfo - ) -> Self::ConnectionContext { - Context { - recorder: self.subscriber.create_connection_context(meta, info), - #metrics_fields_init - } - } - - #subscriber_metrics - } - - impl Drop for Context { - fn drop(&mut self) { - #metrics_record - } - } - } - - #[cfg(any(test, feature = "testing"))] - pub mod testing { - use super::*; - use crate::event::snapshot::Location; - #imports - #mutex - - pub mod endpoint { - use super::*; - - pub struct Subscriber { - location: Option, - output: #testing_output_type, - #endpoint_testing_fields - } - - impl Drop for Subscriber { - fn drop(&mut self) { - // don't make any assertions if we're already failing the test - if std::thread::panicking() { - return; - } - - if let Some(location) = self.location.as_ref() { - location.snapshot_log(&self.output #lock); - } - } - } - - impl Subscriber { - /// Creates a subscriber with snapshot assertions enabled - #[track_caller] - pub fn snapshot() -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Location::from_thread_name(); - sub - } - - /// Creates a subscriber with snapshot assertions enabled - #[track_caller] - pub fn named_snapshot(name: Name) -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Some(Location::new(name)); - sub - } - - /// Creates a subscriber with snapshot assertions disabled - pub fn no_snapshot() -> Self { - Self { - location: None, - output: Default::default(), - #endpoint_testing_fields_init - } - } - } - - impl super::super::Subscriber for Subscriber { - type ConnectionContext = (); - - fn create_connection_context( - &#mode self, - _meta: &api::ConnectionMeta, - _info: &api::ConnectionInfo - ) -> Self::ConnectionContext {} - - #endpoint_subscriber_testing - } - } - - #[derive(Debug)] - pub struct Subscriber { - location: Option, - output: #testing_output_type, - #testing_fields - } - - impl Drop for Subscriber { - fn drop(&mut self) { - // don't make any assertions if we're already failing the test - if std::thread::panicking() { - return; - } - - if let Some(location) = self.location.as_ref() { - location.snapshot_log(&self.output #lock); - } - } - } - - impl Subscriber { - /// Creates a subscriber with snapshot assertions enabled - #[track_caller] - pub fn snapshot() -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Location::from_thread_name(); - sub - } - - /// Creates a subscriber with snapshot assertions enabled - #[track_caller] - pub fn named_snapshot(name: Name) -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Some(Location::new(name)); - sub - } - - /// Creates a subscriber with snapshot assertions disabled - pub fn no_snapshot() -> Self { - Self { - location: None, - output: Default::default(), - #testing_fields_init - } - } - } - - impl super::Subscriber for Subscriber { - type ConnectionContext = (); - - fn create_connection_context( - &#mode self, - _meta: &api::ConnectionMeta, - _info: &api::ConnectionInfo - ) -> Self::ConnectionContext {} - - #subscriber_testing - } - - #[derive(Debug)] - pub struct Publisher { - location: Option, - output: #testing_output_type, - #testing_fields - } - - impl Publisher { - /// Creates a publisher with snapshot assertions enabled - #[track_caller] - pub fn snapshot() -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Location::from_thread_name(); - sub - } - - /// Creates a subscriber with snapshot assertions enabled - #[track_caller] - pub fn named_snapshot(name: Name) -> Self { - let mut sub = Self::no_snapshot(); - sub.location = Some(Location::new(name)); - sub - } - - /// Creates a publisher with snapshot assertions disabled - pub fn no_snapshot() -> Self { - Self { - location: None, - output: Default::default(), - #testing_fields_init - } - } - } - - impl super::EndpointPublisher for Publisher { - #endpoint_publisher_testing - - fn quic_version(&self) -> Option { - Some(1) - } - } - - impl super::ConnectionPublisher for Publisher { - #connection_publisher_testing - - fn quic_version(&self) -> u32 { - 1 - } - - fn subject(&self) -> api::Subject { - builder::Subject::Connection { id: 0 }.into_event() - } - } - - impl Drop for Publisher { - fn drop(&mut self) { - // don't make any assertions if we're already failing the test - if std::thread::panicking() { - return; - } - - if let Some(location) = self.location.as_ref() { - location.snapshot_log(&self.output #lock); - } - } - } - } - )); - } -} +use output::Output; +use output_mode::OutputMode; struct EventInfo<'a> { input_path: &'a str, diff --git a/quic/s2n-quic-events/src/output.rs b/quic/s2n-quic-events/src/output.rs new file mode 100644 index 000000000..a203b0e82 --- /dev/null +++ b/quic/s2n-quic-events/src/output.rs @@ -0,0 +1,652 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use crate::OutputMode; +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; + +#[derive(Debug, Default)] +pub struct Output { + pub subscriber: TokenStream, + pub endpoint_publisher: TokenStream, + pub endpoint_publisher_subscriber: TokenStream, + pub connection_publisher: TokenStream, + pub connection_publisher_subscriber: TokenStream, + pub tuple_subscriber: TokenStream, + pub ref_subscriber: TokenStream, + pub tracing_subscriber: TokenStream, + pub tracing_subscriber_attr: TokenStream, + pub tracing_subscriber_def: TokenStream, + pub builders: TokenStream, + pub api: TokenStream, + pub testing_fields: TokenStream, + pub testing_fields_init: TokenStream, + pub subscriber_testing: TokenStream, + pub endpoint_subscriber_testing: TokenStream, + pub endpoint_testing_fields: TokenStream, + pub endpoint_testing_fields_init: TokenStream, + pub endpoint_publisher_testing: TokenStream, + pub connection_publisher_testing: TokenStream, + pub metrics_fields: TokenStream, + pub metrics_fields_init: TokenStream, + pub metrics_record: TokenStream, + pub subscriber_metrics: TokenStream, + pub extra: TokenStream, + pub mode: OutputMode, + pub s2n_quic_core_path: TokenStream, +} + +impl ToTokens for Output { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Output { + subscriber, + endpoint_publisher, + endpoint_publisher_subscriber, + connection_publisher, + connection_publisher_subscriber, + tuple_subscriber, + ref_subscriber, + tracing_subscriber, + tracing_subscriber_attr, + tracing_subscriber_def, + builders, + api, + testing_fields, + testing_fields_init, + subscriber_testing, + endpoint_subscriber_testing, + endpoint_testing_fields, + endpoint_testing_fields_init, + endpoint_publisher_testing, + connection_publisher_testing, + metrics_fields, + metrics_fields_init, + metrics_record, + subscriber_metrics, + extra, + mode, + s2n_quic_core_path, + } = self; + + let imports = self.mode.imports(); + let mutex = self.mode.mutex(); + let testing_output_type = self.mode.testing_output_type(); + let lock = self.mode.lock(); + let target_crate = self.mode.target_crate(); + let supervisor = self.mode.supervisor(); + let supervisor_timeout = self.mode.supervisor_timeout(); + let supervisor_timeout_tuple = self.mode.supervisor_timeout_tuple(); + let query_mut = self.mode.query_mut(); + let query_mut_tuple = self.mode.query_mut_tuple(); + let trait_constraints = self.mode.trait_constraints(); + + let ref_subscriber = self.mode.ref_subscriber(quote!( + type ConnectionContext = T::ConnectionContext; + + #[inline] + fn create_connection_context( + &#mode self, + meta: &api::ConnectionMeta, + info: &api::ConnectionInfo + ) -> Self::ConnectionContext { + self.as_ref().create_connection_context(meta, info) + } + + #ref_subscriber + + #[inline] + fn on_event(&#mode self, meta: &M, event: &E) { + self.as_ref().on_event(meta, event); + } + + #[inline] + fn on_connection_event( + &#mode self, + context: &#mode Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &E + ) { + self.as_ref().on_connection_event(context, meta, event); + } + )); + + tokens.extend(quote!( + use super::*; + + pub mod api { + //! This module contains events that are emitted to the [`Subscriber`](crate::event::Subscriber) + use super::*; + + pub use traits::Subscriber; + + #api + + #extra + } + + #tracing_subscriber_attr + pub mod tracing { + //! This module contains event integration with [`tracing`](https://docs.rs/tracing) + use super::api; + + #tracing_subscriber_def + + impl super::Subscriber for Subscriber { + type ConnectionContext = tracing::Span; + + fn create_connection_context( + &#mode self, + meta: &api::ConnectionMeta, + _info: &api::ConnectionInfo + ) -> Self::ConnectionContext { + let parent = self.parent(meta); + tracing::span!(target: #target_crate, parent: parent, tracing::Level::DEBUG, "conn", id = meta.id) + } + + #tracing_subscriber + } + } + + pub mod builder { + use super::*; + + #builders + } + + #supervisor + + pub use traits::*; + mod traits { + use super::*; + use core::fmt; + use #s2n_quic_core_path::query; + use crate::event::Meta; + + /// Allows for events to be subscribed to + pub trait Subscriber: #trait_constraints { + + /// An application provided type associated with each connection. + /// + /// The context provides a mechanism for applications to provide a custom type + /// and update it on each event, e.g. computing statistics. Each event + /// invocation (e.g. [`Subscriber::on_packet_sent`]) also provides mutable + /// access to the context `&mut ConnectionContext` and allows for updating the + /// context. + /// + /// ```no_run + /// # mod s2n_quic { pub mod provider { pub mod event { + /// # pub use s2n_quic_core::event::{api as events, api::ConnectionInfo, api::ConnectionMeta, Subscriber}; + /// # }}} + /// use s2n_quic::provider::event::{ + /// ConnectionInfo, ConnectionMeta, Subscriber, events::PacketSent + /// }; + /// + /// pub struct MyEventSubscriber; + /// + /// pub struct MyEventContext { + /// packet_sent: u64, + /// } + /// + /// impl Subscriber for MyEventSubscriber { + /// type ConnectionContext = MyEventContext; + /// + /// fn create_connection_context( + /// &mut self, _meta: &ConnectionMeta, + /// _info: &ConnectionInfo, + /// ) -> Self::ConnectionContext { + /// MyEventContext { packet_sent: 0 } + /// } + /// + /// fn on_packet_sent( + /// &mut self, + /// context: &mut Self::ConnectionContext, + /// _meta: &ConnectionMeta, + /// _event: &PacketSent, + /// ) { + /// context.packet_sent += 1; + /// } + /// } + /// ``` + type ConnectionContext: 'static + Send; + + /// Creates a context to be passed to each connection-related event + fn create_connection_context( + &#mode self, + meta: &api::ConnectionMeta, + info: &api::ConnectionInfo + ) -> Self::ConnectionContext; + + #supervisor_timeout + + #subscriber + + /// Called for each event that relates to the endpoint and all connections + #[inline] + fn on_event(&#mode self, meta: &M, event: &E) { + let _ = meta; + let _ = event; + } + + /// Called for each event that relates to a connection + #[inline] + fn on_connection_event( + &#mode self, + context: &#mode Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &E + ) { + let _ = context; + let _ = meta; + let _ = event; + } + + /// Used for querying the `Subscriber::ConnectionContext` on a Subscriber + #[inline] + fn query(context: &Self::ConnectionContext, query: &mut dyn query::Query) -> query::ControlFlow { + query.execute(context) + } + + #query_mut + } + + #ref_subscriber + + /// Subscriber is implemented for a 2-element tuple to make it easy to compose multiple + /// subscribers. + impl Subscriber for (A, B) + where + A: Subscriber, + B: Subscriber, + { + type ConnectionContext = (A::ConnectionContext, B::ConnectionContext); + + #[inline] + fn create_connection_context( + &#mode self, + meta: &api::ConnectionMeta, + info: &api::ConnectionInfo + ) -> Self::ConnectionContext { + (self.0.create_connection_context(meta, info), self.1.create_connection_context(meta, info)) + } + + #supervisor_timeout_tuple + + #tuple_subscriber + + #[inline] + fn on_event(&#mode self, meta: &M, event: &E) { + self.0.on_event(meta, event); + self.1.on_event(meta, event); + } + + #[inline] + fn on_connection_event( + &#mode self, + context: &#mode Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &E + ) { + self.0.on_connection_event(&#mode context.0, meta, event); + self.1.on_connection_event(&#mode context.1, meta, event); + } + + #[inline] + fn query(context: &Self::ConnectionContext, query: &mut dyn query::Query) -> query::ControlFlow { + query.execute(context) + .and_then(|| A::query(&context.0, query)) + .and_then(|| B::query(&context.1, query)) + } + + #query_mut_tuple + } + + pub trait EndpointPublisher { + #endpoint_publisher + + /// Returns the QUIC version, if any + fn quic_version(&self) -> Option; + } + + pub struct EndpointPublisherSubscriber<'a, Sub: Subscriber> { + meta: api::EndpointMeta, + quic_version: Option, + subscriber: &'a #mode Sub, + } + + impl<'a, Sub: Subscriber> fmt::Debug for EndpointPublisherSubscriber<'a, Sub> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ConnectionPublisherSubscriber") + .field("meta", &self.meta) + .field("quic_version", &self.quic_version) + .finish() + } + } + + impl<'a, Sub: Subscriber> EndpointPublisherSubscriber<'a, Sub> { + #[inline] + pub fn new( + meta: builder::EndpointMeta, + quic_version: Option, + subscriber: &'a #mode Sub, + ) -> Self { + Self { + meta: meta.into_event(), + quic_version, + subscriber, + } + } + } + + impl<'a, Sub: Subscriber> EndpointPublisher for EndpointPublisherSubscriber<'a, Sub> { + #endpoint_publisher_subscriber + + #[inline] + fn quic_version(&self) -> Option { + self.quic_version + } + } + + pub trait ConnectionPublisher { + #connection_publisher + + /// Returns the QUIC version negotiated for the current connection, if any + fn quic_version(&self) -> u32; + + /// Returns the [`Subject`] for the current publisher + fn subject(&self) -> api::Subject; + } + + pub struct ConnectionPublisherSubscriber<'a, Sub: Subscriber> { + meta: api::ConnectionMeta, + quic_version: u32, + subscriber: &'a #mode Sub, + context: &'a #mode Sub::ConnectionContext, + } + + impl<'a, Sub: Subscriber> fmt::Debug for ConnectionPublisherSubscriber<'a, Sub> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ConnectionPublisherSubscriber") + .field("meta", &self.meta) + .field("quic_version", &self.quic_version) + .finish() + } + } + + impl<'a, Sub: Subscriber> ConnectionPublisherSubscriber<'a, Sub> { + #[inline] + pub fn new( + meta: builder::ConnectionMeta, + quic_version: u32, + subscriber: &'a #mode Sub, + context: &'a #mode Sub::ConnectionContext + ) -> Self { + Self { + meta: meta.into_event(), + quic_version, + subscriber, + context, + } + } + } + + impl<'a, Sub: Subscriber> ConnectionPublisher for ConnectionPublisherSubscriber<'a, Sub> { + #connection_publisher_subscriber + + #[inline] + fn quic_version(&self) -> u32 { + self.quic_version + } + + #[inline] + fn subject(&self) -> api::Subject { + self.meta.subject() + } + } + } + + pub mod metrics { + use super::*; + #imports + use #s2n_quic_core_path::event::metrics::Recorder; + + #[derive(Debug)] + pub struct Subscriber + where S::ConnectionContext: Recorder { + subscriber: S, + } + + impl Subscriber + where S::ConnectionContext: Recorder { + pub fn new(subscriber: S) -> Self { + Self { subscriber } + } + } + + pub struct Context { + recorder: R, + #metrics_fields + } + + impl super::Subscriber for Subscriber + where S::ConnectionContext: Recorder { + type ConnectionContext = Context; + + fn create_connection_context( + &#mode self, + meta: &api::ConnectionMeta, + info: &api::ConnectionInfo + ) -> Self::ConnectionContext { + Context { + recorder: self.subscriber.create_connection_context(meta, info), + #metrics_fields_init + } + } + + #subscriber_metrics + } + + impl Drop for Context { + fn drop(&mut self) { + #metrics_record + } + } + } + + #[cfg(any(test, feature = "testing"))] + pub mod testing { + use super::*; + use crate::event::snapshot::Location; + #imports + #mutex + + pub mod endpoint { + use super::*; + + pub struct Subscriber { + location: Option, + output: #testing_output_type, + #endpoint_testing_fields + } + + impl Drop for Subscriber { + fn drop(&mut self) { + // don't make any assertions if we're already failing the test + if std::thread::panicking() { + return; + } + + if let Some(location) = self.location.as_ref() { + location.snapshot_log(&self.output #lock); + } + } + } + + impl Subscriber { + /// Creates a subscriber with snapshot assertions enabled + #[track_caller] + pub fn snapshot() -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Location::from_thread_name(); + sub + } + + /// Creates a subscriber with snapshot assertions enabled + #[track_caller] + pub fn named_snapshot(name: Name) -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Some(Location::new(name)); + sub + } + + /// Creates a subscriber with snapshot assertions disabled + pub fn no_snapshot() -> Self { + Self { + location: None, + output: Default::default(), + #endpoint_testing_fields_init + } + } + } + + impl super::super::Subscriber for Subscriber { + type ConnectionContext = (); + + fn create_connection_context( + &#mode self, + _meta: &api::ConnectionMeta, + _info: &api::ConnectionInfo + ) -> Self::ConnectionContext {} + + #endpoint_subscriber_testing + } + } + + #[derive(Debug)] + pub struct Subscriber { + location: Option, + output: #testing_output_type, + #testing_fields + } + + impl Drop for Subscriber { + fn drop(&mut self) { + // don't make any assertions if we're already failing the test + if std::thread::panicking() { + return; + } + + if let Some(location) = self.location.as_ref() { + location.snapshot_log(&self.output #lock); + } + } + } + + impl Subscriber { + /// Creates a subscriber with snapshot assertions enabled + #[track_caller] + pub fn snapshot() -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Location::from_thread_name(); + sub + } + + /// Creates a subscriber with snapshot assertions enabled + #[track_caller] + pub fn named_snapshot(name: Name) -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Some(Location::new(name)); + sub + } + + /// Creates a subscriber with snapshot assertions disabled + pub fn no_snapshot() -> Self { + Self { + location: None, + output: Default::default(), + #testing_fields_init + } + } + } + + impl super::Subscriber for Subscriber { + type ConnectionContext = (); + + fn create_connection_context( + &#mode self, + _meta: &api::ConnectionMeta, + _info: &api::ConnectionInfo + ) -> Self::ConnectionContext {} + + #subscriber_testing + } + + #[derive(Debug)] + pub struct Publisher { + location: Option, + output: #testing_output_type, + #testing_fields + } + + impl Publisher { + /// Creates a publisher with snapshot assertions enabled + #[track_caller] + pub fn snapshot() -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Location::from_thread_name(); + sub + } + + /// Creates a subscriber with snapshot assertions enabled + #[track_caller] + pub fn named_snapshot(name: Name) -> Self { + let mut sub = Self::no_snapshot(); + sub.location = Some(Location::new(name)); + sub + } + + /// Creates a publisher with snapshot assertions disabled + pub fn no_snapshot() -> Self { + Self { + location: None, + output: Default::default(), + #testing_fields_init + } + } + } + + impl super::EndpointPublisher for Publisher { + #endpoint_publisher_testing + + fn quic_version(&self) -> Option { + Some(1) + } + } + + impl super::ConnectionPublisher for Publisher { + #connection_publisher_testing + + fn quic_version(&self) -> u32 { + 1 + } + + fn subject(&self) -> api::Subject { + builder::Subject::Connection { id: 0 }.into_event() + } + } + + impl Drop for Publisher { + fn drop(&mut self) { + // don't make any assertions if we're already failing the test + if std::thread::panicking() { + return; + } + + if let Some(location) = self.location.as_ref() { + location.snapshot_log(&self.output #lock); + } + } + } + } + )); + } +} diff --git a/quic/s2n-quic-events/src/output_mode.rs b/quic/s2n-quic-events/src/output_mode.rs new file mode 100644 index 000000000..b1e283511 --- /dev/null +++ b/quic/s2n-quic-events/src/output_mode.rs @@ -0,0 +1,321 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; + +#[derive(Debug, Default)] +pub enum OutputMode { + Ref, + #[default] + Mut, +} + +impl OutputMode { + pub fn is_ref(&self) -> bool { + matches!(self, Self::Ref) + } + + #[allow(unused)] + pub fn is_mut(&self) -> bool { + matches!(self, Self::Mut) + } + + pub fn receiver(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!(mut), + } + } + + pub fn counter_type(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(AtomicU32), + OutputMode::Mut => quote!(u32), + } + } + + pub fn counter_init(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(AtomicU32::new(0)), + OutputMode::Mut => quote!(0), + } + } + + pub fn counter_increment(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(.fetch_add(1, Ordering::Relaxed)), + OutputMode::Mut => quote!(+= 1), + } + } + + pub fn counter_load(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(.load(Ordering::Relaxed)), + OutputMode::Mut => quote!(), + } + } + + pub fn lock(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(.lock().unwrap()), + OutputMode::Mut => quote!(), + } + } + + pub fn imports(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!( + use core::sync::atomic::{AtomicU32, Ordering}; + ), + OutputMode::Mut => quote!(), + } + } + + pub fn mutex(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!( + use std::sync::Mutex; + ), + OutputMode::Mut => quote!(), + } + } + + pub fn testing_output_type(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(Mutex>), + OutputMode::Mut => quote!(Vec), + } + } + + pub fn target_crate(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!("s2n_quic_dc"), + OutputMode::Mut => quote!("s2n_quic"), + } + } + + pub fn trait_constraints(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!('static + Send + Sync), + OutputMode::Mut => quote!('static + Send), + } + } + + pub fn query_mut(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!( + /// Used for querying and mutating the `Subscriber::ConnectionContext` on a Subscriber + #[inline] + fn query_mut( + context: &mut Self::ConnectionContext, + query: &mut dyn query::QueryMut, + ) -> query::ControlFlow { + query.execute_mut(context) + } + ), + } + } + + pub fn query_mut_tuple(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!( + #[inline] + fn query_mut( + context: &mut Self::ConnectionContext, + query: &mut dyn query::QueryMut, + ) -> query::ControlFlow { + query + .execute_mut(context) + .and_then(|| A::query_mut(&mut context.0, query)) + .and_then(|| B::query_mut(&mut context.1, query)) + } + ), + } + } + + pub fn supervisor(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!( + pub mod supervisor { + //! This module contains the `supervisor::Outcome` and `supervisor::Context` for use + //! when implementing [`Subscriber::supervisor_timeout`](crate::event::Subscriber::supervisor_timeout) and + //! [`Subscriber::on_supervisor_timeout`](crate::event::Subscriber::on_supervisor_timeout) + //! on a Subscriber. + + use crate::{ + application, + event::{builder::SocketAddress, IntoEvent}, + }; + + #[non_exhaustive] + #[derive(Clone, Debug, Eq, PartialEq)] + pub enum Outcome { + /// Allow the connection to remain open + Continue, + + /// Close the connection and notify the peer + Close { error_code: application::Error }, + + /// Close the connection without notifying the peer + ImmediateClose { reason: &'static str }, + } + + impl Default for Outcome { + fn default() -> Self { + Self::Continue + } + } + + #[non_exhaustive] + #[derive(Debug)] + pub struct Context<'a> { + /// Number of handshakes that have begun but not completed + pub inflight_handshakes: usize, + + /// Number of open connections + pub connection_count: usize, + + /// The address of the peer + pub remote_address: SocketAddress<'a>, + + /// True if the connection is in the handshake state, false otherwise + pub is_handshaking: bool, + } + + impl<'a> Context<'a> { + pub fn new( + inflight_handshakes: usize, + connection_count: usize, + remote_address: &'a crate::inet::SocketAddress, + is_handshaking: bool, + ) -> Self { + Self { + inflight_handshakes, + connection_count, + remote_address: remote_address.into_event(), + is_handshaking, + } + } + } + } + ), + } + } + + pub fn supervisor_timeout(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!( + /// The period at which `on_supervisor_timeout` is called + /// + /// If multiple `event::Subscriber`s are composed together, the minimum `supervisor_timeout` + /// across all `event::Subscriber`s will be used. + /// + /// If the `supervisor_timeout()` is `None` across all `event::Subscriber`s, connection supervision + /// will cease for the remaining lifetime of the connection and `on_supervisor_timeout` will no longer + /// be called. + /// + /// It is recommended to avoid setting this value less than ~100ms, as short durations + /// may lead to higher CPU utilization. + #[allow(unused_variables)] + fn supervisor_timeout( + &mut self, + conn_context: &mut Self::ConnectionContext, + meta: &api::ConnectionMeta, + context: &supervisor::Context, + ) -> Option { + None + } + + /// Called for each `supervisor_timeout` to determine any action to take on the connection based on the `supervisor::Outcome` + /// + /// If multiple `event::Subscriber`s are composed together, the minimum `supervisor_timeout` + /// across all `event::Subscriber`s will be used, and thus `on_supervisor_timeout` may be called + /// earlier than the `supervisor_timeout` for a given `event::Subscriber` implementation. + #[allow(unused_variables)] + fn on_supervisor_timeout( + &mut self, + conn_context: &mut Self::ConnectionContext, + meta: &api::ConnectionMeta, + context: &supervisor::Context, + ) -> supervisor::Outcome { + supervisor::Outcome::default() + } + ), + } + } + + pub fn supervisor_timeout_tuple(&self) -> TokenStream { + match self { + OutputMode::Ref => quote!(), + OutputMode::Mut => quote!( + #[inline] + fn supervisor_timeout( + &mut self, + conn_context: &mut Self::ConnectionContext, + meta: &api::ConnectionMeta, + context: &supervisor::Context, + ) -> Option { + let timeout_a = self + .0 + .supervisor_timeout(&mut conn_context.0, meta, context); + let timeout_b = self + .1 + .supervisor_timeout(&mut conn_context.1, meta, context); + match (timeout_a, timeout_b) { + (None, None) => None, + (None, Some(timeout)) | (Some(timeout), None) => Some(timeout), + (Some(a), Some(b)) => Some(a.min(b)), + } + } + + #[inline] + fn on_supervisor_timeout( + &mut self, + conn_context: &mut Self::ConnectionContext, + meta: &api::ConnectionMeta, + context: &supervisor::Context, + ) -> supervisor::Outcome { + let outcome_a = + self.0 + .on_supervisor_timeout(&mut conn_context.0, meta, context); + let outcome_b = + self.1 + .on_supervisor_timeout(&mut conn_context.1, meta, context); + match (outcome_a, outcome_b) { + (supervisor::Outcome::ImmediateClose { reason }, _) + | (_, supervisor::Outcome::ImmediateClose { reason }) => { + supervisor::Outcome::ImmediateClose { reason } + } + (supervisor::Outcome::Close { error_code }, _) + | (_, supervisor::Outcome::Close { error_code }) => { + supervisor::Outcome::Close { error_code } + } + _ => supervisor::Outcome::Continue, + } + } + ), + } + } + + pub fn ref_subscriber(&self, inner: TokenStream) -> TokenStream { + match self { + OutputMode::Ref => quote!( + impl Subscriber for std::sync::Arc { + #inner + } + ), + OutputMode::Mut => quote!(), + } + } +} + +impl ToTokens for OutputMode { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.extend(self.receiver()); + } +} diff --git a/quic/s2n-quic-events/src/parser.rs b/quic/s2n-quic-events/src/parser.rs index 12317f74a..08472e945 100644 --- a/quic/s2n-quic-events/src/parser.rs +++ b/quic/s2n-quic-events/src/parser.rs @@ -72,6 +72,7 @@ impl Struct { generics, fields, } = self; + let ident_str = ident.to_string(); let derive_attrs = &attrs.derive_attrs; let builder_derive_attrs = &attrs.builder_derive_attrs; @@ -83,6 +84,7 @@ impl Struct { let builder_fields = fields.iter().map(Field::builder); let builder_field_impls = fields.iter().map(Field::builder_impl); let api_fields = fields.iter().map(Field::api); + let snapshot_fields = fields.iter().map(Field::snapshot); if attrs.builder_derive { output.builders.extend(quote!( @@ -128,6 +130,16 @@ impl Struct { pub struct #ident #generics { #(#api_fields)* } + + #[cfg(any(test, feature = "testing"))] + #allow_deprecated + impl #generics crate::event::snapshot::Fmt for #ident #generics { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + let mut fmt = fmt.debug_struct(#ident_str); + #(#snapshot_fields)* + fmt.finish() + } + } )); if let Some(event_name) = attrs.event_name.as_ref() { @@ -186,6 +198,16 @@ impl Struct { } )); + if output.mode.is_ref() { + output.ref_subscriber.extend(quote!( + #[inline] + #allow_deprecated + fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) { + self.as_ref().#function(meta, event); + } + )); + } + output.tracing_subscriber.extend(quote!( #[inline] #allow_deprecated @@ -219,7 +241,10 @@ impl Struct { #allow_deprecated fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) { self.#counter #counter_increment; - self.output #lock.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output #lock.push(out); } )); } @@ -237,7 +262,9 @@ impl Struct { fn #function(&#receiver self, event: builder::#ident) { self.#counter #counter_increment; let event = event.into_event(); - self.output #lock.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output #lock.push(out); } )); } @@ -273,6 +300,21 @@ impl Struct { } )); + if output.mode.is_ref() { + output.ref_subscriber.extend(quote!( + #[inline] + #allow_deprecated + fn #function( + &#receiver self, + context: &#receiver Self::ConnectionContext, + meta: &api::ConnectionMeta, + event: &api::#ident + ) { + self.as_ref().#function(context, meta, event); + } + )); + } + output.tracing_subscriber.extend(quote!( #[inline] #allow_deprecated @@ -340,7 +382,10 @@ impl Struct { ) { self.#counter #counter_increment; if self.location.is_some() { - self.output #lock.push(format!("{meta:?} {event:?}")); + let meta = crate::event::snapshot::Fmt::to_snapshot(meta); + let event = crate::event::snapshot::Fmt::to_snapshot(event); + let out = format!("{meta:?} {event:?}"); + self.output #lock.push(out); } } )); @@ -351,7 +396,9 @@ impl Struct { self.#counter #counter_increment; let event = event.into_event(); if self.location.is_some() { - self.output #lock.push(format!("{event:?}")); + let event = crate::event::snapshot::Fmt::to_snapshot(&event); + let out = format!("{event:?}"); + self.output #lock.push(out); } } )); @@ -602,6 +649,17 @@ impl Field { } } + fn snapshot(&self) -> TokenStream { + let Self { attrs, ident, .. } = self; + let ident = ident.as_ref().expect("all events should have field names"); + let ident_str = ident.to_string(); + if let Some(expr) = attrs.snapshot.as_ref() { + quote!(fmt.field(#ident_str, &#expr);) + } else { + quote!(fmt.field(#ident_str, &self.#ident);) + } + } + fn builder_impl(&self) -> TokenStream { let Self { ident, .. } = self; quote!(#ident: #ident.into_event(),) @@ -619,6 +677,7 @@ impl Field { #[derive(Debug)] struct FieldAttrs { builder: Option, + snapshot: Option, extra: TokenStream, } @@ -627,12 +686,15 @@ impl FieldAttrs { let mut v = Self { // The event can override the builder with a specific type builder: None, + snapshot: None, extra: quote!(), }; for attr in attrs { if attr.path().is_ident("builder") { v.builder = Some(attr.parse_args().unwrap()); + } else if attr.path().is_ident("snapshot") { + v.snapshot = Some(attr.parse_args().unwrap()); } else { attr.to_tokens(&mut v.extra) }