Skip to content

Commit fa2e663

Browse files
events: add ConnectionCloseFrameReceived event (#2436)
* create new ConnectionCloseFrameReceived event * fix typo * add helper method and debug to print reason as UTF-8 * put behind alloc feature * PR feedback * add cfg_attr * trying again * trying again
1 parent ac52a48 commit fa2e663

16 files changed

Lines changed: 1047 additions & 658 deletions

quic/s2n-quic-core/events/common.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,51 @@ impl<'a> IntoEvent<builder::Frame> for &crate::frame::DcStatelessResetTokens<'a>
581581
}
582582
}
583583

584+
#[derive(Clone)]
585+
struct ConnectionCloseFrame<'a> {
586+
error_code: u64,
587+
frame_type: Option<u64>,
588+
reason: Option<&'a [u8]>,
589+
}
590+
591+
#[cfg(feature = "alloc")]
592+
impl<'a> ConnectionCloseFrame<'a> {
593+
/// Converts the reason to a UTF-8 `str`, including invalid characters
594+
pub fn reason_lossy_utf8(&self) -> Option<alloc::borrow::Cow<'a, str>> {
595+
self.reason
596+
.map(|reason| alloc::string::String::from_utf8_lossy(reason))
597+
}
598+
}
599+
600+
impl<'a> IntoEvent<builder::ConnectionCloseFrame<'a>> for &crate::frame::ConnectionClose<'a> {
601+
#[inline]
602+
fn into_event(self) -> builder::ConnectionCloseFrame<'a> {
603+
builder::ConnectionCloseFrame {
604+
error_code: self.error_code.as_u64(),
605+
frame_type: self.frame_type.into_event(),
606+
reason: self.reason.into_event(),
607+
}
608+
}
609+
}
610+
611+
#[cfg(feature = "alloc")]
612+
impl<'a> core::fmt::Debug for ConnectionCloseFrame<'a> {
613+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
614+
f.debug_struct("ConnectionCloseFrame")
615+
.field("error_code", &self.error_code)
616+
.field("frame_type", &self.frame_type)
617+
.field("reason", &self.reason_lossy_utf8())
618+
.finish()
619+
}
620+
}
621+
622+
#[cfg(not(feature = "alloc"))]
623+
impl<'a> core::fmt::Debug for ConnectionCloseFrame<'a> {
624+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
625+
write!(f, "{:?}", self)
626+
}
627+
}
628+
584629
enum StreamType {
585630
Bidirectional,
586631
Unidirectional,

quic/s2n-quic-core/events/connection.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ struct FrameReceived<'a> {
8787
frame: Frame,
8888
}
8989

90+
/// A `CONNECTION_CLOSE` frame was received
91+
///
92+
/// This event includes additional details from the frame, particularly the
93+
/// reason (if provided) the peer closed the connection
94+
#[event("transport:connection_close_frame_received")]
95+
struct ConnectionCloseFrameReceived<'a> {
96+
#[nominal_counter("packet")]
97+
packet_header: PacketHeader,
98+
path: Path<'a>,
99+
frame: ConnectionCloseFrame<'a>,
100+
}
101+
90102
#[event("recovery:packet_lost")]
91103
//= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.4.5
92104
/// Packet was lost

quic/s2n-quic-core/src/event/generated.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,23 @@ pub mod api {
202202
fmt.finish()
203203
}
204204
}
205+
#[non_exhaustive]
206+
#[derive(Clone)]
207+
pub struct ConnectionCloseFrame<'a> {
208+
pub error_code: u64,
209+
pub frame_type: Option<u64>,
210+
pub reason: Option<&'a [u8]>,
211+
}
212+
#[cfg(any(test, feature = "testing"))]
213+
impl<'a> crate::event::snapshot::Fmt for ConnectionCloseFrame<'a> {
214+
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
215+
let mut fmt = fmt.debug_struct("ConnectionCloseFrame");
216+
fmt.field("error_code", &self.error_code);
217+
fmt.field("frame_type", &self.frame_type);
218+
fmt.field("reason", &self.reason);
219+
fmt.finish()
220+
}
221+
}
205222
#[derive(Clone, Debug)]
206223
#[non_exhaustive]
207224
pub struct MtuConfig {
@@ -1923,6 +1940,30 @@ pub mod api {
19231940
}
19241941
#[derive(Clone, Debug)]
19251942
#[non_exhaustive]
1943+
#[doc = " A `CONNECTION_CLOSE` frame was received"]
1944+
#[doc = ""]
1945+
#[doc = " This event includes additional details from the frame, particularly the"]
1946+
#[doc = " reason (if provided) the peer closed the connection"]
1947+
pub struct ConnectionCloseFrameReceived<'a> {
1948+
pub packet_header: PacketHeader,
1949+
pub path: Path<'a>,
1950+
pub frame: ConnectionCloseFrame<'a>,
1951+
}
1952+
#[cfg(any(test, feature = "testing"))]
1953+
impl<'a> crate::event::snapshot::Fmt for ConnectionCloseFrameReceived<'a> {
1954+
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
1955+
let mut fmt = fmt.debug_struct("ConnectionCloseFrameReceived");
1956+
fmt.field("packet_header", &self.packet_header);
1957+
fmt.field("path", &self.path);
1958+
fmt.field("frame", &self.frame);
1959+
fmt.finish()
1960+
}
1961+
}
1962+
impl<'a> Event for ConnectionCloseFrameReceived<'a> {
1963+
const NAME: &'static str = "transport:connection_close_frame_received";
1964+
}
1965+
#[derive(Clone, Debug)]
1966+
#[non_exhaustive]
19261967
#[doc = " Packet was lost"]
19271968
pub struct PacketLost<'a> {
19281969
pub packet_header: PacketHeader,
@@ -3353,6 +3394,40 @@ pub mod api {
33533394
builder::Frame::DcStatelessResetTokens {}
33543395
}
33553396
}
3397+
#[cfg(feature = "alloc")]
3398+
impl<'a> ConnectionCloseFrame<'a> {
3399+
#[doc = " Converts the reason to a UTF-8 `str`, including invalid characters"]
3400+
pub fn reason_lossy_utf8(&self) -> Option<alloc::borrow::Cow<'a, str>> {
3401+
self.reason
3402+
.map(|reason| alloc::string::String::from_utf8_lossy(reason))
3403+
}
3404+
}
3405+
impl<'a> IntoEvent<builder::ConnectionCloseFrame<'a>> for &crate::frame::ConnectionClose<'a> {
3406+
#[inline]
3407+
fn into_event(self) -> builder::ConnectionCloseFrame<'a> {
3408+
builder::ConnectionCloseFrame {
3409+
error_code: self.error_code.as_u64(),
3410+
frame_type: self.frame_type.into_event(),
3411+
reason: self.reason.into_event(),
3412+
}
3413+
}
3414+
}
3415+
#[cfg(feature = "alloc")]
3416+
impl<'a> core::fmt::Debug for ConnectionCloseFrame<'a> {
3417+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3418+
f.debug_struct("ConnectionCloseFrame")
3419+
.field("error_code", &self.error_code)
3420+
.field("frame_type", &self.frame_type)
3421+
.field("reason", &self.reason_lossy_utf8())
3422+
.finish()
3423+
}
3424+
}
3425+
#[cfg(not(feature = "alloc"))]
3426+
impl<'a> core::fmt::Debug for ConnectionCloseFrame<'a> {
3427+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3428+
write!(f, "{:?}", self)
3429+
}
3430+
}
33563431
impl IntoEvent<builder::StreamType> for &crate::stream::StreamType {
33573432
#[inline]
33583433
fn into_event(self) -> builder::StreamType {
@@ -3601,6 +3676,21 @@ pub mod tracing {
36013676
tracing :: event ! (target : "frame_received" , parent : id , tracing :: Level :: DEBUG , { packet_header = tracing :: field :: debug (packet_header) , path = tracing :: field :: debug (path) , frame = tracing :: field :: debug (frame) });
36023677
}
36033678
#[inline]
3679+
fn on_connection_close_frame_received(
3680+
&mut self,
3681+
context: &mut Self::ConnectionContext,
3682+
_meta: &api::ConnectionMeta,
3683+
event: &api::ConnectionCloseFrameReceived,
3684+
) {
3685+
let id = context.id();
3686+
let api::ConnectionCloseFrameReceived {
3687+
packet_header,
3688+
path,
3689+
frame,
3690+
} = event;
3691+
tracing :: event ! (target : "connection_close_frame_received" , parent : id , tracing :: Level :: DEBUG , { packet_header = tracing :: field :: debug (packet_header) , path = tracing :: field :: debug (path) , frame = tracing :: field :: debug (frame) });
3692+
}
3693+
#[inline]
36043694
fn on_packet_lost(
36053695
&mut self,
36063696
context: &mut Self::ConnectionContext,
@@ -4411,6 +4501,27 @@ pub mod builder {
44114501
}
44124502
}
44134503
#[derive(Clone, Debug)]
4504+
pub struct ConnectionCloseFrame<'a> {
4505+
pub error_code: u64,
4506+
pub frame_type: Option<u64>,
4507+
pub reason: Option<&'a [u8]>,
4508+
}
4509+
impl<'a> IntoEvent<api::ConnectionCloseFrame<'a>> for ConnectionCloseFrame<'a> {
4510+
#[inline]
4511+
fn into_event(self) -> api::ConnectionCloseFrame<'a> {
4512+
let ConnectionCloseFrame {
4513+
error_code,
4514+
frame_type,
4515+
reason,
4516+
} = self;
4517+
api::ConnectionCloseFrame {
4518+
error_code: error_code.into_event(),
4519+
frame_type: frame_type.into_event(),
4520+
reason: reason.into_event(),
4521+
}
4522+
}
4523+
}
4524+
#[derive(Clone, Debug)]
44144525
pub struct MtuConfig {
44154526
pub initial_mtu: u16,
44164527
pub base_mtu: u16,
@@ -5480,6 +5591,31 @@ pub mod builder {
54805591
}
54815592
}
54825593
#[derive(Clone, Debug)]
5594+
#[doc = " A `CONNECTION_CLOSE` frame was received"]
5595+
#[doc = ""]
5596+
#[doc = " This event includes additional details from the frame, particularly the"]
5597+
#[doc = " reason (if provided) the peer closed the connection"]
5598+
pub struct ConnectionCloseFrameReceived<'a> {
5599+
pub packet_header: PacketHeader,
5600+
pub path: Path<'a>,
5601+
pub frame: ConnectionCloseFrame<'a>,
5602+
}
5603+
impl<'a> IntoEvent<api::ConnectionCloseFrameReceived<'a>> for ConnectionCloseFrameReceived<'a> {
5604+
#[inline]
5605+
fn into_event(self) -> api::ConnectionCloseFrameReceived<'a> {
5606+
let ConnectionCloseFrameReceived {
5607+
packet_header,
5608+
path,
5609+
frame,
5610+
} = self;
5611+
api::ConnectionCloseFrameReceived {
5612+
packet_header: packet_header.into_event(),
5613+
path: path.into_event(),
5614+
frame: frame.into_event(),
5615+
}
5616+
}
5617+
}
5618+
#[derive(Clone, Debug)]
54835619
#[doc = " Packet was lost"]
54845620
pub struct PacketLost<'a> {
54855621
pub packet_header: PacketHeader,
@@ -6699,6 +6835,18 @@ mod traits {
66996835
let _ = meta;
67006836
let _ = event;
67016837
}
6838+
#[doc = "Called when the `ConnectionCloseFrameReceived` event is triggered"]
6839+
#[inline]
6840+
fn on_connection_close_frame_received(
6841+
&mut self,
6842+
context: &mut Self::ConnectionContext,
6843+
meta: &api::ConnectionMeta,
6844+
event: &api::ConnectionCloseFrameReceived,
6845+
) {
6846+
let _ = context;
6847+
let _ = meta;
6848+
let _ = event;
6849+
}
67026850
#[doc = "Called when the `PacketLost` event is triggered"]
67036851
#[inline]
67046852
fn on_packet_lost(
@@ -7432,6 +7580,16 @@ mod traits {
74327580
(self.1).on_frame_received(&mut context.1, meta, event);
74337581
}
74347582
#[inline]
7583+
fn on_connection_close_frame_received(
7584+
&mut self,
7585+
context: &mut Self::ConnectionContext,
7586+
meta: &api::ConnectionMeta,
7587+
event: &api::ConnectionCloseFrameReceived,
7588+
) {
7589+
(self.0).on_connection_close_frame_received(&mut context.0, meta, event);
7590+
(self.1).on_connection_close_frame_received(&mut context.1, meta, event);
7591+
}
7592+
#[inline]
74357593
fn on_packet_lost(
74367594
&mut self,
74377595
context: &mut Self::ConnectionContext,
@@ -8121,6 +8279,11 @@ mod traits {
81218279
fn on_frame_sent(&mut self, event: builder::FrameSent);
81228280
#[doc = "Publishes a `FrameReceived` event to the publisher's subscriber"]
81238281
fn on_frame_received(&mut self, event: builder::FrameReceived);
8282+
#[doc = "Publishes a `ConnectionCloseFrameReceived` event to the publisher's subscriber"]
8283+
fn on_connection_close_frame_received(
8284+
&mut self,
8285+
event: builder::ConnectionCloseFrameReceived,
8286+
);
81248287
#[doc = "Publishes a `PacketLost` event to the publisher's subscriber"]
81258288
fn on_packet_lost(&mut self, event: builder::PacketLost);
81268289
#[doc = "Publishes a `RecoveryMetrics` event to the publisher's subscriber"]
@@ -8310,6 +8473,18 @@ mod traits {
83108473
self.subscriber.on_event(&self.meta, &event);
83118474
}
83128475
#[inline]
8476+
fn on_connection_close_frame_received(
8477+
&mut self,
8478+
event: builder::ConnectionCloseFrameReceived,
8479+
) {
8480+
let event = event.into_event();
8481+
self.subscriber
8482+
.on_connection_close_frame_received(self.context, &self.meta, &event);
8483+
self.subscriber
8484+
.on_connection_event(self.context, &self.meta, &event);
8485+
self.subscriber.on_event(&self.meta, &event);
8486+
}
8487+
#[inline]
83138488
fn on_packet_lost(&mut self, event: builder::PacketLost) {
83148489
let event = event.into_event();
83158490
self.subscriber
@@ -8882,6 +9057,7 @@ pub mod testing {
88829057
pub path_created: u64,
88839058
pub frame_sent: u64,
88849059
pub frame_received: u64,
9060+
pub connection_close_frame_received: u64,
88859061
pub packet_lost: u64,
88869062
pub recovery_metrics: u64,
88879063
pub congestion: u64,
@@ -8971,6 +9147,7 @@ pub mod testing {
89719147
path_created: 0,
89729148
frame_sent: 0,
89739149
frame_received: 0,
9150+
connection_close_frame_received: 0,
89749151
packet_lost: 0,
89759152
recovery_metrics: 0,
89769153
congestion: 0,
@@ -9157,6 +9334,20 @@ pub mod testing {
91579334
self.output.push(out);
91589335
}
91599336
}
9337+
fn on_connection_close_frame_received(
9338+
&mut self,
9339+
_context: &mut Self::ConnectionContext,
9340+
meta: &api::ConnectionMeta,
9341+
event: &api::ConnectionCloseFrameReceived,
9342+
) {
9343+
self.connection_close_frame_received += 1;
9344+
if self.location.is_some() {
9345+
let meta = crate::event::snapshot::Fmt::to_snapshot(meta);
9346+
let event = crate::event::snapshot::Fmt::to_snapshot(event);
9347+
let out = format!("{meta:?} {event:?}");
9348+
self.output.push(out);
9349+
}
9350+
}
91609351
fn on_packet_lost(
91619352
&mut self,
91629353
_context: &mut Self::ConnectionContext,
@@ -9797,6 +9988,7 @@ pub mod testing {
97979988
pub path_created: u64,
97989989
pub frame_sent: u64,
97999990
pub frame_received: u64,
9991+
pub connection_close_frame_received: u64,
98009992
pub packet_lost: u64,
98019993
pub recovery_metrics: u64,
98029994
pub congestion: u64,
@@ -9876,6 +10068,7 @@ pub mod testing {
987610068
path_created: 0,
987710069
frame_sent: 0,
987810070
frame_received: 0,
10071+
connection_close_frame_received: 0,
987910072
packet_lost: 0,
988010073
recovery_metrics: 0,
988110074
congestion: 0,
@@ -10126,6 +10319,18 @@ pub mod testing {
1012610319
self.output.push(out);
1012710320
}
1012810321
}
10322+
fn on_connection_close_frame_received(
10323+
&mut self,
10324+
event: builder::ConnectionCloseFrameReceived,
10325+
) {
10326+
self.connection_close_frame_received += 1;
10327+
let event = event.into_event();
10328+
if self.location.is_some() {
10329+
let event = crate::event::snapshot::Fmt::to_snapshot(&event);
10330+
let out = format!("{event:?}");
10331+
self.output.push(out);
10332+
}
10333+
}
1012910334
fn on_packet_lost(&mut self, event: builder::PacketLost) {
1013010335
self.packet_lost += 1;
1013110336
let event = event.into_event();

0 commit comments

Comments
 (0)