Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

events: adding detail to DatagramDropped event #2438

Merged
merged 4 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion quic/s2n-quic-core/events/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,11 @@ struct DatagramReceived {
#[event("transport:datagram_dropped")]
//= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.12
/// Datagram dropped by a connection
struct DatagramDropped {
struct DatagramDropped<'a> {
local_addr: SocketAddress<'a>,
remote_addr: SocketAddress<'a>,
destination_cid: ConnectionId<'a>,
source_cid: Option<ConnectionId<'a>>,
#[measure("bytes", Bytes)]
#[counter("bytes.total", Bytes)]
len: u16,
Expand Down
48 changes: 39 additions & 9 deletions quic/s2n-quic-core/src/event/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2289,20 +2289,28 @@ pub mod api {
#[derive(Clone, Debug)]
#[non_exhaustive]
#[doc = " Datagram dropped by a connection"]
pub struct DatagramDropped {
pub struct DatagramDropped<'a> {
pub local_addr: SocketAddress<'a>,
pub remote_addr: SocketAddress<'a>,
pub destination_cid: ConnectionId<'a>,
pub source_cid: Option<ConnectionId<'a>>,
pub len: u16,
pub reason: DatagramDropReason,
}
#[cfg(any(test, feature = "testing"))]
impl crate::event::snapshot::Fmt for DatagramDropped {
impl<'a> crate::event::snapshot::Fmt for DatagramDropped<'a> {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
let mut fmt = fmt.debug_struct("DatagramDropped");
fmt.field("local_addr", &self.local_addr);
fmt.field("remote_addr", &self.remote_addr);
fmt.field("destination_cid", &self.destination_cid);
fmt.field("source_cid", &self.source_cid);
fmt.field("len", &self.len);
fmt.field("reason", &self.reason);
fmt.finish()
}
}
impl Event for DatagramDropped {
impl<'a> Event for DatagramDropped<'a> {
const NAME: &'static str = "transport:datagram_dropped";
}
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -3902,8 +3910,15 @@ pub mod tracing {
event: &api::DatagramDropped,
) {
let id = context.id();
let api::DatagramDropped { len, reason } = event;
tracing :: event ! (target : "datagram_dropped" , parent : id , tracing :: Level :: DEBUG , { len = tracing :: field :: debug (len) , reason = tracing :: field :: debug (reason) });
let api::DatagramDropped {
local_addr,
remote_addr,
destination_cid,
source_cid,
len,
reason,
} = event;
tracing :: event ! (target : "datagram_dropped" , parent : id , tracing :: Level :: DEBUG , { local_addr = tracing :: field :: debug (local_addr) , remote_addr = tracing :: field :: debug (remote_addr) , destination_cid = tracing :: field :: debug (destination_cid) , source_cid = tracing :: field :: debug (source_cid) , len = tracing :: field :: debug (len) , reason = tracing :: field :: debug (reason) });
}
#[inline]
fn on_connection_id_updated(
Expand Down Expand Up @@ -5931,15 +5946,30 @@ pub mod builder {
}
#[derive(Clone, Debug)]
#[doc = " Datagram dropped by a connection"]
pub struct DatagramDropped {
pub struct DatagramDropped<'a> {
pub local_addr: SocketAddress<'a>,
pub remote_addr: SocketAddress<'a>,
pub destination_cid: ConnectionId<'a>,
pub source_cid: Option<ConnectionId<'a>>,
pub len: u16,
pub reason: DatagramDropReason,
}
impl IntoEvent<api::DatagramDropped> for DatagramDropped {
impl<'a> IntoEvent<api::DatagramDropped<'a>> for DatagramDropped<'a> {
#[inline]
fn into_event(self) -> api::DatagramDropped {
let DatagramDropped { len, reason } = self;
fn into_event(self) -> api::DatagramDropped<'a> {
let DatagramDropped {
local_addr,
remote_addr,
destination_cid,
source_cid,
len,
reason,
} = self;
api::DatagramDropped {
local_addr: local_addr.into_event(),
remote_addr: remote_addr.into_event(),
destination_cid: destination_cid.into_event(),
source_cid: source_cid.into_event(),
len: len.into_event(),
reason: reason.into_event(),
}
Expand Down
7 changes: 7 additions & 0 deletions quic/s2n-quic-transport/src/endpoint/initial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ impl<Config: endpoint::Config> endpoint::Endpoint<Config> {
endpoint_context.event_subscriber,
|publisher, _path| {
publisher.on_datagram_dropped(event::builder::DatagramDropped {
local_addr: header.path.local_address().into_event(),
remote_addr: header.path.remote_address().into_event(),
destination_cid: datagram.destination_connection_id.into_event(),
source_cid: datagram
.source_connection_id
.as_ref()
.map(|cid| cid.into_event()),
len: datagram.payload_len as u16,
reason: err,
});
Expand Down
9 changes: 9 additions & 0 deletions quic/s2n-quic-transport/src/endpoint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,15 @@ impl<Cfg: Config> Endpoint<Cfg> {
endpoint_context.event_subscriber,
|publisher, _path| {
publisher.on_datagram_dropped(event::builder::DatagramDropped {
local_addr: header.path.local_address().into_event(),
remote_addr: header.path.remote_address().into_event(),
destination_cid: datagram
.destination_connection_id
.into_event(),
source_cid: datagram
.source_connection_id
.as_ref()
.map(|cid| cid.into_event()),
len: datagram.payload_len as u16,
reason: datagram_drop_reason,
});
Expand Down
70 changes: 69 additions & 1 deletion quic/s2n-quic/src/tests/connection_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use super::*;
use s2n_codec::DecoderBufferMut;
use s2n_quic_core::{
event::api::Subject,
event::api::{DatagramDropReason, Subject},
packet::interceptor::{Datagram, Interceptor},
};

Expand Down Expand Up @@ -218,3 +218,71 @@ fn port_rebind_test() {
fn ip_and_port_rebind_test() {
run_test(|addr| rebind_ip(rebind_port(addr)));
}

// Changes the port of the second datagram received
#[derive(Default)]
struct RebindPortBeforeHandshakeConfirmed {
datagram_count: usize,
changed_port: bool,
}

const REBIND_PORT: u16 = 55555;
impl Interceptor for RebindPortBeforeHandshakeConfirmed {
fn intercept_rx_remote_port(&mut self, _subject: &Subject, port: &mut u16) {
if self.datagram_count == 1 && !self.changed_port {
*port = REBIND_PORT;
self.changed_port = true;
}
}

fn intercept_rx_datagram<'a>(
&mut self,
_subject: &Subject,
_datagram: &Datagram,
payload: DecoderBufferMut<'a>,
) -> DecoderBufferMut<'a> {
self.datagram_count += 1;
payload
}
}

/// Ensures that a datagram received from a client that changes
/// its port before the handshake is confirmed is dropped.
#[test]
fn rebind_before_handshake_confirmed() {
let model = Model::default();
let subscriber = recorder::DatagramDropped::new();
let datagram_dropped_events = subscriber.events();

test(model, move |handle| {
let server = Server::builder()
.with_io(handle.builder().build()?)?
.with_tls(SERVER_CERTS)?
.with_event((tracing_events(), subscriber))?
.with_random(Random::with_seed(456))?
.with_packet_interceptor(RebindPortBeforeHandshakeConfirmed::default())?
.start()?;

let client = Client::builder()
.with_io(handle.builder().build()?)?
.with_tls(certificates::CERT_PEM)?
.with_event(tracing_events())?
.with_random(Random::with_seed(456))?
.start()?;

let addr = start_server(server)?;
start_client(client, addr, Data::new(1000))?;
Ok(addr)
})
.unwrap();

let datagram_dropped_events = datagram_dropped_events.lock().unwrap();

assert_eq!(1, datagram_dropped_events.len());
let event = datagram_dropped_events.first().unwrap();
assert!(matches!(
event.reason,
DatagramDropReason::ConnectionMigrationDuringHandshake { .. },
));
assert_eq!(REBIND_PORT, event.remote_addr.port());
}
25 changes: 25 additions & 0 deletions quic/s2n-quic/src/tests/recorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,28 @@ event_recorder!(
storage.push(addr);
}
);

use s2n_quic_core::event::api::DatagramDropReason;
pub struct DatagramDroppedEvent {
pub remote_addr: SocketAddr,
pub reason: DatagramDropReason,
}

impl<'a> From<&events::DatagramDropped<'a>> for DatagramDroppedEvent {
fn from(value: &events::DatagramDropped<'a>) -> Self {
DatagramDroppedEvent {
remote_addr: value.remote_addr.to_string().parse().unwrap(),
reason: value.reason.clone(),
}
}
}

event_recorder!(
DatagramDropped,
DatagramDropped,
on_datagram_dropped,
DatagramDroppedEvent,
|event: &events::DatagramDropped, storage: &mut Vec<DatagramDroppedEvent>| {
storage.push(event.into());
}
);
Loading