1use crate::stream::{RecvStream, SendStream, WriteCommand};
4use bytes::Bytes;
5use nxtquic_proto::ConnectionId;
6use nxtquic_proto::frame::Frame;
7use std::collections::{HashMap, VecDeque};
8use std::net::SocketAddr;
9use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
10use std::sync::Arc;
11use std::time::Duration;
12use tokio::sync::{Mutex, Notify};
13
14struct StreamInput {
15 tx: tokio::sync::mpsc::UnboundedSender<Option<Vec<u8>>>,
16 next_offset: u64,
17}
18
19#[derive(Clone, Debug, Default)]
21pub struct ConnectionStats {
22 pub smoothed_rtt: Duration,
24 pub min_rtt: Duration,
26 pub latest_rtt: Duration,
28 pub rtt_variance: Duration,
30 pub congestion_window: u64,
32 pub bytes_in_flight: u64,
34 pub packets_sent: u64,
36 pub packets_received: u64,
38 pub packets_lost: u64,
40 pub bytes_sent: u64,
42 pub bytes_received: u64,
44}
45
46#[derive(Clone, Debug, PartialEq, Eq)]
48pub struct ConnectionCloseInfo {
49 pub error_code: u64,
51 pub reason: Bytes,
53 pub from_peer: bool,
55}
56
57#[derive(Clone, Debug, Default)]
59pub struct HandshakeData {
60 pub alpn: Option<Vec<u8>>,
62 pub server_name: Option<String>,
64 pub cipher_suite: Option<String>,
66}
67
68#[derive(Clone)]
70pub struct Connection {
71 incoming_bi: Arc<Mutex<VecDeque<(SendStream, RecvStream)>>>,
72 incoming_uni: Arc<Mutex<VecDeque<RecvStream>>>,
73 incoming_bi_notify: Arc<Notify>,
74 incoming_uni_notify: Arc<Notify>,
75 closed_notify: Arc<Notify>,
76 closed: Arc<AtomicBool>,
77 close_info: Arc<Mutex<Option<ConnectionCloseInfo>>>,
78 socket: Option<Arc<tokio::net::UdpSocket>>,
79 remote_addr: Option<SocketAddr>,
80 local_addr: Option<SocketAddr>,
81 datagrams: Arc<Mutex<tokio::sync::mpsc::UnboundedReceiver<Bytes>>>,
82 datagram_tx: tokio::sync::mpsc::UnboundedSender<Bytes>,
83 stream_inputs: Arc<Mutex<HashMap<u64, StreamInput>>>,
84 outgoing_tx: Option<tokio::sync::mpsc::UnboundedSender<WriteCommand>>,
85 next_server_bi: Arc<AtomicU64>,
86 next_server_uni: Arc<AtomicU64>,
87 max_uni_streams: Arc<AtomicU64>,
88 max_bi_streams: Arc<AtomicU64>,
89 connection_id: ConnectionId,
90 handshake_data: Arc<Mutex<Option<HandshakeData>>>,
91 peer_identity: Arc<Mutex<Option<Vec<rustls::pki_types::CertificateDer<'static>>>>>,
92 stats: Arc<Mutex<ConnectionStats>>,
93}
94
95impl Connection {
96 pub fn new() -> Self {
98 let (datagram_tx, datagram_rx) = tokio::sync::mpsc::unbounded_channel();
99 Self {
100 incoming_bi: Arc::new(Mutex::new(VecDeque::new())),
101 incoming_uni: Arc::new(Mutex::new(VecDeque::new())),
102 incoming_bi_notify: Arc::new(Notify::new()),
103 incoming_uni_notify: Arc::new(Notify::new()),
104 closed_notify: Arc::new(Notify::new()),
105 closed: Arc::new(AtomicBool::new(false)),
106 close_info: Arc::new(Mutex::new(None)),
107 socket: None,
108 remote_addr: None,
109 local_addr: None,
110 datagrams: Arc::new(Mutex::new(datagram_rx)),
111 datagram_tx,
112 stream_inputs: Arc::new(Mutex::new(HashMap::new())),
113 outgoing_tx: None,
114 next_server_bi: Arc::new(AtomicU64::new(1)),
115 next_server_uni: Arc::new(AtomicU64::new(3)),
116 max_uni_streams: Arc::new(AtomicU64::new(100)),
117 max_bi_streams: Arc::new(AtomicU64::new(100)),
118 connection_id: ConnectionId::from_slice(&rand::random::<[u8; 16]>()),
119 handshake_data: Arc::new(Mutex::new(Some(HandshakeData {
120 alpn: Some(b"h3".to_vec()),
121 server_name: None,
122 cipher_suite: Some("TLS_AES_128_GCM_SHA256".to_string()),
123 }))),
124 peer_identity: Arc::new(Mutex::new(None)),
125 stats: Arc::new(Mutex::new(ConnectionStats {
126 smoothed_rtt: Duration::from_millis(10),
127 min_rtt: Duration::from_millis(5),
128 latest_rtt: Duration::from_millis(10),
129 rtt_variance: Duration::from_millis(2),
130 congestion_window: 14720,
131 bytes_in_flight: 0,
132 packets_sent: 0,
133 packets_received: 0,
134 packets_lost: 0,
135 bytes_sent: 0,
136 bytes_received: 0,
137 })),
138 }
139 }
140
141 pub(crate) fn with_outgoing(tx: tokio::sync::mpsc::UnboundedSender<WriteCommand>) -> Self {
142 let mut connection = Self::new();
143 connection.outgoing_tx = Some(tx);
144 connection
145 }
146
147 pub fn from_udp(socket: Arc<tokio::net::UdpSocket>, remote_addr: SocketAddr) -> Self {
149 let local_addr = socket.local_addr().ok();
150 let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
151 let receive_socket = Arc::clone(&socket);
152 let receive_tx = tx.clone();
153 tokio::spawn(async move {
154 let mut packet = vec![0_u8; 65_535];
155 while let Ok((length, peer)) = receive_socket.recv_from(&mut packet).await {
156 if peer == remote_addr
157 && receive_tx
158 .send(Bytes::copy_from_slice(&packet[..length]))
159 .is_err()
160 {
161 break;
162 }
163 }
164 });
165 let mut conn = Self::from_datagrams(socket, remote_addr, rx);
166 conn.local_addr = local_addr;
167 conn
168 }
169
170 pub fn from_datagrams(
172 socket: Arc<tokio::net::UdpSocket>,
173 remote_addr: SocketAddr,
174 rx: tokio::sync::mpsc::UnboundedReceiver<Bytes>,
175 ) -> Self {
176 let local_addr = socket.local_addr().ok();
177 let connection = Self::new();
178 Self {
179 socket: Some(socket),
180 remote_addr: Some(remote_addr),
181 local_addr,
182 datagrams: Arc::new(Mutex::new(rx)),
183 ..connection
184 }
185 }
186
187 pub fn remote_address(&self) -> Option<SocketAddr> {
189 self.remote_addr
190 }
191
192 pub fn local_address(&self) -> Option<SocketAddr> {
194 self.local_addr
195 }
196
197 pub fn is_closed(&self) -> bool {
199 self.closed.load(Ordering::Acquire)
200 }
201
202 pub fn connection_id(&self) -> ConnectionId {
204 self.connection_id
205 }
206
207 pub async fn stats(&self) -> ConnectionStats {
209 self.stats.lock().await.clone()
210 }
211
212 pub async fn rtt(&self) -> Duration {
214 self.stats.lock().await.smoothed_rtt
215 }
216
217 pub async fn congestion_window(&self) -> u64 {
219 self.stats.lock().await.congestion_window
220 }
221
222 pub fn max_datagram_size(&self) -> usize {
224 1200
225 }
226
227 pub async fn handshake_data(&self) -> Option<HandshakeData> {
229 self.handshake_data.lock().await.clone()
230 }
231
232 pub async fn peer_identity(&self) -> Option<Vec<rustls::pki_types::CertificateDer<'static>>> {
234 self.peer_identity.lock().await.clone()
235 }
236
237 pub fn set_max_concurrent_uni_streams(&self, n: u64) {
239 self.max_uni_streams.store(n, Ordering::Release);
240 }
241
242 pub fn set_max_concurrent_bi_streams(&self, n: u64) {
244 self.max_bi_streams.store(n, Ordering::Release);
245 }
246
247 pub async fn open_bi(&self) -> std::io::Result<(SendStream, RecvStream)> {
249 self.ensure_open()?;
250 if let Some(tx) = self.outgoing_tx.as_ref() {
251 let id = self.next_server_bi.fetch_add(4, Ordering::Relaxed);
252 let (_, recv) = SendStream::pair();
253 return Ok((SendStream::network(tx.clone(), id), recv));
254 }
255 Ok(SendStream::pair())
256 }
257
258 pub async fn open_uni(&self) -> std::io::Result<SendStream> {
260 self.ensure_open()?;
261 if let Some(tx) = self.outgoing_tx.as_ref() {
262 let id = self.next_server_uni.fetch_add(4, Ordering::Relaxed);
263 return Ok(SendStream::network(tx.clone(), id));
264 }
265 let (send, recv) = SendStream::pair();
266 self.incoming_uni.lock().await.push_back(recv);
267 self.incoming_uni_notify.notify_one();
268 Ok(send)
269 }
270
271 pub async fn accept_bi(&self) -> std::io::Result<(SendStream, RecvStream)> {
273 loop {
274 self.ensure_open()?;
275 if let Some(stream) = self.incoming_bi.lock().await.pop_front() {
276 return Ok(stream);
277 }
278 self.incoming_bi_notify.notified().await;
279 }
280 }
281
282 pub async fn accept_uni(&self) -> std::io::Result<RecvStream> {
284 loop {
285 self.ensure_open()?;
286 if let Some(stream) = self.incoming_uni.lock().await.pop_front() {
287 return Ok(stream);
288 }
289 self.incoming_uni_notify.notified().await;
290 }
291 }
292
293 pub async fn send_datagram(&self, data: bytes::Bytes) -> std::io::Result<()> {
295 self.ensure_open()?;
296 let len = data.len() as u64;
297 match (&self.socket, self.remote_addr) {
298 (Some(socket), Some(remote_addr)) => {
299 socket.send_to(&data, remote_addr).await.map(|_| ())?;
300 let mut stats = self.stats.lock().await;
301 stats.packets_sent += 1;
302 stats.bytes_sent += len;
303 Ok(())
304 }
305 _ => Err(std::io::Error::new(
306 std::io::ErrorKind::NotConnected,
307 "connection has no UDP path",
308 )),
309 }
310 }
311
312 pub async fn send_datagram_wait(&self, data: bytes::Bytes) -> std::io::Result<()> {
314 self.send_datagram(data).await
315 }
316
317 pub async fn recv_datagram(&self) -> std::io::Result<Bytes> {
319 self.ensure_open()?;
320 let data = self.datagrams.lock().await.recv().await.ok_or_else(|| {
321 std::io::Error::new(
322 std::io::ErrorKind::UnexpectedEof,
323 "connection receive queue closed",
324 )
325 })?;
326 let len = data.len() as u64;
327 let mut stats = self.stats.lock().await;
328 stats.packets_received += 1;
329 stats.bytes_received += len;
330 Ok(data)
331 }
332
333 pub async fn ingest_frames(&self, mut payload: &[u8]) -> std::io::Result<()> {
335 while !payload.is_empty() {
336 let before = payload.len();
337 let frame = Frame::decode(&mut payload)
338 .map_err(|error| std::io::Error::new(std::io::ErrorKind::InvalidData, error))?;
339 match frame {
340 Frame::Datagram(frame) => self.datagram_tx.send(frame.data).map_err(|_| {
341 std::io::Error::new(
342 std::io::ErrorKind::BrokenPipe,
343 "connection receive queue closed",
344 )
345 })?,
346 Frame::Padding | Frame::Ping | Frame::Ack(_) => {}
347 Frame::ConnectionClose(close_frame) => {
348 let info = ConnectionCloseInfo {
349 error_code: close_frame.error_code.into_inner(),
350 reason: close_frame.reason,
351 from_peer: true,
352 };
353 *self.close_info.lock().await = Some(info);
354 self.close().await;
355 return Ok(());
356 }
357 Frame::Stream(frame) => {
358 let stream_id = frame.stream_id.into_inner().into_inner();
359 let mut streams = self.stream_inputs.lock().await;
360 if let Some(input) = streams.get_mut(&stream_id) {
361 if frame.offset.into_inner() != input.next_offset {
362 return Err(std::io::Error::new(
363 std::io::ErrorKind::InvalidData,
364 "out-of-order STREAM frame",
365 ));
366 }
367 input.next_offset += frame.data.len() as u64;
368 input
369 .tx
370 .send(Some(frame.data.to_vec()))
371 .map_err(|_| {
372 std::io::Error::new(
373 std::io::ErrorKind::BrokenPipe,
374 "stream receiver closed",
375 )
376 })?;
377 if frame.fin {
378 let _ = input.tx.send(None);
379 }
380 } else {
381 let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
382 tx.send(Some(frame.data.to_vec())).map_err(|_| {
383 std::io::Error::new(
384 std::io::ErrorKind::BrokenPipe,
385 "stream receiver closed",
386 )
387 })?;
388 let recv = RecvStream::from_receiver_with_id(
389 rx,
390 stream_id,
391 self.outgoing_tx.clone(),
392 );
393 let uni = stream_id & 0b10 != 0;
394 if uni {
395 self.incoming_uni.lock().await.push_back(recv);
396 self.incoming_uni_notify.notify_one();
397 } else {
398 let send = if let Some(tx) = self.outgoing_tx.as_ref() {
399 SendStream::network(tx.clone(), stream_id)
400 } else {
401 SendStream::pair().0
402 };
403 self.incoming_bi.lock().await.push_back((send, recv));
404 self.incoming_bi_notify.notify_one();
405 }
406 if !frame.fin {
407 streams.insert(
408 stream_id,
409 StreamInput {
410 tx,
411 next_offset: frame.offset.into_inner()
412 + frame.data.len() as u64,
413 },
414 );
415 } else {
416 let _ = tx.send(None);
417 }
418 }
419 }
420 _ => {
421 return Err(std::io::Error::new(
422 std::io::ErrorKind::Unsupported,
423 "QUIC control frame handling is not enabled",
424 ));
425 }
426 }
427 if payload.len() == before {
428 return Err(std::io::Error::new(
429 std::io::ErrorKind::InvalidData,
430 "frame decoder made no progress",
431 ));
432 }
433 }
434 Ok(())
435 }
436
437 pub async fn close_with(&self, code: u64, reason: &[u8]) {
439 if !self.closed.swap(true, Ordering::AcqRel) {
440 *self.close_info.lock().await = Some(ConnectionCloseInfo {
441 error_code: code,
442 reason: Bytes::copy_from_slice(reason),
443 from_peer: false,
444 });
445 self.incoming_bi_notify.notify_waiters();
446 self.incoming_uni_notify.notify_waiters();
447 self.closed_notify.notify_waiters();
448 }
449 }
450
451 pub async fn close(&self) {
453 self.close_with(0, b"").await;
454 }
455
456 pub async fn closed(&self) -> ConnectionCloseInfo {
458 while !self.is_closed() {
459 self.closed_notify.notified().await;
460 }
461 self.close_info
462 .lock()
463 .await
464 .clone()
465 .unwrap_or(ConnectionCloseInfo {
466 error_code: 0,
467 reason: Bytes::new(),
468 from_peer: false,
469 })
470 }
471
472 pub async fn close_reason(&self) -> Option<ConnectionCloseInfo> {
474 if self.is_closed() {
475 self.close_info.lock().await.clone()
476 } else {
477 None
478 }
479 }
480
481 fn ensure_open(&self) -> std::io::Result<()> {
482 if self.closed.load(Ordering::Acquire) {
483 Err(std::io::Error::new(
484 std::io::ErrorKind::NotConnected,
485 "connection is closed",
486 ))
487 } else {
488 Ok(())
489 }
490 }
491}
492
493impl Default for Connection {
494 fn default() -> Self {
495 Self::new()
496 }
497}