runsync_transfer/transport/
quic.rs1use super::{BoxRecv, BoxSend, Transport};
10use crate::error::{Error, Result};
11use std::net::SocketAddr;
12use std::sync::Arc;
13use std::time::Duration;
14
15#[derive(Clone)]
17pub struct QuicTransport {
18 conn: quinn::Connection,
19}
20
21impl QuicTransport {
22 pub fn from_connection(conn: quinn::Connection) -> Self {
23 Self { conn }
24 }
25
26 pub fn connection(&self) -> &quinn::Connection {
27 &self.conn
28 }
29}
30
31#[async_trait::async_trait]
32impl Transport for QuicTransport {
33 async fn open_uni(&self) -> Result<BoxSend> {
34 let s = self.conn.open_uni().await.map_err(Error::transport)?;
35 Ok(Box::new(s))
36 }
37
38 async fn accept_uni(&self) -> Result<BoxRecv> {
39 let s = self.conn.accept_uni().await.map_err(Error::transport)?;
40 Ok(Box::new(s))
41 }
42
43 async fn open_bi(&self) -> Result<(BoxSend, BoxRecv)> {
44 let (w, r) = self.conn.open_bi().await.map_err(Error::transport)?;
45 Ok((Box::new(w), Box::new(r)))
46 }
47
48 async fn accept_bi(&self) -> Result<(BoxSend, BoxRecv)> {
49 let (w, r) = self.conn.accept_bi().await.map_err(Error::transport)?;
50 Ok((Box::new(w), Box::new(r)))
51 }
52
53 fn close(&self, code: u32, reason: &[u8]) {
54 self.conn.close(code.into(), reason);
55 }
56
57 fn peer_label(&self) -> String {
58 self.conn.remote_address().to_string()
59 }
60
61 fn bytes_sent(&self) -> Option<u64> {
62 Some(self.conn.stats().udp_tx.bytes)
63 }
64}
65
66pub fn bulk_transport_config() -> quinn::TransportConfig {
73 let mut t = quinn::TransportConfig::default();
74 t.receive_window(quinn::VarInt::from_u32(64 * 1024 * 1024));
76 t.stream_receive_window(quinn::VarInt::from_u32(16 * 1024 * 1024));
77 t.send_window(64 * 1024 * 1024);
78 t.max_concurrent_uni_streams(quinn::VarInt::from_u32(256));
79 t.max_concurrent_bidi_streams(quinn::VarInt::from_u32(16));
80 t.keep_alive_interval(Some(Duration::from_secs(5)));
83 t.max_idle_timeout(Some(Duration::from_secs(60).try_into().unwrap()));
84 t
85}
86
87pub fn server_endpoint(
89 addr: SocketAddr,
90 cert_chain: Vec<rustls::pki_types::CertificateDer<'static>>,
91 key: rustls::pki_types::PrivateKeyDer<'static>,
92) -> Result<quinn::Endpoint> {
93 let mut server_crypto = rustls::ServerConfig::builder_with_provider(Arc::new(
94 rustls::crypto::ring::default_provider(),
95 ))
96 .with_protocol_versions(&[&rustls::version::TLS13])
97 .map_err(Error::transport)?
98 .with_no_client_auth()
99 .with_single_cert(cert_chain, key)
100 .map_err(Error::transport)?;
101 server_crypto.alpn_protocols = vec![ALPN.to_vec()];
102
103 let mut cfg = quinn::ServerConfig::with_crypto(Arc::new(
104 quinn::crypto::rustls::QuicServerConfig::try_from(server_crypto)
105 .map_err(Error::transport)?,
106 ));
107 cfg.transport_config(Arc::new(bulk_transport_config()));
108 quinn::Endpoint::server(cfg, addr).map_err(Error::from)
109}
110
111pub fn client_endpoint(
117 bind: SocketAddr,
118 server_cert: rustls::pki_types::CertificateDer<'static>,
119) -> Result<quinn::Endpoint> {
120 let mut roots = rustls::RootCertStore::empty();
121 roots.add(server_cert).map_err(Error::transport)?;
122
123 let mut client_crypto = rustls::ClientConfig::builder_with_provider(Arc::new(
124 rustls::crypto::ring::default_provider(),
125 ))
126 .with_protocol_versions(&[&rustls::version::TLS13])
127 .map_err(Error::transport)?
128 .with_root_certificates(roots)
129 .with_no_client_auth();
130 client_crypto.alpn_protocols = vec![ALPN.to_vec()];
131
132 let mut cfg = quinn::ClientConfig::new(Arc::new(
133 quinn::crypto::rustls::QuicClientConfig::try_from(client_crypto)
134 .map_err(Error::transport)?,
135 ));
136 cfg.transport_config(Arc::new(bulk_transport_config()));
137
138 let mut ep = quinn::Endpoint::client(bind).map_err(Error::from)?;
139 ep.set_default_client_config(cfg);
140 Ok(ep)
141}
142
143pub const ALPN: &[u8] = b"runsync-transfer/1";
144
145#[cfg(feature = "test-certs")]
147pub fn self_signed(
148 names: Vec<String>,
149) -> Result<(
150 rustls::pki_types::CertificateDer<'static>,
151 rustls::pki_types::PrivateKeyDer<'static>,
152)> {
153 let c = rcgen::generate_simple_self_signed(names).map_err(Error::transport)?;
154 let cert = rustls::pki_types::CertificateDer::from(c.cert);
155 let key = rustls::pki_types::PrivateKeyDer::try_from(c.key_pair.serialize_der())
156 .map_err(Error::transport)?;
157 Ok((cert, key))
158}