trillium_quinn/
connection.rs1use async_compat::Compat;
2use futures_lite::{AsyncRead, AsyncWrite};
3use quinn::VarInt;
4use std::{
5 fmt::{self, Debug, Formatter},
6 future::Future,
7 io,
8 net::SocketAddr,
9 pin::Pin,
10};
11use trillium_macros::{AsyncRead, AsyncWrite};
12use trillium_server_common::{
13 QuicConnectionTrait, QuicTransportBidi, QuicTransportReceive, QuicTransportSend, Transport,
14};
15
16#[derive(AsyncRead, AsyncWrite)]
19pub struct QuinnTransport {
20 #[async_read]
21 recv: Compat<quinn::RecvStream>,
22 #[async_write]
23 send: Compat<quinn::SendStream>,
24}
25
26impl QuinnTransport {
27 fn new(recv: quinn::RecvStream, send: quinn::SendStream) -> Self {
28 Self {
29 recv: Compat::new(recv),
30 send: Compat::new(send),
31 }
32 }
33}
34
35impl QuicTransportReceive for QuinnTransport {
36 fn stop(&mut self, code: u64) {
37 let error_code = VarInt::from_u64(code).unwrap_or_default();
38 let _ = self.recv.get_mut().stop(error_code);
39 }
40}
41
42fn stopped_future(
47 send: &quinn::SendStream,
48) -> Option<Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>> {
49 let stopped = send.stopped();
50 Some(Box::pin(async move {
51 let _ = stopped.await;
52 }))
53}
54
55impl QuicTransportSend for QuinnTransport {
56 fn reset(&mut self, code: u64) {
57 let error_code = VarInt::from_u64(code).unwrap_or_default();
58 let _ = self.send.get_mut().reset(error_code);
59 }
60
61 fn stopped(&self) -> Option<Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>> {
62 stopped_future(self.send.get_ref())
63 }
64
65 fn set_priority(&mut self, priority: i32) {
66 let _ = self.send.get_mut().set_priority(priority);
69 }
70}
71
72impl QuicTransportBidi for QuinnTransport {}
73
74impl Transport for QuinnTransport {}
79
80#[derive(Clone, Debug)]
82pub struct QuinnConnection(quinn::Connection);
83
84impl QuinnConnection {
85 pub(crate) fn new(connection: quinn::Connection) -> Self {
86 Self(connection)
87 }
88}
89
90#[derive(AsyncRead)]
91pub struct QuinnRecv(Compat<quinn::RecvStream>);
92impl Debug for QuinnRecv {
93 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
94 f.debug_tuple("QuinnRecv").finish_non_exhaustive()
95 }
96}
97impl From<quinn::RecvStream> for QuinnRecv {
98 fn from(value: quinn::RecvStream) -> Self {
99 Self(Compat::new(value))
100 }
101}
102impl QuicTransportReceive for QuinnRecv {
103 fn stop(&mut self, code: u64) {
104 let error_code = VarInt::from_u64(code).unwrap_or_default();
105 let _ = self.0.get_mut().stop(error_code);
106 }
107}
108
109#[derive(AsyncWrite)]
110pub struct QuinnSend(Compat<quinn::SendStream>);
111
112impl Debug for QuinnSend {
113 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
114 f.debug_tuple("QuinnSend").finish_non_exhaustive()
115 }
116}
117impl From<quinn::SendStream> for QuinnSend {
118 fn from(value: quinn::SendStream) -> Self {
119 Self(Compat::new(value))
120 }
121}
122impl QuicTransportSend for QuinnSend {
123 fn reset(&mut self, code: u64) {
124 let error_code = VarInt::from_u64(code).unwrap_or_default();
125 let _ = self.0.get_mut().reset(error_code);
126 }
127
128 fn stopped(&self) -> Option<Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>> {
129 stopped_future(self.0.get_ref())
130 }
131
132 fn set_priority(&mut self, priority: i32) {
133 let _ = self.0.get_mut().set_priority(priority);
134 }
135}
136
137impl QuicConnectionTrait for QuinnConnection {
138 type BidiStream = QuinnTransport;
139 type RecvStream = QuinnRecv;
140 type SendStream = QuinnSend;
141
142 async fn accept_bidi(&self) -> io::Result<(u64, Self::BidiStream)> {
143 let (send, recv) = self.0.accept_bi().await.map_err(conn_err)?;
144 let stream_id = VarInt::from(recv.id()).into_inner();
145 Ok((stream_id, QuinnTransport::new(recv, send)))
146 }
147
148 async fn accept_uni(&self) -> io::Result<(u64, Self::RecvStream)> {
149 let recv = self.0.accept_uni().await.map_err(conn_err)?;
150 let stream_id = VarInt::from(recv.id()).into_inner();
151 Ok((stream_id, recv.into()))
152 }
153
154 async fn open_uni(&self) -> io::Result<(u64, Self::SendStream)> {
155 let send = self.0.open_uni().await.map_err(conn_err)?;
156 let stream_id = VarInt::from(send.id()).into_inner();
157 Ok((stream_id, send.into()))
158 }
159
160 async fn open_bidi(&self) -> io::Result<(u64, Self::BidiStream)> {
161 let (send, recv) = self.0.open_bi().await.map_err(conn_err)?;
162 let stream_id = VarInt::from(recv.id()).into_inner();
163 Ok((stream_id, QuinnTransport::new(recv, send)))
164 }
165
166 fn remote_address(&self) -> SocketAddr {
167 self.0.remote_address()
168 }
169
170 fn close(&self, error_code: u64, reason: &[u8]) {
171 self.0
172 .close(VarInt::from_u64(error_code).unwrap_or(VarInt::MAX), reason);
173 }
174
175 fn send_datagram(&self, data: &[u8]) -> io::Result<()> {
176 self.0
177 .send_datagram(data.to_vec().into())
178 .map_err(io::Error::other)
179 }
180
181 async fn recv_datagram<F: FnOnce(&[u8]) + Send>(&self, callback: F) -> io::Result<()> {
182 self.0
183 .read_datagram()
184 .await
185 .map(|d| callback(&d))
186 .map_err(conn_err)
187 }
188
189 fn max_datagram_size(&self) -> Option<usize> {
190 self.0.max_datagram_size()
191 }
192}
193
194fn conn_err(e: quinn::ConnectionError) -> io::Error {
195 io::Error::new(io::ErrorKind::ConnectionReset, e)
196}