diff --git a/quinn-proto/src/crypto.rs b/quinn-proto/src/crypto.rs index cfab8ebe86..ad15b5977c 100644 --- a/quinn-proto/src/crypto.rs +++ b/quinn-proto/src/crypto.rs @@ -56,7 +56,8 @@ pub trait Session: Send + 'static { /// /// This should be called with the contents of `CRYPTO` frames. If it returns `Ok`, the /// caller should call `write_handshake()` to check if the crypto protocol has anything - /// to send to the peer. + /// to send to the peer. This method will only return `true` the first time that + /// handshake data is available. Future calls will always return false. /// /// On success, returns `true` iff `self.handshake_data()` has been populated. fn read_handshake(&mut self, buf: &[u8]) -> Result; diff --git a/quinn-proto/src/transport_error.rs b/quinn-proto/src/transport_error.rs index cbc8b2e1c6..63e06a1ee8 100644 --- a/quinn-proto/src/transport_error.rs +++ b/quinn-proto/src/transport_error.rs @@ -49,7 +49,7 @@ pub struct Code(u64); impl Code { /// Create QUIC error code from TLS alert code - pub(crate) fn crypto(code: u8) -> Self { + pub fn crypto(code: u8) -> Self { Code(0x100 | u64::from(code)) } } diff --git a/quinn-proto/src/transport_parameters.rs b/quinn-proto/src/transport_parameters.rs index a3ca0afa34..41dbee6f92 100644 --- a/quinn-proto/src/transport_parameters.rs +++ b/quinn-proto/src/transport_parameters.rs @@ -94,6 +94,67 @@ macro_rules! make_struct { pub(crate) preferred_address: Option, } + impl TransportParameters { + $($(#[$doc])* + #[inline] + pub fn $name (&self) -> u64 { + self.$name.0 + })* + + /// Does the endpoint support active connection migration + #[inline] + pub fn disable_active_migration(&self) -> bool { + self.disable_active_migration + } + + /// Maximum size for datagram frames + #[inline] + pub fn max_datagram_frame_size(&self) -> Option { + self.max_datagram_frame_size.map_or(None, |x| Some(x.0)) + } + + /// The value that the endpoint included in the Source Connection ID field of the first + /// Initial packet it sends for the connection + #[inline] + pub fn initial_src_cid(&self) -> Option { + self.initial_src_cid + } + + /// The endpoint is willing to receive QUIC packets containing any value for the fixed + /// bit + #[inline] + pub fn grease_quic_bit(&self) -> bool { + self.grease_quic_bit + } + + // Server-only + /// The value of the Destination Connection ID field from the first Initial packet sent + /// by the client + #[inline] + pub fn original_dst_cid(&self) -> Option { + self.original_dst_cid + } + + /// The value that the server included in the Source Connection ID field of a Retry + /// packet + #[inline] + pub fn retry_src_cid(&self) -> Option { + self.retry_src_cid + } + + /// Token used by the client to verify a stateless reset from the server + #[inline] + pub fn stateless_reset_token(&self) -> Option { + self.stateless_reset_token + } + + /// The server's preferred address for communication after handshake completion + #[inline] + pub fn preferred_address(&self) -> Option { + self.preferred_address + } + } + impl Default for TransportParameters { /// Standard defaults, used if the peer does not supply a given parameter. fn default() -> Self { @@ -186,14 +247,34 @@ impl TransportParameters { /// /// This is communicated as a transport parameter during TLS session establishment. #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub(crate) struct PreferredAddress { - pub address_v4: Option, - pub address_v6: Option, - pub connection_id: ConnectionId, - pub stateless_reset_token: ResetToken, +pub struct PreferredAddress { + pub(crate) address_v4: Option, + pub(crate) address_v6: Option, + pub(crate) connection_id: ConnectionId, + pub(crate) stateless_reset_token: ResetToken, } impl PreferredAddress { + /// Returns the server's IPv4 address, if available. + pub fn address_v4(&self) -> Option { + self.address_v4.map_or(None, |addr| Some(addr)) + } + + /// Returns the server's IPv6 address, if available. + pub fn address_v6(&self) -> Option { + self.address_v6.map_or(None, |addr| Some(addr)) + } + + /// Returns the connection ID. + pub fn connection_id(&self) -> ConnectionId { + self.connection_id + } + + /// Returns the reset token. + pub fn stateless_reset_token(&self) -> ResetToken { + self.stateless_reset_token + } + fn wire_size(&self) -> u16 { 4 + 2 + 16 + 2 + 1 + self.connection_id.len() as u16 + 16 } diff --git a/quinn/src/endpoint.rs b/quinn/src/endpoint.rs index c134231c70..3e5b1ab18d 100644 --- a/quinn/src/endpoint.rs +++ b/quinn/src/endpoint.rs @@ -107,7 +107,8 @@ impl Endpoint { Self::new_with_runtime(config, server_config, Box::new(socket), Arc::new(runtime)) } - fn new_with_runtime( + /// Construct an endpoint with arbitrary configuration and pre-constructed async socket. + pub fn new_with_runtime( config: EndpointConfig, server_config: Option, socket: Box,