diff --git a/core/lib/src/listener/quic.rs b/core/lib/src/listener/quic.rs index f237a88e..e866f036 100644 --- a/core/lib/src/listener/quic.rs +++ b/core/lib/src/listener/quic.rs @@ -37,7 +37,7 @@ use futures::Stream; use tokio::sync::Mutex; use tokio_stream::StreamExt; -use crate::tls::TlsConfig; +use crate::tls::{TlsConfig, Error}; use crate::listener::{Listener, Connection, Endpoint}; type H3Conn = h3::server::Connection; @@ -62,43 +62,29 @@ pub struct QuicRx(h3::server::RequestStream); pub struct QuicTx(h3::server::RequestStream, Bytes>); impl QuicListener { - pub async fn bind(address: SocketAddr, tls: TlsConfig) -> Result { - use quic::provider::tls::rustls::{rustls, DEFAULT_CIPHERSUITES, Server as H3TlsServer}; + pub async fn bind(address: SocketAddr, tls: TlsConfig) -> Result { + use quic::provider::tls::rustls::Server as H3TlsServer; - // FIXME: Remove this as soon as `s2n_quic` is on rustls >= 0.22. - let cert_chain = tls.load_certs() - .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))? + let cert_chain = tls.load_certs()? .into_iter() .map(|v| v.to_vec()) - .map(rustls::Certificate) .collect::>(); - let key = tls.load_key() - .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))? - .secret_der() - .to_vec(); - - let mut h3tls = rustls::server::ServerConfig::builder() - .with_cipher_suites(DEFAULT_CIPHERSUITES) - .with_safe_default_kx_groups() - .with_safe_default_protocol_versions() - .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))? - .with_client_cert_verifier(rustls::server::NoClientAuth::boxed()) - .with_single_cert(cert_chain, rustls::PrivateKey(key)) - .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))?; - - h3tls.alpn_protocols = vec![b"h3".to_vec()]; - h3tls.ignore_client_order = tls.prefer_server_cipher_order; - h3tls.session_storage = rustls::server::ServerSessionMemoryCache::new(1024); - h3tls.ticketer = rustls::Ticketer::new() - .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS ticketer: {}", e)))?; + let h3tls = H3TlsServer::builder() + .with_application_protocols(["h3"].into_iter()) + .map_err(|e| Error::Bind(e))? + .with_certificate(cert_chain, tls.load_key()?.secret_der()) + .map_err(|e| Error::Bind(e))? + .with_prefer_server_cipher_suite_order(tls.prefer_server_cipher_order) + .map_err(|e| Error::Bind(e))? + .build() + .map_err(|e| Error::Bind(e))?; let listener = quic::Server::builder() - .with_tls(H3TlsServer::new(h3tls)) - .unwrap_or_else(|e| match e { }) + .with_tls(h3tls)? .with_io(address)? .start() - .map_err(io::Error::other)?; + .map_err(|e| Error::Bind(Box::new(e)))?; Ok(QuicListener { tls, diff --git a/core/lib/src/server.rs b/core/lib/src/server.rs index 8d26604f..e008c7bc 100644 --- a/core/lib/src/server.rs +++ b/core/lib/src/server.rs @@ -108,7 +108,10 @@ impl Rocket { let endpoint = h12listener.endpoint()?; #[cfg(feature = "http3-preview")] if let (Some(addr), Some(tls)) = (endpoint.tcp(), endpoint.tls_config()) { - let h3listener = crate::listener::quic::QuicListener::bind(addr, tls.clone()).await?; + let h3listener = crate::listener::quic::QuicListener::bind(addr, tls.clone()) + .map_err(|e| ErrorKind::Bind(Some(endpoint.clone()), Box::new(e))) + .await?; + let rocket = self.into_orbit(vec![h3listener.endpoint()?, endpoint]); let rocket = post_bind_callback(rocket).await?; diff --git a/core/lib/src/tls/error.rs b/core/lib/src/tls/error.rs index ab2faf3e..5fd50615 100644 --- a/core/lib/src/tls/error.rs +++ b/core/lib/src/tls/error.rs @@ -96,3 +96,9 @@ impl From for Error { Error::PrivKey(value) } } + +impl From for Error { + fn from(v: std::convert::Infallible) -> Self { + v.into() + } +}