Skip to content

Commit 73a8142

Browse files
Merge pull request from GHSA-rfhg-rjfp-9q8q
* fix(s2n-quic-transport): close connection when no available connection ids * allow all connection migrations when testing * add generator to stateless reset token * fix partial eq impl for connection IDs * add new connection ID to fuzz test * implement hash and fix merge issues * Impl PartialOrd and Ord * PR feedback * clippy
1 parent 6ea5851 commit 73a8142

File tree

8 files changed

+150
-210
lines changed

8 files changed

+150
-210
lines changed

quic/s2n-quic-core/src/connection/id.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub const MAX_LIFETIME: Duration = Duration::from_secs(24 * 60 * 60); // one day
3535
macro_rules! id {
3636
($type:ident, $min_len:expr) => {
3737
/// Uniquely identifies a QUIC connection between 2 peers
38-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
38+
#[derive(Copy, Clone, Eq)]
3939
#[cfg_attr(any(feature = "generator", test), derive(TypeGenerator))]
4040
pub struct $type {
4141
bytes: [u8; MAX_LEN],
@@ -49,6 +49,30 @@ macro_rules! id {
4949
}
5050
}
5151

52+
impl PartialEq for $type {
53+
fn eq(&self, other: &Self) -> bool {
54+
self.as_bytes() == other.as_bytes()
55+
}
56+
}
57+
58+
impl core::hash::Hash for $type {
59+
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
60+
self.as_bytes().hash(state);
61+
}
62+
}
63+
64+
impl PartialOrd for $type {
65+
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
66+
Some(self.cmp(other))
67+
}
68+
}
69+
70+
impl Ord for $type {
71+
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
72+
self.as_bytes().cmp(&other.as_bytes())
73+
}
74+
}
75+
5276
impl $type {
5377
/// The minimum length for this connection ID type
5478
pub const MIN_LEN: usize = $min_len;

quic/s2n-quic-core/src/path/migration.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,18 @@ pub mod disabled {
219219
}
220220
}
221221
}
222+
223+
#[cfg(any(test, feature = "testing"))]
224+
pub mod allow_all {
225+
use super::*;
226+
227+
#[derive(Debug, Default)]
228+
pub struct Validator;
229+
230+
impl super::Validator for Validator {
231+
fn on_migration_attempt(&mut self, _attempt: &Attempt) -> Outcome {
232+
// allow all migration attempts
233+
Outcome::Allow
234+
}
235+
}
236+
}

quic/s2n-quic-core/src/stateless_reset/token.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ pub const LEN: usize = 128 / 8;
2020
// Hash can still be derived.
2121
#[allow(clippy::derived_hash_with_manual_eq)]
2222
#[derive(Copy, Clone, Debug, Eq, Hash)]
23+
#[cfg_attr(
24+
any(test, feature = "generator"),
25+
derive(bolero_generator::TypeGenerator)
26+
)]
2327
pub struct Token([u8; LEN]);
2428

2529
impl Token {

quic/s2n-quic-transport/src/endpoint/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ pub mod testing {
11721172
type StreamManager = crate::stream::DefaultStreamManager;
11731173
type ConnectionCloseFormatter = s2n_quic_core::connection::close::Development;
11741174
type EventSubscriber = Subscriber;
1175-
type PathMigrationValidator = path::migration::default::Validator;
1175+
type PathMigrationValidator = path::migration::allow_all::Validator;
11761176
type PacketInterceptor = s2n_quic_core::packet::interceptor::Disabled;
11771177
type DatagramEndpoint = s2n_quic_core::datagram::Disabled;
11781178

@@ -1202,7 +1202,7 @@ pub mod testing {
12021202
type StreamManager = crate::stream::DefaultStreamManager;
12031203
type ConnectionCloseFormatter = s2n_quic_core::connection::close::Development;
12041204
type EventSubscriber = Subscriber;
1205-
type PathMigrationValidator = path::migration::default::Validator;
1205+
type PathMigrationValidator = path::migration::allow_all::Validator;
12061206
type PacketInterceptor = s2n_quic_core::packet::interceptor::Disabled;
12071207
type DatagramEndpoint = s2n_quic_core::datagram::Disabled;
12081208

quic/s2n-quic-transport/src/path/manager.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -705,11 +705,10 @@ impl<Config: endpoint::Config> Manager<Config> {
705705
active_path_connection_id,
706706
publisher,
707707
)
708-
.expect(
709-
"since we are only checking the active path and new id was delivered \
710-
via the new_connection_id frames, there will always be a new id available \
711-
to consume if necessary",
712-
);
708+
.ok_or(transport::Error::PROTOCOL_VIOLATION.with_reason(
709+
"A NEW_CONNECTION_ID frame was received that retired the active path's \
710+
connection ID and no unused connection IDs remain to replace it",
711+
))?
713712
}
714713

715714
Ok(())

0 commit comments

Comments
 (0)