Skip to content

Commit

Permalink
feat(s2n-quic-core): updates to dc provider (#2244)
Browse files Browse the repository at this point in the history
  • Loading branch information
WesleyRosenblum authored Jun 11, 2024
1 parent c93f74a commit 7a06121
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 23 deletions.
9 changes: 8 additions & 1 deletion quic/s2n-quic-core/src/dc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

use crate::{
connection::Limits,
event::{api::SocketAddress, IntoEvent as _},
event::{
api::{EndpointType, SocketAddress},
IntoEvent as _,
},
inet,
path::MaxMtu,
transport::parameters::{DcSupportedVersions, InitialFlowControlLimits},
Expand Down Expand Up @@ -47,6 +50,8 @@ pub struct ConnectionInfo<'a> {
pub dc_version: u32,
/// Various settings relevant to the dc path
pub application_params: ApplicationParams,
/// The local endpoint type (client or server)
pub endpoint_type: EndpointType,
}

impl<'a> ConnectionInfo<'a> {
Expand All @@ -56,11 +61,13 @@ impl<'a> ConnectionInfo<'a> {
remote_address: &'a inet::SocketAddress,
dc_version: Version,
application_params: ApplicationParams,
endpoint_type: EndpointType,
) -> Self {
Self {
remote_address: remote_address.into_event(),
dc_version,
application_params,
endpoint_type,
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions quic/s2n-quic-core/src/dc/disabled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use crate::{
crypto::tls::TlsSession,
dc::{ConnectionInfo, Endpoint, Path},
stateless_reset,
stateless_reset, transport,
};
use alloc::vec::Vec;

Expand All @@ -23,7 +23,10 @@ impl Endpoint for Disabled {

// The Disabled Endpoint returns `None`, so this is not used
impl Path for () {
fn on_path_secrets_ready(&mut self, _session: &impl TlsSession) -> Vec<stateless_reset::Token> {
fn on_path_secrets_ready(
&mut self,
_session: &impl TlsSession,
) -> Result<Vec<stateless_reset::Token>, transport::Error> {
unimplemented!()
}

Expand Down
9 changes: 6 additions & 3 deletions quic/s2n-quic-core/src/dc/testing.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use crate::{crypto::tls::TlsSession, dc, dc::ConnectionInfo, stateless_reset};
use crate::{crypto::tls::TlsSession, dc, dc::ConnectionInfo, stateless_reset, transport};

pub struct MockDcEndpoint {
stateless_reset_tokens: Vec<stateless_reset::Token>,
Expand Down Expand Up @@ -35,9 +35,12 @@ impl dc::Endpoint for MockDcEndpoint {
}

impl dc::Path for MockDcPath {
fn on_path_secrets_ready(&mut self, _session: &impl TlsSession) -> Vec<stateless_reset::Token> {
fn on_path_secrets_ready(
&mut self,
_session: &impl TlsSession,
) -> Result<Vec<stateless_reset::Token>, transport::Error> {
self.on_path_secrets_ready_count += 1;
self.stateless_reset_tokens.clone()
Ok(self.stateless_reset_tokens.clone())
}

fn on_peer_stateless_reset_tokens<'a>(
Expand Down
14 changes: 10 additions & 4 deletions quic/s2n-quic-core/src/dc/traits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use crate::{crypto::tls::TlsSession, dc, stateless_reset};
use crate::{crypto::tls::TlsSession, dc, stateless_reset, transport};
use alloc::vec::Vec;

/// The `dc::Endpoint` trait provides a way to support dc functionality
Expand All @@ -25,7 +25,10 @@ pub trait Path: 'static + Send {
///
/// Returns the stateless reset tokens to include in a `DC_STATELESS_RESET_TOKENS`
/// frame sent to the peer.
fn on_path_secrets_ready(&mut self, session: &impl TlsSession) -> Vec<stateless_reset::Token>;
fn on_path_secrets_ready(
&mut self,
session: &impl TlsSession,
) -> Result<Vec<stateless_reset::Token>, transport::Error>;

/// Called when a `DC_STATELESS_RESET_TOKENS` frame has been received from the peer
fn on_peer_stateless_reset_tokens<'a>(
Expand All @@ -36,11 +39,14 @@ pub trait Path: 'static + Send {

impl<P: Path> Path for Option<P> {
#[inline]
fn on_path_secrets_ready(&mut self, session: &impl TlsSession) -> Vec<stateless_reset::Token> {
fn on_path_secrets_ready(
&mut self,
session: &impl TlsSession,
) -> Result<Vec<stateless_reset::Token>, transport::Error> {
if let Some(path) = self {
path.on_path_secrets_ready(session)
} else {
Vec::default()
Ok(Vec::default())
}
}

Expand Down
15 changes: 11 additions & 4 deletions quic/s2n-quic-transport/src/dc/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use s2n_quic_core::{
state::{event, is},
stateless_reset, transmission,
transmission::interest::Query,
transport,
};

/// Manages transmission and receipt of `DC_STATELESS_RESET_TOKENS` and
Expand Down Expand Up @@ -117,10 +118,14 @@ impl<Config: endpoint::Config> Manager<Config> {
&mut self,
session: &impl tls::TlsSession,
publisher: &mut Pub,
) {
ensure!(self.state.on_path_secrets_ready().is_ok());
) -> Result<(), transport::Error> {
ensure!(self.path.is_some(), Ok(()));
ensure!(
self.state.on_path_secrets_ready().is_ok(),
Err(transport::Error::INTERNAL_ERROR)
);

let tokens = self.path.on_path_secrets_ready(session);
let tokens = self.path.on_path_secrets_ready(session)?;
let flag = Flag::new(DcStatelessResetTokenWriter::new(tokens));
self.stateless_reset_token_sync = flag;

Expand All @@ -134,7 +139,9 @@ impl<Config: endpoint::Config> Manager<Config> {

publisher.on_dc_state_changed(DcStateChanged {
state: DcState::PathSecretsReady,
})
});

Ok(())
}

/// Called when a `DC_STATELESS_RESET_TOKENS` frame is received from the peer
Expand Down
26 changes: 20 additions & 6 deletions quic/s2n-quic-transport/src/dc/manager/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ fn disabled() {

// verify calling all the methods doesn't panic
manager.on_peer_dc_stateless_reset_tokens([TEST_TOKEN_1].iter(), &mut publisher);
manager.on_path_secrets_ready(&Session, &mut publisher);
assert!(manager
.on_path_secrets_ready(&Session, &mut publisher)
.is_ok());
manager.on_packet_ack(ack_set, &mut publisher);
manager.on_packet_loss(ack_set);
manager.on_transmit(&mut context);
Expand All @@ -73,7 +75,9 @@ fn on_path_secrets_ready() {
let path = MockDcPath::default();
let mut manager: Manager<Server> = Manager::new(Some(path), 1, &mut publisher);

manager.on_path_secrets_ready(&Session, &mut publisher);
assert!(manager
.on_path_secrets_ready(&Session, &mut publisher)
.is_ok());

assert_eq!(1, manager.path().on_path_secrets_ready_count);
assert!(manager.state.is_path_secrets_ready());
Expand All @@ -83,12 +87,20 @@ fn on_path_secrets_ready() {
let path = MockDcPath::default();
let mut manager: Manager<Client> = Manager::new(Some(path), 1, &mut publisher);

manager.on_path_secrets_ready(&Session, &mut publisher);
assert!(manager
.on_path_secrets_ready(&Session, &mut publisher)
.is_ok());

assert_eq!(1, manager.path().on_path_secrets_ready_count);
assert!(manager.state.is_path_secrets_ready());
// Client starts transmitting as soon as path secrets are ready
assert!(manager.has_transmission_interest());

// Calling on_path_secrets_ready again results in an internal error
assert_eq!(
manager.on_path_secrets_ready(&Session, &mut publisher),
Err(transport::Error::INTERNAL_ERROR)
);
}

#[test]
Expand Down Expand Up @@ -125,7 +137,7 @@ fn on_peer_dc_stateless_reset_tokens<Config, Endpoint>(
assert!(manager.path().peer_stateless_reset_tokens.is_empty());

// Now path secrets are ready, so the peer tokens are received
manager.on_path_secrets_ready(&Session, publisher);
assert!(manager.on_path_secrets_ready(&Session, publisher).is_ok());

manager.on_peer_dc_stateless_reset_tokens(tokens.iter(), publisher);

Expand Down Expand Up @@ -193,7 +205,7 @@ fn on_packet_ack<Config, Endpoint>(
);
let pn = context.packet_number();

manager.on_path_secrets_ready(&Session, publisher);
assert!(manager.on_path_secrets_ready(&Session, publisher).is_ok());

if Config::ENDPOINT_TYPE.is_server() {
// Receive tokens on the server to trigger sending
Expand Down Expand Up @@ -241,7 +253,9 @@ fn on_packet_loss() {
);
let pn = context.packet_number();

manager.on_path_secrets_ready(&Session, &mut publisher);
assert!(manager
.on_path_secrets_ready(&Session, &mut publisher)
.is_ok());
assert!(manager.has_transmission_interest());

manager.on_transmit(&mut context);
Expand Down
10 changes: 7 additions & 3 deletions quic/s2n-quic-transport/src/space/session_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,12 @@ impl<'a, Config: endpoint::Config, Pub: event::ConnectionPublisher>
let application_params =
dc::ApplicationParams::new(max_mtu, &peer_flow_control_limits, self.limits);
let remote_address = self.path_manager.active_path().remote_address().0;
let conn_info =
dc::ConnectionInfo::new(&remote_address, dc_version, application_params);
let conn_info = dc::ConnectionInfo::new(
&remote_address,
dc_version,
application_params,
Config::ENDPOINT_TYPE.into_event(),
);
let dc_path = self.dc.new_path(&conn_info);
crate::dc::Manager::new(dc_path, dc_version, self.publisher)
} else {
Expand Down Expand Up @@ -511,7 +515,7 @@ impl<'a, Config: endpoint::Config, Pub: event::ConnectionPublisher>
.as_mut()
.expect("application keys should be ready before the tls exporter")
.dc_manager
.on_path_secrets_ready(session, self.publisher);
.on_path_secrets_ready(session, self.publisher)?;

self.publisher
.on_tls_exporter_ready(event::builder::TlsExporterReady {
Expand Down

0 comments on commit 7a06121

Please sign in to comment.