hickory_proto/quic/
quic_server.rs1use alloc::sync::Arc;
9use std::{io, net::SocketAddr};
10
11use quinn::crypto::rustls::QuicServerConfig;
12use quinn::{Connection, Endpoint, ServerConfig};
13use rustls::server::ResolvesServerCert;
14use rustls::server::ServerConfig as TlsServerConfig;
15use rustls::version::TLS13;
16
17use crate::{error::ProtoError, rustls::default_provider, udp::UdpSocket};
18
19use super::{
20 quic_config,
21 quic_stream::{self, QuicStream},
22};
23
24pub struct QuicServer {
26 endpoint: Endpoint,
27}
28
29impl QuicServer {
30 pub async fn new(
32 name_server: SocketAddr,
33 server_cert_resolver: Arc<dyn ResolvesServerCert>,
34 ) -> Result<Self, ProtoError> {
35 let socket = <tokio::net::UdpSocket as UdpSocket>::bind(name_server).await?;
37 Self::with_socket(socket, server_cert_resolver)
38 }
39
40 pub fn with_socket(
42 socket: tokio::net::UdpSocket,
43 server_cert_resolver: Arc<dyn ResolvesServerCert>,
44 ) -> Result<Self, ProtoError> {
45 let mut config = TlsServerConfig::builder_with_provider(Arc::new(default_provider()))
46 .with_protocol_versions(&[&TLS13])
47 .unwrap() .with_no_client_auth()
49 .with_cert_resolver(server_cert_resolver);
50
51 config.alpn_protocols = vec![quic_stream::DOQ_ALPN.to_vec()];
52
53 let mut server_config =
54 ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(config)?));
55 server_config.transport = Arc::new(quic_config::transport());
56
57 let socket = socket.into_std()?;
58
59 let endpoint_config = quic_config::endpoint();
60 let endpoint = Endpoint::new(
61 endpoint_config,
62 Some(server_config),
63 socket,
64 Arc::new(quinn::TokioRuntime),
65 )?;
66
67 Ok(Self { endpoint })
68 }
69
70 pub async fn next(&mut self) -> Result<Option<(QuicStreams, SocketAddr)>, ProtoError> {
76 let connecting = match self.endpoint.accept().await {
77 Some(conn) => conn,
78 None => return Ok(None),
79 };
80
81 let remote_addr = connecting.remote_address();
82 let connection = connecting.await?;
83 Ok(Some((QuicStreams { connection }, remote_addr)))
84 }
85
86 pub fn local_addr(&self) -> Result<SocketAddr, io::Error> {
91 self.endpoint.local_addr()
92 }
93}
94
95pub struct QuicStreams {
97 connection: Connection,
98}
99
100impl QuicStreams {
101 pub async fn next(&mut self) -> Option<Result<QuicStream, ProtoError>> {
103 match self.connection.accept_bi().await {
104 Ok((send_stream, receive_stream)) => {
105 Some(Ok(QuicStream::new(send_stream, receive_stream)))
106 }
107 Err(e) => Some(Err(e.into())),
108 }
109 }
110}