use quinn::{ Certificate, CertificateChain, ClientConfig, ClientConfigBuilder, Endpoint, Incoming, PrivateKey, ServerConfig, ServerConfigBuilder, TransportConfig, }; use std::{net::SocketAddr, sync::Arc}; /// Constructs a QUIC endpoint configured for use a client only. /// /// ## Args /// /// - server_certs: list of trusted certificates. #[allow(unused)] pub fn make_client_endpoint( bind_addr: SocketAddr, server_certs: &[&[u8]], ) -> anyhow::Result { let client_cfg = configure_client(server_certs)?; let mut endpoint_builder = Endpoint::builder(); endpoint_builder.default_client_config(client_cfg); let (endpoint, _incoming) = endpoint_builder.bind(&bind_addr)?; Ok(endpoint) } /// Constructs a QUIC endpoint configured to listen for incoming connections on a certain address /// and port. /// /// ## Returns /// /// - a stream of incoming QUIC connections /// - server certificate serialized into DER format #[allow(unused)] pub fn make_server_endpoint(bind_addr: SocketAddr) -> anyhow::Result<(Incoming, Vec)> { let (server_config, server_cert) = configure_server()?; let mut endpoint_builder = Endpoint::builder(); endpoint_builder.listen(server_config); let (_endpoint, incoming) = endpoint_builder.bind(&bind_addr)?; Ok((incoming, server_cert)) } /// Builds default quinn client config and trusts given certificates. /// /// ## Args /// /// - server_certs: a list of trusted certificates in DER format. fn configure_client(server_certs: &[&[u8]]) -> anyhow::Result { let mut cfg_builder = ClientConfigBuilder::default(); for cert in server_certs { cfg_builder.add_certificate_authority(Certificate::from_der(&cert)?)?; } Ok(cfg_builder.build()) } /// Returns default server configuration along with its certificate. #[allow(clippy::field_reassign_with_default)] // https://github.com/rust-lang/rust-clippy/issues/6527 fn configure_server() -> anyhow::Result<(ServerConfig, Vec)> { let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap(); let cert_der = cert.serialize_der().unwrap(); let priv_key = cert.serialize_private_key_der(); let priv_key = PrivateKey::from_der(&priv_key)?; let mut transport_config = TransportConfig::default(); transport_config.max_concurrent_uni_streams(0).unwrap(); let mut server_config = ServerConfig::default(); server_config.transport = Arc::new(transport_config); let mut cfg_builder = ServerConfigBuilder::new(server_config); let cert = Certificate::from_der(&cert_der)?; cfg_builder.certificate(CertificateChain::from_certs(vec![cert]), priv_key)?; Ok((cfg_builder.build(), cert_der)) } #[allow(unused)] pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];