From a384ee2edbebd37aee5c2c62b35046b9cdfb7d7f Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Sun, 10 Oct 2021 13:18:30 -0700 Subject: [PATCH] Erase crypto::Session::HandshakeData --- quinn-proto/src/crypto.rs | 7 ++----- quinn-proto/src/crypto/rustls.rs | 9 ++++----- quinn-proto/src/tests/mod.rs | 2 ++ quinn/examples/server.rs | 1 + quinn/src/connection.rs | 13 ++++++++++--- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/quinn-proto/src/crypto.rs b/quinn-proto/src/crypto.rs index 09702e063..e8b7c04df 100644 --- a/quinn-proto/src/crypto.rs +++ b/quinn-proto/src/crypto.rs @@ -8,7 +8,7 @@ //! Note that usage of any protocol (version) other than TLS 1.3 does not conform to any //! published versions of the specification, and will not be supported in QUIC v1. -use std::str; +use std::{any::Any, str}; use bytes::BytesMut; @@ -29,9 +29,6 @@ pub(crate) mod types; /// A cryptographic session (commonly TLS) pub trait Session: Send + Sized { - /// Parameters determined when the handshake begins, e.g. server name and/or application - /// protocol - type HandshakeData; /// Cryptographic identity of the peer type Identity: Sized; /// Type used to hold configuration for client sessions @@ -53,7 +50,7 @@ pub trait Session: Send + Sized { /// Get data negotiated during the handshake, if available /// /// Returns `None` until the connection emits `HandshakeDataReady`. - fn handshake_data(&self) -> Option; + fn handshake_data(&self) -> Option>; /// Get the peer's identity, if available fn peer_identity(&self) -> Option; diff --git a/quinn-proto/src/crypto/rustls.rs b/quinn-proto/src/crypto/rustls.rs index b2040f3ff..724ba42e4 100644 --- a/quinn-proto/src/crypto/rustls.rs +++ b/quinn-proto/src/crypto/rustls.rs @@ -1,4 +1,4 @@ -use std::{convert::TryInto, io, str, sync::Arc}; +use std::{any::Any, convert::TryInto, io, str, sync::Arc}; use bytes::BytesMut; use ring::{aead, hkdf, hmac}; @@ -36,7 +36,6 @@ impl TlsSession { } impl crypto::Session for TlsSession { - type HandshakeData = HandshakeData; type Identity = CertificateChain; type ClientConfig = Arc; type HmacKey = hmac::Key; @@ -59,17 +58,17 @@ impl crypto::Session for TlsSession { } } - fn handshake_data(&self) -> Option { + fn handshake_data(&self) -> Option> { if !self.got_handshake_data { return None; } - Some(HandshakeData { + Some(Box::new(HandshakeData { protocol: self.inner.alpn_protocol().map(|x| x.into()), server_name: match self.inner { Connection::Client(_) => None, Connection::Server(ref session) => session.sni_hostname().map(|x| x.into()), }, - }) + })) } fn peer_identity(&self) -> Option { diff --git a/quinn-proto/src/tests/mod.rs b/quinn-proto/src/tests/mod.rs index 166ae9f09..01a686d38 100644 --- a/quinn-proto/src/tests/mod.rs +++ b/quinn-proto/src/tests/mod.rs @@ -561,6 +561,8 @@ fn alpn_success() { .client_conn_mut(client_ch) .crypto_session() .handshake_data() + .unwrap() + .downcast::() .unwrap(); assert_eq!(hd.protocol.unwrap(), &b"bar"[..]); } diff --git a/quinn/examples/server.rs b/quinn/examples/server.rs index a0a179ae8..a9f0bee1b 100644 --- a/quinn/examples/server.rs +++ b/quinn/examples/server.rs @@ -156,6 +156,7 @@ async fn handle_connection(root: Arc, conn: quinn::Connecting) -> Result<( protocol = %connection .handshake_data() .unwrap() + .downcast::().unwrap() .protocol .map_or_else(|| "".into(), |x| String::from_utf8_lossy(&x).into_owned()) ); diff --git a/quinn/src/connection.rs b/quinn/src/connection.rs index 8b1825e94..187e123a7 100644 --- a/quinn/src/connection.rs +++ b/quinn/src/connection.rs @@ -1,4 +1,5 @@ use std::{ + any::Any, fmt, future::Future, mem, @@ -111,7 +112,12 @@ where } /// Parameters negotiated during the handshake - pub async fn handshake_data(&mut self) -> Result { + /// + /// The dynamic type returned is determined by the configured + /// [`Session`](proto::crypto::Session). For the default `rustls` session, the return value can + /// be [`downcast`](Box::downcast) to a + /// [`crypto::rustls::HandshakeData`](crate::crypto::rustls::HandshakeData). + pub async fn handshake_data(&mut self) -> Result, ConnectionError> { // Taking &mut self allows us to use a single oneshot channel rather than dealing with // potentially many tasks waiting on the same event. It's a bit of a hack, but keeps things // simple. @@ -459,10 +465,11 @@ where /// Parameters negotiated during the handshake /// /// Guaranteed to return `Some` on fully established connections or after - /// [`Connecting::handshake_data()`] succeeds. + /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for details on + /// the returned value. /// /// [`Connection::handshake_data()`]: crate::generic::Connecting::handshake_data - pub fn handshake_data(&self) -> Option { + pub fn handshake_data(&self) -> Option> { self.0 .lock("handshake_data") .inner