diff --git a/quic/s2n-quic-core/src/crypto/tls.rs b/quic/s2n-quic-core/src/crypto/tls.rs index 3da543aa9e..00c68ebd06 100644 --- a/quic/s2n-quic-core/src/crypto/tls.rs +++ b/quic/s2n-quic-core/src/crypto/tls.rs @@ -5,7 +5,7 @@ use alloc::vec::Vec; #[cfg(feature = "alloc")] pub use bytes::{Bytes, BytesMut}; -use core::fmt::Debug; +use core::{any::Any, fmt::Debug}; use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned}; mod error; @@ -130,6 +130,8 @@ pub trait Context { //# peer's Finished message. fn on_handshake_complete(&mut self) -> Result<(), crate::transport::Error>; + /// Transfer application context from TLS connection to quic connection + fn on_application_context(&mut self, _context: Option>); fn on_tls_exporter_ready( &mut self, session: &impl TlsSession, diff --git a/quic/s2n-quic-core/src/crypto/tls/testing.rs b/quic/s2n-quic-core/src/crypto/tls/testing.rs index 9f09d32ddf..a48b6369c9 100644 --- a/quic/s2n-quic-core/src/crypto/tls/testing.rs +++ b/quic/s2n-quic-core/src/crypto/tls/testing.rs @@ -808,4 +808,6 @@ where fn waker(&self) -> &Waker { &self.waker } + + fn on_application_context(&mut self, _context: Option>) {} } diff --git a/quic/s2n-quic-tls/src/session.rs b/quic/s2n-quic-tls/src/session.rs index b73f71f7fb..79db908e24 100644 --- a/quic/s2n-quic-tls/src/session.rs +++ b/quic/s2n-quic-tls/src/session.rs @@ -16,6 +16,7 @@ use s2n_tls::{ enums::{Blinding, Mode}, error::{Error, ErrorType}, }; +use std::any::Any; #[derive(Debug)] pub struct Session { @@ -155,6 +156,10 @@ impl tls::Session for Session { context.on_tls_exporter_ready(self)?; self.handshake_complete = true; } + // TODO Add new s2n-tls new api, take and put in quic::connection + let ctx: Option> = + self.connection.take_application_context(); + context.on_application_context(ctx); Poll::Ready(Ok(())) } Poll::Ready(Err(e)) => Poll::Ready(Err(e diff --git a/quic/s2n-quic-transport/src/connection/api_provider.rs b/quic/s2n-quic-transport/src/connection/api_provider.rs index e84da7105f..023e004a84 100644 --- a/quic/s2n-quic-transport/src/connection/api_provider.rs +++ b/quic/s2n-quic-transport/src/connection/api_provider.rs @@ -21,6 +21,7 @@ use s2n_quic_core::{ query::{Query, QueryMut}, stream::{ops, StreamId, StreamType}, }; +use std::any::Any; /// A dynamically dispatched connection API pub(crate) type ConnectionApi = Arc; @@ -58,6 +59,10 @@ pub(crate) trait ConnectionApiProvider: Sync + Send { fn application_protocol(&self) -> Result; + fn take_application_context( + &mut self, + ) -> Result>, connection::Error>; + fn id(&self) -> u64; fn ping(&self) -> Result<(), connection::Error>; diff --git a/quic/s2n-quic-transport/src/connection/connection_container.rs b/quic/s2n-quic-transport/src/connection/connection_container.rs index 8428501281..76db4e312c 100644 --- a/quic/s2n-quic-transport/src/connection/connection_container.rs +++ b/quic/s2n-quic-transport/src/connection/connection_container.rs @@ -41,6 +41,7 @@ use s2n_quic_core::{ transport, }; use smallvec::SmallVec; +use std::any::Any; // Intrusive list adapter for managing the list of `done` connections intrusive_adapter!(DoneConnectionsAdapter = Arc>: ConnectionNode { @@ -310,6 +311,12 @@ impl> ConnectionApiProvider for Con self.api_read_call(|conn| Ok(conn.application_protocol())) } + fn take_application_context( + &mut self, + ) -> Result>, connection::Error> { + self.api_write_call(|conn| Ok(conn.take_application_context())) + } + fn id(&self) -> u64 { self.internal_connection_id.into() } diff --git a/quic/s2n-quic-transport/src/connection/connection_container/tests.rs b/quic/s2n-quic-transport/src/connection/connection_container/tests.rs index 45094e79c8..d2f5163628 100644 --- a/quic/s2n-quic-transport/src/connection/connection_container/tests.rs +++ b/quic/s2n-quic-transport/src/connection/connection_container/tests.rs @@ -62,7 +62,9 @@ impl connection::Trait for TestConnection { fn new(_params: connection::Parameters) -> Result { Ok(Self::default()) } - + fn take_application_context(&mut self) -> Option> { + todo!() + } fn internal_connection_id(&self) -> InternalConnectionId { todo!() } diff --git a/quic/s2n-quic-transport/src/connection/connection_impl.rs b/quic/s2n-quic-transport/src/connection/connection_impl.rs index f61030acf4..88f93efff2 100644 --- a/quic/s2n-quic-transport/src/connection/connection_impl.rs +++ b/quic/s2n-quic-transport/src/connection/connection_impl.rs @@ -61,6 +61,7 @@ use s2n_quic_core::{ time::{timer, Timestamp}, transport, }; +use std::any::Any; /// Possible states for handing over a connection from the endpoint to the /// application. @@ -1944,6 +1945,10 @@ impl connection::Trait for ConnectionImpl { self.space_manager.application_protocol.clone() } + fn take_application_context(&mut self) -> Option> { + self.space_manager.application_context.take() + } + fn ping(&mut self) -> Result<(), connection::Error> { self.error?; diff --git a/quic/s2n-quic-transport/src/connection/connection_trait.rs b/quic/s2n-quic-transport/src/connection/connection_trait.rs index b6f74b96b7..351cdf8e60 100644 --- a/quic/s2n-quic-transport/src/connection/connection_trait.rs +++ b/quic/s2n-quic-transport/src/connection/connection_trait.rs @@ -36,6 +36,7 @@ use s2n_quic_core::{ query, time::Timestamp, }; +use std::any::Any; /// A trait which represents an internally used `Connection` pub trait ConnectionTrait: 'static + Send + Sized { @@ -505,6 +506,7 @@ pub trait ConnectionTrait: 'static + Send + Sized { >, &path::Path, ); + fn take_application_context(&mut self) -> Option>; } /// A lock that synchronizes connection state between the QUIC endpoint thread and application diff --git a/quic/s2n-quic-transport/src/space/mod.rs b/quic/s2n-quic-transport/src/space/mod.rs index 9c02489683..3f420811ed 100644 --- a/quic/s2n-quic-transport/src/space/mod.rs +++ b/quic/s2n-quic-transport/src/space/mod.rs @@ -16,6 +16,7 @@ use core::{ ops::RangeInclusive, task::{Poll, Waker}, }; +use std::any::Any; use s2n_codec::DecoderBufferMut; use s2n_quic_core::{ application::ServerName, @@ -63,6 +64,7 @@ pub struct PacketSpaceManager { retry_cid: Option>, initial: Option>>, handshake: Option>>, + pub application_context: Option>, application: Option>>, zero_rtt_crypto: Option::Session as CryptoSuite>::ZeroRttKey>>, @@ -124,6 +126,7 @@ impl PacketSpaceManager { session, initial_cid, }), + application_context: None, retry_cid: None, initial: Some(Box::new(InitialSpace::new( initial_key, @@ -258,6 +261,7 @@ impl PacketSpaceManager { handshake: &mut self.handshake, application: &mut self.application, zero_rtt_crypto: &mut self.zero_rtt_crypto, + application_context: &mut self.application_context, path_manager, handshake_status: &mut self.handshake_status, local_id_registry, @@ -303,6 +307,7 @@ impl PacketSpaceManager { retry_cid: self.retry_cid.as_deref(), initial: &mut self.initial, handshake: &mut self.handshake, + application_context: &mut self.application_context, application: &mut self.application, zero_rtt_crypto: &mut self.zero_rtt_crypto, path_manager, diff --git a/quic/s2n-quic-transport/src/space/session_context.rs b/quic/s2n-quic-transport/src/space/session_context.rs index 374a4555da..6130ee94e4 100644 --- a/quic/s2n-quic-transport/src/space/session_context.rs +++ b/quic/s2n-quic-transport/src/space/session_context.rs @@ -41,6 +41,7 @@ use s2n_quic_core::{ Error, }, }; +use std::any::Any; pub struct SessionContext<'a, Config: endpoint::Config, Pub: event::ConnectionPublisher> { pub now: Timestamp, @@ -62,6 +63,7 @@ pub struct SessionContext<'a, Config: endpoint::Config, Pub: event::ConnectionPu pub publisher: &'a mut Pub, pub datagram: &'a mut Config::DatagramEndpoint, pub dc: &'a mut Config::DcEndpoint, + pub application_context: &'a mut Option>, } impl SessionContext<'_, Config, Pub> { @@ -697,4 +699,7 @@ impl Ok(()) } + fn on_application_context(&mut self, context: Option>) { + *self.application_context = context; + } }