Skip to content
Open
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
16 changes: 11 additions & 5 deletions quic/s2n-quic-core/events/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ impl From<&SocketAddress<'_>> for core::net::SocketAddr {
}
}

impl IntoEvent<crate::inet::SocketAddress> for &crate::inet::SocketAddress {
#[inline]
fn into_event(self) -> crate::inet::SocketAddress {
*self
}
}

enum DuplicatePacketError {
/// The packet number was already received and is a duplicate.
Duplicate,
Expand Down Expand Up @@ -777,11 +784,10 @@ enum DatagramDropReason {
InvalidMtuConfiguration {
/// MTU configuration for the endpoint
endpoint_mtu_config: MtuConfig,
// TODO expose connection level mtu config.
// TODO expose the remote address.
// https://github.com/aws/s2n-quic/issues/2254
// error from mtu::Config
// remote_addr: SocketAddress<'a>,
/// The connection-specific MTU configuration that was invalid
conn_mtu_config: MtuConfig,
/// The remote address that caused the MTU configuration error
remote_addr: crate::inet::SocketAddress,
},
/// The Destination Connection Id is unknown and does not map to a Connection.
///
Expand Down
18 changes: 18 additions & 0 deletions quic/s2n-quic-core/src/event/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,10 @@ pub mod api {
InvalidMtuConfiguration {
#[doc = " MTU configuration for the endpoint"]
endpoint_mtu_config: MtuConfig,
#[doc = " The connection-specific MTU configuration that was invalid"]
conn_mtu_config: MtuConfig,
#[doc = " The remote address that caused the MTU configuration error"]
remote_addr: crate::inet::SocketAddress,
},
#[non_exhaustive]
#[doc = " The Destination Connection Id is unknown and does not map to a Connection."]
Expand Down Expand Up @@ -3357,6 +3361,12 @@ pub mod api {
}
}
}
impl IntoEvent<crate::inet::SocketAddress> for &crate::inet::SocketAddress {
#[inline]
fn into_event(self) -> crate::inet::SocketAddress {
*self
}
}
impl IntoEvent<builder::DuplicatePacketError> for crate::packet::number::SlidingWindowError {
#[inline]
fn into_event(self) -> builder::DuplicatePacketError {
Expand Down Expand Up @@ -5223,6 +5233,10 @@ pub mod builder {
InvalidMtuConfiguration {
#[doc = " MTU configuration for the endpoint"]
endpoint_mtu_config: MtuConfig,
#[doc = " The connection-specific MTU configuration that was invalid"]
conn_mtu_config: MtuConfig,
#[doc = " The remote address that caused the MTU configuration error"]
remote_addr: crate::inet::SocketAddress,
},
#[doc = " The Destination Connection Id is unknown and does not map to a Connection."]
#[doc = ""]
Expand Down Expand Up @@ -5260,8 +5274,12 @@ pub mod builder {
Self::InvalidSourceConnectionId => InvalidSourceConnectionId {},
Self::InvalidMtuConfiguration {
endpoint_mtu_config,
conn_mtu_config,
remote_addr,
} => InvalidMtuConfiguration {
endpoint_mtu_config: endpoint_mtu_config.into_event(),
conn_mtu_config: conn_mtu_config.into_event(),
remote_addr: remote_addr.into_event(),
},
Self::UnknownDestinationConnectionId => UnknownDestinationConnectionId {},
Self::RejectedConnectionAttempt => RejectedConnectionAttempt {},
Expand Down
49 changes: 43 additions & 6 deletions quic/s2n-quic-core/src/path/mtu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const MINIMUM_MTU: u16 = MINIMUM_MAX_DATAGRAM_SIZE

macro_rules! impl_mtu {
($name:ident, $default:expr) => {
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct $name(NonZeroU16);

impl $name {
Expand Down Expand Up @@ -242,6 +242,29 @@ impl Display for MtuError {

impl core::error::Error for MtuError {}

/// Error returned when runtime MTU configuration validation fails
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MtuConfigError {
/// The remote address for which the configuration was requested
pub remote_addr: inet::SocketAddress,
/// The connection-specific MTU config that was invalid
pub conn_config: Config,
/// The endpoint's MTU config for comparison
pub endpoint_config: Config,
}

impl Display for MtuConfigError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"Invalid MTU configuration for {}: conn_config={:?}, endpoint_config={:?}",
self.remote_addr, self.conn_config, self.endpoint_config
)
}
}

impl core::error::Error for MtuConfigError {}

/// Information about the path that may be used when generating MTU configuration.
#[non_exhaustive]
pub struct PathInfo<'a> {
Expand Down Expand Up @@ -275,13 +298,27 @@ impl<E: mtu::Endpoint> Manager<E> {
}
}

pub fn config(&mut self, remote_address: &inet::SocketAddress) -> Result<Config, MtuError> {
pub fn config(
&mut self,
remote_address: &inet::SocketAddress,
) -> Result<Config, MtuConfigError> {
let info = mtu::PathInfo::new(remote_address);
if let Some(conn_config) = self.provider.on_path(&info, self.endpoint_mtu_config) {
ensure!(conn_config.is_valid(), Err(MtuError));
ensure!(
u16::from(conn_config.max_mtu) <= u16::from(self.endpoint_mtu_config.max_mtu()),
Err(MtuError)
conn_config.is_valid(),
Err(MtuConfigError {
remote_addr: *remote_address,
conn_config,
endpoint_config: self.endpoint_mtu_config,
})
);
ensure!(
conn_config.max_mtu <= self.endpoint_mtu_config.max_mtu(),
Err(MtuConfigError {
remote_addr: *remote_address,
conn_config,
endpoint_config: self.endpoint_mtu_config,
})
);

Ok(conn_config)
Expand Down Expand Up @@ -327,7 +364,7 @@ impl Endpoint for Inherit {
}

/// MTU configuration.
#[derive(Copy, Clone, Debug, Default)]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct Config {
initial_mtu: InitialMtu,
base_mtu: BaseMtu,
Expand Down
12 changes: 10 additions & 2 deletions quic/s2n-quic-core/src/path/mtu/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ fn mtu_manager() {
};
assert!(!mtu_provider.is_valid());
let mut manager: Manager<Config> = Manager::new(mtu_provider);
assert_eq!(manager.config(&remote).unwrap_err(), MtuError);
let err = manager.config(&remote).unwrap_err();
assert_eq!(err.remote_addr, remote);
assert_eq!(err.conn_config, mtu_provider);
assert_eq!(err.endpoint_config, Default::default());

// invalid: mtu_provider.max_mtu > endpoint_config.max_mtu
let mtu_provider = mtu::Config::builder()
Expand All @@ -161,7 +164,12 @@ fn mtu_manager() {
.unwrap();
assert!(mtu_provider.is_valid());
let mut manager: Manager<Config> = Manager::new(mtu_provider);
assert_eq!(manager.config(&remote).unwrap_err(), MtuError);
let err = manager.config(&remote).unwrap_err();
assert_eq!(err.remote_addr, remote);
assert_eq!(err.conn_config, mtu_provider);
assert_eq!(err.endpoint_config, Default::default());
// Verify it's the "exceeds endpoint max" case
assert!(err.conn_config.max_mtu() > err.endpoint_config.max_mtu());
}

#[test]
Expand Down
6 changes: 4 additions & 2 deletions quic/s2n-quic-transport/src/path/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,9 +416,11 @@ impl<Config: endpoint::Config> Manager<Config> {
.rtt_estimator
.for_new_path(limits.initial_round_trip_time());

let mtu_config = mtu.config(&remote_address).map_err(|_err| {
let mtu_config = mtu.config(&remote_address).map_err(|err| {
event::builder::DatagramDropReason::InvalidMtuConfiguration {
endpoint_mtu_config: mtu.endpoint_config().into_event(),
endpoint_mtu_config: err.endpoint_config.into_event(),
conn_mtu_config: err.conn_config.into_event(),
remote_addr: err.remote_addr.into_event(),
}
})?;

Expand Down
Loading