quiche/
lib.rs

1// Copyright (C) 2018-2019, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright notice,
9//       this list of conditions and the following disclaimer.
10//
11//     * Redistributions in binary form must reproduce the above copyright
12//       notice, this list of conditions and the following disclaimer in the
13//       documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27//! 🥧 Savoury implementation of the QUIC transport protocol and HTTP/3.
28//!
29//! [quiche] is an implementation of the QUIC transport protocol and HTTP/3 as
30//! specified by the [IETF]. It provides a low level API for processing QUIC
31//! packets and handling connection state. The application is responsible for
32//! providing I/O (e.g. sockets handling) as well as an event loop with support
33//! for timers.
34//!
35//! [quiche]: https://github.com/cloudflare/quiche/
36//! [ietf]: https://quicwg.org/
37//!
38//! ## Configuring connections
39//!
40//! The first step in establishing a QUIC connection using quiche is creating a
41//! [`Config`] object:
42//!
43//! ```
44//! let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
45//! config.set_application_protos(&[b"example-proto"]);
46//!
47//! // Additional configuration specific to application and use case...
48//! # Ok::<(), quiche::Error>(())
49//! ```
50//!
51//! The [`Config`] object controls important aspects of the QUIC connection such
52//! as QUIC version, ALPN IDs, flow control, congestion control, idle timeout
53//! and other properties or features.
54//!
55//! QUIC is a general-purpose transport protocol and there are several
56//! configuration properties where there is no reasonable default value. For
57//! example, the permitted number of concurrent streams of any particular type
58//! is dependent on the application running over QUIC, and other use-case
59//! specific concerns.
60//!
61//! quiche defaults several properties to zero, applications most likely need
62//! to set these to something else to satisfy their needs using the following:
63//!
64//! - [`set_initial_max_streams_bidi()`]
65//! - [`set_initial_max_streams_uni()`]
66//! - [`set_initial_max_data()`]
67//! - [`set_initial_max_stream_data_bidi_local()`]
68//! - [`set_initial_max_stream_data_bidi_remote()`]
69//! - [`set_initial_max_stream_data_uni()`]
70//!
71//! [`Config`] also holds TLS configuration. This can be changed by mutators on
72//! the an existing object, or by constructing a TLS context manually and
73//! creating a configuration using [`with_boring_ssl_ctx_builder()`].
74//!
75//! A configuration object can be shared among multiple connections.
76//!
77//! ### Connection setup
78//!
79//! On the client-side the [`connect()`] utility function can be used to create
80//! a new connection, while [`accept()`] is for servers:
81//!
82//! ```
83//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
84//! # let server_name = "quic.tech";
85//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
86//! # let peer = "127.0.0.1:1234".parse().unwrap();
87//! # let local = "127.0.0.1:4321".parse().unwrap();
88//! // Client connection.
89//! let conn =
90//!     quiche::connect(Some(&server_name), &scid, local, peer, &mut config)?;
91//!
92//! // Server connection.
93//! # let peer = "127.0.0.1:1234".parse().unwrap();
94//! # let local = "127.0.0.1:4321".parse().unwrap();
95//! let conn = quiche::accept(&scid, None, local, peer, &mut config)?;
96//! # Ok::<(), quiche::Error>(())
97//! ```
98//!
99//! In both cases, the application is responsible for generating a new source
100//! connection ID that will be used to identify the new connection.
101//!
102//! The application also need to pass the address of the remote peer of the
103//! connection: in the case of a client that would be the address of the server
104//! it is trying to connect to, and for a server that is the address of the
105//! client that initiated the connection.
106//!
107//! ## Handling incoming packets
108//!
109//! Using the connection's [`recv()`] method the application can process
110//! incoming packets that belong to that connection from the network:
111//!
112//! ```no_run
113//! # let mut buf = [0; 512];
114//! # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
115//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
116//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
117//! # let peer = "127.0.0.1:1234".parse().unwrap();
118//! # let local = "127.0.0.1:4321".parse().unwrap();
119//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
120//! let to = socket.local_addr().unwrap();
121//!
122//! loop {
123//!     let (read, from) = socket.recv_from(&mut buf).unwrap();
124//!
125//!     let recv_info = quiche::RecvInfo { from, to };
126//!
127//!     let read = match conn.recv(&mut buf[..read], recv_info) {
128//!         Ok(v) => v,
129//!
130//!         Err(quiche::Error::Done) => {
131//!             // Done reading.
132//!             break;
133//!         },
134//!
135//!         Err(e) => {
136//!             // An error occurred, handle it.
137//!             break;
138//!         },
139//!     };
140//! }
141//! # Ok::<(), quiche::Error>(())
142//! ```
143//!
144//! The application has to pass a [`RecvInfo`] structure in order to provide
145//! additional information about the received packet (such as the address it
146//! was received from).
147//!
148//! ## Generating outgoing packets
149//!
150//! Outgoing packet are generated using the connection's [`send()`] method
151//! instead:
152//!
153//! ```no_run
154//! # let mut out = [0; 512];
155//! # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
156//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
157//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
158//! # let peer = "127.0.0.1:1234".parse().unwrap();
159//! # let local = "127.0.0.1:4321".parse().unwrap();
160//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
161//! loop {
162//!     let (write, send_info) = match conn.send(&mut out) {
163//!         Ok(v) => v,
164//!
165//!         Err(quiche::Error::Done) => {
166//!             // Done writing.
167//!             break;
168//!         },
169//!
170//!         Err(e) => {
171//!             // An error occurred, handle it.
172//!             break;
173//!         },
174//!     };
175//!
176//!     socket.send_to(&out[..write], &send_info.to).unwrap();
177//! }
178//! # Ok::<(), quiche::Error>(())
179//! ```
180//!
181//! The application will be provided with a [`SendInfo`] structure providing
182//! additional information about the newly created packet (such as the address
183//! the packet should be sent to).
184//!
185//! When packets are sent, the application is responsible for maintaining a
186//! timer to react to time-based connection events. The timer expiration can be
187//! obtained using the connection's [`timeout()`] method.
188//!
189//! ```
190//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
191//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
192//! # let peer = "127.0.0.1:1234".parse().unwrap();
193//! # let local = "127.0.0.1:4321".parse().unwrap();
194//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
195//! let timeout = conn.timeout();
196//! # Ok::<(), quiche::Error>(())
197//! ```
198//!
199//! The application is responsible for providing a timer implementation, which
200//! can be specific to the operating system or networking framework used. When
201//! a timer expires, the connection's [`on_timeout()`] method should be called,
202//! after which additional packets might need to be sent on the network:
203//!
204//! ```no_run
205//! # let mut out = [0; 512];
206//! # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
207//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
208//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
209//! # let peer = "127.0.0.1:1234".parse().unwrap();
210//! # let local = "127.0.0.1:4321".parse().unwrap();
211//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
212//! // Timeout expired, handle it.
213//! conn.on_timeout();
214//!
215//! // Send more packets as needed after timeout.
216//! loop {
217//!     let (write, send_info) = match conn.send(&mut out) {
218//!         Ok(v) => v,
219//!
220//!         Err(quiche::Error::Done) => {
221//!             // Done writing.
222//!             break;
223//!         },
224//!
225//!         Err(e) => {
226//!             // An error occurred, handle it.
227//!             break;
228//!         },
229//!     };
230//!
231//!     socket.send_to(&out[..write], &send_info.to).unwrap();
232//! }
233//! # Ok::<(), quiche::Error>(())
234//! ```
235//!
236//! ### Pacing
237//!
238//! It is recommended that applications [pace] sending of outgoing packets to
239//! avoid creating packet bursts that could cause short-term congestion and
240//! losses in the network.
241//!
242//! quiche exposes pacing hints for outgoing packets through the [`at`] field
243//! of the [`SendInfo`] structure that is returned by the [`send()`] method.
244//! This field represents the time when a specific packet should be sent into
245//! the network.
246//!
247//! Applications can use these hints by artificially delaying the sending of
248//! packets through platform-specific mechanisms (such as the [`SO_TXTIME`]
249//! socket option on Linux), or custom methods (for example by using user-space
250//! timers).
251//!
252//! [pace]: https://datatracker.ietf.org/doc/html/rfc9002#section-7.7
253//! [`SO_TXTIME`]: https://man7.org/linux/man-pages/man8/tc-etf.8.html
254//!
255//! ## Sending and receiving stream data
256//!
257//! After some back and forth, the connection will complete its handshake and
258//! will be ready for sending or receiving application data.
259//!
260//! Data can be sent on a stream by using the [`stream_send()`] method:
261//!
262//! ```no_run
263//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
264//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
265//! # let peer = "127.0.0.1:1234".parse().unwrap();
266//! # let local = "127.0.0.1:4321".parse().unwrap();
267//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
268//! if conn.is_established() {
269//!     // Handshake completed, send some data on stream 0.
270//!     conn.stream_send(0, b"hello", true)?;
271//! }
272//! # Ok::<(), quiche::Error>(())
273//! ```
274//!
275//! The application can check whether there are any readable streams by using
276//! the connection's [`readable()`] method, which returns an iterator over all
277//! the streams that have outstanding data to read.
278//!
279//! The [`stream_recv()`] method can then be used to retrieve the application
280//! data from the readable stream:
281//!
282//! ```no_run
283//! # let mut buf = [0; 512];
284//! # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
285//! # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
286//! # let peer = "127.0.0.1:1234".parse().unwrap();
287//! # let local = "127.0.0.1:4321".parse().unwrap();
288//! # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
289//! if conn.is_established() {
290//!     // Iterate over readable streams.
291//!     for stream_id in conn.readable() {
292//!         // Stream is readable, read until there's no more data.
293//!         while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
294//!             println!("Got {} bytes on stream {}", read, stream_id);
295//!         }
296//!     }
297//! }
298//! # Ok::<(), quiche::Error>(())
299//! ```
300//!
301//! ## HTTP/3
302//!
303//! The quiche [HTTP/3 module] provides a high level API for sending and
304//! receiving HTTP requests and responses on top of the QUIC transport protocol.
305//!
306//! [`Config`]: https://docs.quic.tech/quiche/struct.Config.html
307//! [`set_initial_max_streams_bidi()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_streams_bidi
308//! [`set_initial_max_streams_uni()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_streams_uni
309//! [`set_initial_max_data()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data
310//! [`set_initial_max_stream_data_bidi_local()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_stream_data_bidi_local
311//! [`set_initial_max_stream_data_bidi_remote()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_stream_data_bidi_remote
312//! [`set_initial_max_stream_data_uni()`]: https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_stream_data_uni
313//! [`with_boring_ssl_ctx_builder()`]: https://docs.quic.tech/quiche/struct.Config.html#method.with_boring_ssl_ctx_builder
314//! [`connect()`]: fn.connect.html
315//! [`accept()`]: fn.accept.html
316//! [`recv()`]: struct.Connection.html#method.recv
317//! [`RecvInfo`]: struct.RecvInfo.html
318//! [`send()`]: struct.Connection.html#method.send
319//! [`SendInfo`]: struct.SendInfo.html
320//! [`at`]: struct.SendInfo.html#structfield.at
321//! [`timeout()`]: struct.Connection.html#method.timeout
322//! [`on_timeout()`]: struct.Connection.html#method.on_timeout
323//! [`stream_send()`]: struct.Connection.html#method.stream_send
324//! [`readable()`]: struct.Connection.html#method.readable
325//! [`stream_recv()`]: struct.Connection.html#method.stream_recv
326//! [HTTP/3 module]: h3/index.html
327//!
328//! ## Congestion Control
329//!
330//! The quiche library provides a high-level API for configuring which
331//! congestion control algorithm to use throughout the QUIC connection.
332//!
333//! When a QUIC connection is created, the application can optionally choose
334//! which CC algorithm to use. See [`CongestionControlAlgorithm`] for currently
335//! available congestion control algorithms.
336//!
337//! For example:
338//!
339//! ```
340//! let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION).unwrap();
341//! config.set_cc_algorithm(quiche::CongestionControlAlgorithm::Reno);
342//! ```
343//!
344//! Alternatively, you can configure the congestion control algorithm to use
345//! by its name.
346//!
347//! ```
348//! let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION).unwrap();
349//! config.set_cc_algorithm_name("reno").unwrap();
350//! ```
351//!
352//! Note that the CC algorithm should be configured before calling [`connect()`]
353//! or [`accept()`]. Otherwise the connection will use a default CC algorithm.
354//!
355//! [`CongestionControlAlgorithm`]: enum.CongestionControlAlgorithm.html
356//!
357//! ## Feature flags
358//!
359//! quiche defines a number of [feature flags] to reduce the amount of compiled
360//! code and dependencies:
361//!
362//! * `boringssl-vendored` (default): Build the vendored BoringSSL library.
363//!
364//! * `boringssl-boring-crate`: Use the BoringSSL library provided by the
365//!   [boring] crate. It takes precedence over `boringssl-vendored` if both
366//!   features are enabled.
367//!
368//! * `pkg-config-meta`: Generate pkg-config metadata file for libquiche.
369//!
370//! * `ffi`: Build and expose the FFI API.
371//!
372//! * `qlog`: Enable support for the [qlog] logging format.
373//!
374//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
375//! [boring]: https://crates.io/crates/boring
376//! [qlog]: https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema
377
378#![allow(clippy::upper_case_acronyms)]
379#![warn(missing_docs)]
380#![warn(unused_qualifications)]
381#![cfg_attr(docsrs, feature(doc_cfg))]
382
383#[macro_use]
384extern crate log;
385
386use std::cmp;
387
388use std::collections::HashSet;
389use std::collections::VecDeque;
390
391use std::convert::TryInto;
392
393use std::net::SocketAddr;
394
395use std::str::FromStr;
396
397use std::sync::Arc;
398
399use std::time::Duration;
400use std::time::Instant;
401
402#[cfg(feature = "qlog")]
403use qlog::events::connectivity::ConnectivityEventType;
404#[cfg(feature = "qlog")]
405use qlog::events::connectivity::TransportOwner;
406#[cfg(feature = "qlog")]
407use qlog::events::quic::RecoveryEventType;
408#[cfg(feature = "qlog")]
409use qlog::events::quic::TransportEventType;
410#[cfg(feature = "qlog")]
411use qlog::events::DataRecipient;
412#[cfg(feature = "qlog")]
413use qlog::events::Event;
414#[cfg(feature = "qlog")]
415use qlog::events::EventData;
416#[cfg(feature = "qlog")]
417use qlog::events::EventImportance;
418#[cfg(feature = "qlog")]
419use qlog::events::EventType;
420#[cfg(feature = "qlog")]
421use qlog::events::RawInfo;
422
423use smallvec::SmallVec;
424
425use crate::range_buf::DefaultBufFactory;
426
427use crate::recovery::OnAckReceivedOutcome;
428use crate::recovery::OnLossDetectionTimeoutOutcome;
429use crate::recovery::RecoveryOps;
430use crate::recovery::ReleaseDecision;
431
432use crate::stream::StreamPriorityKey;
433
434/// The current QUIC wire version.
435pub const PROTOCOL_VERSION: u32 = PROTOCOL_VERSION_V1;
436
437/// Supported QUIC versions.
438const PROTOCOL_VERSION_V1: u32 = 0x0000_0001;
439
440/// The maximum length of a connection ID.
441pub const MAX_CONN_ID_LEN: usize = packet::MAX_CID_LEN as usize;
442
443/// The minimum length of Initial packets sent by a client.
444pub const MIN_CLIENT_INITIAL_LEN: usize = 1200;
445
446/// The default initial RTT.
447const DEFAULT_INITIAL_RTT: Duration = Duration::from_millis(333);
448
449#[cfg(not(feature = "fuzzing"))]
450const PAYLOAD_MIN_LEN: usize = 4;
451
452#[cfg(feature = "fuzzing")]
453// Due to the fact that in fuzzing mode we use a zero-length AEAD tag (which
454// would normally be 16 bytes), we need to adjust the minimum payload size to
455// account for that.
456const PAYLOAD_MIN_LEN: usize = 20;
457
458// PATH_CHALLENGE (9 bytes) + AEAD tag (16 bytes).
459const MIN_PROBING_SIZE: usize = 25;
460
461const MAX_AMPLIFICATION_FACTOR: usize = 3;
462
463// The maximum number of tracked packet number ranges that need to be acked.
464//
465// This represents more or less how many ack blocks can fit in a typical packet.
466const MAX_ACK_RANGES: usize = 68;
467
468// The highest possible stream ID allowed.
469const MAX_STREAM_ID: u64 = 1 << 60;
470
471// The default max_datagram_size used in congestion control.
472const MAX_SEND_UDP_PAYLOAD_SIZE: usize = 1200;
473
474// The default length of DATAGRAM queues.
475const DEFAULT_MAX_DGRAM_QUEUE_LEN: usize = 0;
476
477// The default length of PATH_CHALLENGE receive queue.
478const DEFAULT_MAX_PATH_CHALLENGE_RX_QUEUE_LEN: usize = 3;
479
480// The DATAGRAM standard recommends either none or 65536 as maximum DATAGRAM
481// frames size. We enforce the recommendation for forward compatibility.
482const MAX_DGRAM_FRAME_SIZE: u64 = 65536;
483
484// The length of the payload length field.
485const PAYLOAD_LENGTH_LEN: usize = 2;
486
487// The number of undecryptable that can be buffered.
488const MAX_UNDECRYPTABLE_PACKETS: usize = 10;
489
490const RESERVED_VERSION_MASK: u32 = 0xfafafafa;
491
492// The default size of the receiver connection flow control window.
493const DEFAULT_CONNECTION_WINDOW: u64 = 48 * 1024;
494
495// The maximum size of the receiver connection flow control window.
496const MAX_CONNECTION_WINDOW: u64 = 24 * 1024 * 1024;
497
498// How much larger the connection flow control window need to be larger than
499// the stream flow control window.
500const CONNECTION_WINDOW_FACTOR: f64 = 1.5;
501
502// How many probing packet timeouts do we tolerate before considering the path
503// validation as failed.
504const MAX_PROBING_TIMEOUTS: usize = 3;
505
506// The default initial congestion window size in terms of packet count.
507const DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS: usize = 10;
508
509// The maximum data offset that can be stored in a crypto stream.
510const MAX_CRYPTO_STREAM_OFFSET: u64 = 1 << 16;
511
512// The send capacity factor.
513const TX_CAP_FACTOR: f64 = 1.0;
514
515/// A specialized [`Result`] type for quiche operations.
516///
517/// This type is used throughout quiche's public API for any operation that
518/// can produce an error.
519///
520/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
521pub type Result<T> = std::result::Result<T, Error>;
522
523/// A QUIC error.
524#[derive(Clone, Copy, Debug, PartialEq, Eq)]
525pub enum Error {
526    /// There is no more work to do.
527    Done,
528
529    /// The provided buffer is too short.
530    BufferTooShort,
531
532    /// The provided packet cannot be parsed because its version is unknown.
533    UnknownVersion,
534
535    /// The provided packet cannot be parsed because it contains an invalid
536    /// frame.
537    InvalidFrame,
538
539    /// The provided packet cannot be parsed.
540    InvalidPacket,
541
542    /// The operation cannot be completed because the connection is in an
543    /// invalid state.
544    InvalidState,
545
546    /// The operation cannot be completed because the stream is in an
547    /// invalid state.
548    ///
549    /// The stream ID is provided as associated data.
550    InvalidStreamState(u64),
551
552    /// The peer's transport params cannot be parsed.
553    InvalidTransportParam,
554
555    /// A cryptographic operation failed.
556    CryptoFail,
557
558    /// The TLS handshake failed.
559    TlsFail,
560
561    /// The peer violated the local flow control limits.
562    FlowControl,
563
564    /// The peer violated the local stream limits.
565    StreamLimit,
566
567    /// The specified stream was stopped by the peer.
568    ///
569    /// The error code sent as part of the `STOP_SENDING` frame is provided as
570    /// associated data.
571    StreamStopped(u64),
572
573    /// The specified stream was reset by the peer.
574    ///
575    /// The error code sent as part of the `RESET_STREAM` frame is provided as
576    /// associated data.
577    StreamReset(u64),
578
579    /// The received data exceeds the stream's final size.
580    FinalSize,
581
582    /// Error in congestion control.
583    CongestionControl,
584
585    /// Too many identifiers were provided.
586    IdLimit,
587
588    /// Not enough available identifiers.
589    OutOfIdentifiers,
590
591    /// Error in key update.
592    KeyUpdate,
593
594    /// The peer sent more data in CRYPTO frames than we can buffer.
595    CryptoBufferExceeded,
596
597    /// The peer sent an ACK frame with an invalid range.
598    InvalidAckRange,
599
600    /// The peer send an ACK frame for a skipped packet used for Optimistic ACK
601    /// mitigation.
602    OptimisticAckDetected,
603}
604
605/// QUIC error codes sent on the wire.
606///
607/// As defined in [RFC9000](https://www.rfc-editor.org/rfc/rfc9000.html#name-error-codes).
608#[derive(Copy, Clone, Debug, Eq, PartialEq)]
609pub enum WireErrorCode {
610    /// An endpoint uses this with CONNECTION_CLOSE to signal that the
611    /// connection is being closed abruptly in the absence of any error.
612    NoError              = 0x0,
613    /// The endpoint encountered an internal error and cannot continue with the
614    /// connection.
615    InternalError        = 0x1,
616    /// The server refused to accept a new connection.
617    ConnectionRefused    = 0x2,
618    /// An endpoint received more data than it permitted in its advertised data
619    /// limits; see Section 4.
620    FlowControlError     = 0x3,
621    /// An endpoint received a frame for a stream identifier that exceeded its
622    /// advertised stream limit for the corresponding stream type.
623    StreamLimitError     = 0x4,
624    /// An endpoint received a frame for a stream that was not in a state that
625    /// permitted that frame.
626    StreamStateError     = 0x5,
627    /// (1) An endpoint received a STREAM frame containing data that exceeded
628    /// the previously established final size, (2) an endpoint received a
629    /// STREAM frame or a RESET_STREAM frame containing a final size that
630    /// was lower than the size of stream data that was already received, or
631    /// (3) an endpoint received a STREAM frame or a RESET_STREAM frame
632    /// containing a different final size to the one already established.
633    FinalSizeError       = 0x6,
634    /// An endpoint received a frame that was badly formatted -- for instance, a
635    /// frame of an unknown type or an ACK frame that has more
636    /// acknowledgment ranges than the remainder of the packet could carry.
637    FrameEncodingError   = 0x7,
638    /// An endpoint received transport parameters that were badly formatted,
639    /// included an invalid value, omitted a mandatory transport parameter,
640    /// included a forbidden transport parameter, or were otherwise in
641    /// error.
642    TransportParameterError = 0x8,
643    /// An endpoint received transport parameters that were badly formatted,
644    /// included an invalid value, omitted a mandatory transport parameter,
645    /// included a forbidden transport parameter, or were otherwise in
646    /// error.
647    ConnectionIdLimitError = 0x9,
648    /// An endpoint detected an error with protocol compliance that was not
649    /// covered by more specific error codes.
650    ProtocolViolation    = 0xa,
651    /// A server received a client Initial that contained an invalid Token
652    /// field.
653    InvalidToken         = 0xb,
654    /// The application or application protocol caused the connection to be
655    /// closed.
656    ApplicationError     = 0xc,
657    /// An endpoint has received more data in CRYPTO frames than it can buffer.
658    CryptoBufferExceeded = 0xd,
659    /// An endpoint detected errors in performing key updates.
660    KeyUpdateError       = 0xe,
661    /// An endpoint has reached the confidentiality or integrity limit for the
662    /// AEAD algorithm used by the given connection.
663    AeadLimitReached     = 0xf,
664    /// An endpoint has determined that the network path is incapable of
665    /// supporting QUIC. An endpoint is unlikely to receive a
666    /// CONNECTION_CLOSE frame carrying this code except when the path does
667    /// not support a large enough MTU.
668    NoViablePath         = 0x10,
669}
670
671impl Error {
672    fn to_wire(self) -> u64 {
673        match self {
674            Error::Done => WireErrorCode::NoError as u64,
675            Error::InvalidFrame => WireErrorCode::FrameEncodingError as u64,
676            Error::InvalidStreamState(..) =>
677                WireErrorCode::StreamStateError as u64,
678            Error::InvalidTransportParam =>
679                WireErrorCode::TransportParameterError as u64,
680            Error::FlowControl => WireErrorCode::FlowControlError as u64,
681            Error::StreamLimit => WireErrorCode::StreamLimitError as u64,
682            Error::IdLimit => WireErrorCode::ConnectionIdLimitError as u64,
683            Error::FinalSize => WireErrorCode::FinalSizeError as u64,
684            Error::CryptoBufferExceeded =>
685                WireErrorCode::CryptoBufferExceeded as u64,
686            Error::KeyUpdate => WireErrorCode::KeyUpdateError as u64,
687            _ => WireErrorCode::ProtocolViolation as u64,
688        }
689    }
690
691    #[cfg(feature = "ffi")]
692    fn to_c(self) -> libc::ssize_t {
693        match self {
694            Error::Done => -1,
695            Error::BufferTooShort => -2,
696            Error::UnknownVersion => -3,
697            Error::InvalidFrame => -4,
698            Error::InvalidPacket => -5,
699            Error::InvalidState => -6,
700            Error::InvalidStreamState(_) => -7,
701            Error::InvalidTransportParam => -8,
702            Error::CryptoFail => -9,
703            Error::TlsFail => -10,
704            Error::FlowControl => -11,
705            Error::StreamLimit => -12,
706            Error::FinalSize => -13,
707            Error::CongestionControl => -14,
708            Error::StreamStopped { .. } => -15,
709            Error::StreamReset { .. } => -16,
710            Error::IdLimit => -17,
711            Error::OutOfIdentifiers => -18,
712            Error::KeyUpdate => -19,
713            Error::CryptoBufferExceeded => -20,
714            Error::InvalidAckRange => -21,
715            Error::OptimisticAckDetected => -22,
716        }
717    }
718}
719
720impl std::fmt::Display for Error {
721    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
722        write!(f, "{self:?}")
723    }
724}
725
726impl std::error::Error for Error {
727    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
728        None
729    }
730}
731
732impl From<octets::BufferTooShortError> for Error {
733    fn from(_err: octets::BufferTooShortError) -> Self {
734        Error::BufferTooShort
735    }
736}
737
738/// Ancillary information about incoming packets.
739#[derive(Clone, Copy, Debug, PartialEq, Eq)]
740pub struct RecvInfo {
741    /// The remote address the packet was received from.
742    pub from: SocketAddr,
743
744    /// The local address the packet was received on.
745    pub to: SocketAddr,
746}
747
748/// Ancillary information about outgoing packets.
749#[derive(Clone, Copy, Debug, PartialEq, Eq)]
750pub struct SendInfo {
751    /// The local address the packet should be sent from.
752    pub from: SocketAddr,
753
754    /// The remote address the packet should be sent to.
755    pub to: SocketAddr,
756
757    /// The time to send the packet out.
758    ///
759    /// See [Pacing] for more details.
760    ///
761    /// [Pacing]: index.html#pacing
762    pub at: Instant,
763}
764
765/// Represents information carried by `CONNECTION_CLOSE` frames.
766#[derive(Clone, Debug, PartialEq, Eq)]
767pub struct ConnectionError {
768    /// Whether the error came from the application or the transport layer.
769    pub is_app: bool,
770
771    /// The error code carried by the `CONNECTION_CLOSE` frame.
772    pub error_code: u64,
773
774    /// The reason carried by the `CONNECTION_CLOSE` frame.
775    pub reason: Vec<u8>,
776}
777
778/// The side of the stream to be shut down.
779///
780/// This should be used when calling [`stream_shutdown()`].
781///
782/// [`stream_shutdown()`]: struct.Connection.html#method.stream_shutdown
783#[repr(C)]
784#[derive(PartialEq, Eq)]
785pub enum Shutdown {
786    /// Stop receiving stream data.
787    Read  = 0,
788
789    /// Stop sending stream data.
790    Write = 1,
791}
792
793/// Qlog logging level.
794#[repr(C)]
795#[cfg(feature = "qlog")]
796#[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
797pub enum QlogLevel {
798    /// Logs any events of Core importance.
799    Core  = 0,
800
801    /// Logs any events of Core and Base importance.
802    Base  = 1,
803
804    /// Logs any events of Core, Base and Extra importance
805    Extra = 2,
806}
807
808/// Stores configuration shared between multiple connections.
809pub struct Config {
810    local_transport_params: TransportParams,
811
812    version: u32,
813
814    tls_ctx: tls::Context,
815
816    application_protos: Vec<Vec<u8>>,
817
818    grease: bool,
819
820    cc_algorithm: CongestionControlAlgorithm,
821    custom_bbr_params: Option<BbrParams>,
822    initial_congestion_window_packets: usize,
823    enable_relaxed_loss_threshold: bool,
824
825    pmtud: bool,
826
827    hystart: bool,
828
829    pacing: bool,
830    /// Send rate limit in Mbps
831    max_pacing_rate: Option<u64>,
832
833    tx_cap_factor: f64,
834
835    dgram_recv_max_queue_len: usize,
836    dgram_send_max_queue_len: usize,
837
838    path_challenge_recv_max_queue_len: usize,
839
840    max_send_udp_payload_size: usize,
841
842    max_connection_window: u64,
843    max_stream_window: u64,
844
845    max_amplification_factor: usize,
846
847    disable_dcid_reuse: bool,
848
849    track_unknown_transport_params: Option<usize>,
850
851    initial_rtt: Duration,
852}
853
854// See https://quicwg.org/base-drafts/rfc9000.html#section-15
855fn is_reserved_version(version: u32) -> bool {
856    version & RESERVED_VERSION_MASK == version
857}
858
859impl Config {
860    /// Creates a config object with the given version.
861    ///
862    /// ## Examples:
863    ///
864    /// ```
865    /// let config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
866    /// # Ok::<(), quiche::Error>(())
867    /// ```
868    pub fn new(version: u32) -> Result<Config> {
869        Self::with_tls_ctx(version, tls::Context::new()?)
870    }
871
872    /// Creates a config object with the given version and
873    /// [`SslContextBuilder`].
874    ///
875    /// This is useful for applications that wish to manually configure
876    /// [`SslContextBuilder`].
877    ///
878    /// [`SslContextBuilder`]: https://docs.rs/boring/latest/boring/ssl/struct.SslContextBuilder.html
879    #[cfg(feature = "boringssl-boring-crate")]
880    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
881    pub fn with_boring_ssl_ctx_builder(
882        version: u32, tls_ctx_builder: boring::ssl::SslContextBuilder,
883    ) -> Result<Config> {
884        Self::with_tls_ctx(version, tls::Context::from_boring(tls_ctx_builder))
885    }
886
887    fn with_tls_ctx(version: u32, tls_ctx: tls::Context) -> Result<Config> {
888        if !is_reserved_version(version) && !version_is_supported(version) {
889            return Err(Error::UnknownVersion);
890        }
891
892        Ok(Config {
893            local_transport_params: TransportParams::default(),
894            version,
895            tls_ctx,
896            application_protos: Vec::new(),
897            grease: true,
898            cc_algorithm: CongestionControlAlgorithm::CUBIC,
899            custom_bbr_params: None,
900            initial_congestion_window_packets:
901                DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS,
902            enable_relaxed_loss_threshold: false,
903            pmtud: false,
904            hystart: true,
905            pacing: true,
906            max_pacing_rate: None,
907
908            tx_cap_factor: TX_CAP_FACTOR,
909
910            dgram_recv_max_queue_len: DEFAULT_MAX_DGRAM_QUEUE_LEN,
911            dgram_send_max_queue_len: DEFAULT_MAX_DGRAM_QUEUE_LEN,
912
913            path_challenge_recv_max_queue_len:
914                DEFAULT_MAX_PATH_CHALLENGE_RX_QUEUE_LEN,
915
916            max_send_udp_payload_size: MAX_SEND_UDP_PAYLOAD_SIZE,
917
918            max_connection_window: MAX_CONNECTION_WINDOW,
919            max_stream_window: stream::MAX_STREAM_WINDOW,
920
921            max_amplification_factor: MAX_AMPLIFICATION_FACTOR,
922
923            disable_dcid_reuse: false,
924
925            track_unknown_transport_params: None,
926            initial_rtt: DEFAULT_INITIAL_RTT,
927        })
928    }
929
930    /// Configures the given certificate chain.
931    ///
932    /// The content of `file` is parsed as a PEM-encoded leaf certificate,
933    /// followed by optional intermediate certificates.
934    ///
935    /// ## Examples:
936    ///
937    /// ```no_run
938    /// # let mut config = quiche::Config::new(0xbabababa)?;
939    /// config.load_cert_chain_from_pem_file("/path/to/cert.pem")?;
940    /// # Ok::<(), quiche::Error>(())
941    /// ```
942    pub fn load_cert_chain_from_pem_file(&mut self, file: &str) -> Result<()> {
943        self.tls_ctx.use_certificate_chain_file(file)
944    }
945
946    /// Configures the given private key.
947    ///
948    /// The content of `file` is parsed as a PEM-encoded private key.
949    ///
950    /// ## Examples:
951    ///
952    /// ```no_run
953    /// # let mut config = quiche::Config::new(0xbabababa)?;
954    /// config.load_priv_key_from_pem_file("/path/to/key.pem")?;
955    /// # Ok::<(), quiche::Error>(())
956    /// ```
957    pub fn load_priv_key_from_pem_file(&mut self, file: &str) -> Result<()> {
958        self.tls_ctx.use_privkey_file(file)
959    }
960
961    /// Specifies a file where trusted CA certificates are stored for the
962    /// purposes of certificate verification.
963    ///
964    /// The content of `file` is parsed as a PEM-encoded certificate chain.
965    ///
966    /// ## Examples:
967    ///
968    /// ```no_run
969    /// # let mut config = quiche::Config::new(0xbabababa)?;
970    /// config.load_verify_locations_from_file("/path/to/cert.pem")?;
971    /// # Ok::<(), quiche::Error>(())
972    /// ```
973    pub fn load_verify_locations_from_file(&mut self, file: &str) -> Result<()> {
974        self.tls_ctx.load_verify_locations_from_file(file)
975    }
976
977    /// Specifies a directory where trusted CA certificates are stored for the
978    /// purposes of certificate verification.
979    ///
980    /// The content of `dir` a set of PEM-encoded certificate chains.
981    ///
982    /// ## Examples:
983    ///
984    /// ```no_run
985    /// # let mut config = quiche::Config::new(0xbabababa)?;
986    /// config.load_verify_locations_from_directory("/path/to/certs")?;
987    /// # Ok::<(), quiche::Error>(())
988    /// ```
989    pub fn load_verify_locations_from_directory(
990        &mut self, dir: &str,
991    ) -> Result<()> {
992        self.tls_ctx.load_verify_locations_from_directory(dir)
993    }
994
995    /// Configures whether to verify the peer's certificate.
996    ///
997    /// This should usually be `true` for client-side connections and `false`
998    /// for server-side ones.
999    ///
1000    /// Note that by default, no verification is performed.
1001    ///
1002    /// Also note that on the server-side, enabling verification of the peer
1003    /// will trigger a certificate request and make authentication errors
1004    /// fatal, but will still allow anonymous clients (i.e. clients that
1005    /// don't present a certificate at all). Servers can check whether a
1006    /// client presented a certificate by calling [`peer_cert()`] if they
1007    /// need to.
1008    ///
1009    /// [`peer_cert()`]: struct.Connection.html#method.peer_cert
1010    pub fn verify_peer(&mut self, verify: bool) {
1011        self.tls_ctx.set_verify(verify);
1012    }
1013
1014    /// Configures whether to do path MTU discovery.
1015    ///
1016    /// The default value is `false`.
1017    pub fn discover_pmtu(&mut self, discover: bool) {
1018        self.pmtud = discover;
1019    }
1020
1021    /// Configures whether to send GREASE values.
1022    ///
1023    /// The default value is `true`.
1024    pub fn grease(&mut self, grease: bool) {
1025        self.grease = grease;
1026    }
1027
1028    /// Enables logging of secrets.
1029    ///
1030    /// When logging is enabled, the [`set_keylog()`] method must be called on
1031    /// the connection for its cryptographic secrets to be logged in the
1032    /// [keylog] format to the specified writer.
1033    ///
1034    /// [`set_keylog()`]: struct.Connection.html#method.set_keylog
1035    /// [keylog]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
1036    pub fn log_keys(&mut self) {
1037        self.tls_ctx.enable_keylog();
1038    }
1039
1040    /// Configures the session ticket key material.
1041    ///
1042    /// On the server this key will be used to encrypt and decrypt session
1043    /// tickets, used to perform session resumption without server-side state.
1044    ///
1045    /// By default a key is generated internally, and rotated regularly, so
1046    /// applications don't need to call this unless they need to use a
1047    /// specific key (e.g. in order to support resumption across multiple
1048    /// servers), in which case the application is also responsible for
1049    /// rotating the key to provide forward secrecy.
1050    pub fn set_ticket_key(&mut self, key: &[u8]) -> Result<()> {
1051        self.tls_ctx.set_ticket_key(key)
1052    }
1053
1054    /// Enables sending or receiving early data.
1055    pub fn enable_early_data(&mut self) {
1056        self.tls_ctx.set_early_data_enabled(true);
1057    }
1058
1059    /// Configures the list of supported application protocols.
1060    ///
1061    /// On the client this configures the list of protocols to send to the
1062    /// server as part of the ALPN extension.
1063    ///
1064    /// On the server this configures the list of supported protocols to match
1065    /// against the client-supplied list.
1066    ///
1067    /// Applications must set a value, but no default is provided.
1068    ///
1069    /// ## Examples:
1070    ///
1071    /// ```
1072    /// # let mut config = quiche::Config::new(0xbabababa)?;
1073    /// config.set_application_protos(&[b"http/1.1", b"http/0.9"]);
1074    /// # Ok::<(), quiche::Error>(())
1075    /// ```
1076    pub fn set_application_protos(
1077        &mut self, protos_list: &[&[u8]],
1078    ) -> Result<()> {
1079        self.application_protos =
1080            protos_list.iter().map(|s| s.to_vec()).collect();
1081
1082        self.tls_ctx.set_alpn(protos_list)
1083    }
1084
1085    /// Configures the list of supported application protocols using wire
1086    /// format.
1087    ///
1088    /// The list of protocols `protos` must be a series of non-empty, 8-bit
1089    /// length-prefixed strings.
1090    ///
1091    /// See [`set_application_protos`](Self::set_application_protos) for more
1092    /// background about application protocols.
1093    ///
1094    /// ## Examples:
1095    ///
1096    /// ```
1097    /// # let mut config = quiche::Config::new(0xbabababa)?;
1098    /// config.set_application_protos_wire_format(b"\x08http/1.1\x08http/0.9")?;
1099    /// # Ok::<(), quiche::Error>(())
1100    /// ```
1101    pub fn set_application_protos_wire_format(
1102        &mut self, protos: &[u8],
1103    ) -> Result<()> {
1104        let mut b = octets::Octets::with_slice(protos);
1105
1106        let mut protos_list = Vec::new();
1107
1108        while let Ok(proto) = b.get_bytes_with_u8_length() {
1109            protos_list.push(proto.buf());
1110        }
1111
1112        self.set_application_protos(&protos_list)
1113    }
1114
1115    /// Sets the anti-amplification limit factor.
1116    ///
1117    /// The default value is `3`.
1118    pub fn set_max_amplification_factor(&mut self, v: usize) {
1119        self.max_amplification_factor = v;
1120    }
1121
1122    /// Sets the send capacity factor.
1123    ///
1124    /// The default value is `1`.
1125    pub fn set_send_capacity_factor(&mut self, v: f64) {
1126        self.tx_cap_factor = v;
1127    }
1128
1129    /// Sets the connection's initial RTT.
1130    ///
1131    /// The default value is `333`.
1132    pub fn set_initial_rtt(&mut self, v: Duration) {
1133        self.initial_rtt = v;
1134    }
1135
1136    /// Sets the `max_idle_timeout` transport parameter, in milliseconds.
1137    ///
1138    /// The default value is infinite, that is, no timeout is used.
1139    pub fn set_max_idle_timeout(&mut self, v: u64) {
1140        self.local_transport_params.max_idle_timeout =
1141            cmp::min(v, octets::MAX_VAR_INT);
1142    }
1143
1144    /// Sets the `max_udp_payload_size transport` parameter.
1145    ///
1146    /// The default value is `65527`.
1147    pub fn set_max_recv_udp_payload_size(&mut self, v: usize) {
1148        self.local_transport_params.max_udp_payload_size =
1149            cmp::min(v as u64, octets::MAX_VAR_INT);
1150    }
1151
1152    /// Sets the maximum outgoing UDP payload size.
1153    ///
1154    /// The default and minimum value is `1200`.
1155    pub fn set_max_send_udp_payload_size(&mut self, v: usize) {
1156        self.max_send_udp_payload_size = cmp::max(v, MAX_SEND_UDP_PAYLOAD_SIZE);
1157    }
1158
1159    /// Sets the `initial_max_data` transport parameter.
1160    ///
1161    /// When set to a non-zero value quiche will only allow at most `v` bytes of
1162    /// incoming stream data to be buffered for the whole connection (that is,
1163    /// data that is not yet read by the application) and will allow more data
1164    /// to be received as the buffer is consumed by the application.
1165    ///
1166    /// When set to zero, either explicitly or via the default, quiche will not
1167    /// give any flow control to the peer, preventing it from sending any stream
1168    /// data.
1169    ///
1170    /// The default value is `0`.
1171    pub fn set_initial_max_data(&mut self, v: u64) {
1172        self.local_transport_params.initial_max_data =
1173            cmp::min(v, octets::MAX_VAR_INT);
1174    }
1175
1176    /// Sets the `initial_max_stream_data_bidi_local` transport parameter.
1177    ///
1178    /// When set to a non-zero value quiche will only allow at most `v` bytes
1179    /// of incoming stream data to be buffered for each locally-initiated
1180    /// bidirectional stream (that is, data that is not yet read by the
1181    /// application) and will allow more data to be received as the buffer is
1182    /// consumed by the application.
1183    ///
1184    /// When set to zero, either explicitly or via the default, quiche will not
1185    /// give any flow control to the peer, preventing it from sending any stream
1186    /// data.
1187    ///
1188    /// The default value is `0`.
1189    pub fn set_initial_max_stream_data_bidi_local(&mut self, v: u64) {
1190        self.local_transport_params
1191            .initial_max_stream_data_bidi_local =
1192            cmp::min(v, octets::MAX_VAR_INT);
1193    }
1194
1195    /// Sets the `initial_max_stream_data_bidi_remote` transport parameter.
1196    ///
1197    /// When set to a non-zero value quiche will only allow at most `v` bytes
1198    /// of incoming stream data to be buffered for each remotely-initiated
1199    /// bidirectional stream (that is, data that is not yet read by the
1200    /// application) and will allow more data to be received as the buffer is
1201    /// consumed by the application.
1202    ///
1203    /// When set to zero, either explicitly or via the default, quiche will not
1204    /// give any flow control to the peer, preventing it from sending any stream
1205    /// data.
1206    ///
1207    /// The default value is `0`.
1208    pub fn set_initial_max_stream_data_bidi_remote(&mut self, v: u64) {
1209        self.local_transport_params
1210            .initial_max_stream_data_bidi_remote =
1211            cmp::min(v, octets::MAX_VAR_INT);
1212    }
1213
1214    /// Sets the `initial_max_stream_data_uni` transport parameter.
1215    ///
1216    /// When set to a non-zero value quiche will only allow at most `v` bytes
1217    /// of incoming stream data to be buffered for each unidirectional stream
1218    /// (that is, data that is not yet read by the application) and will allow
1219    /// more data to be received as the buffer is consumed by the application.
1220    ///
1221    /// When set to zero, either explicitly or via the default, quiche will not
1222    /// give any flow control to the peer, preventing it from sending any stream
1223    /// data.
1224    ///
1225    /// The default value is `0`.
1226    pub fn set_initial_max_stream_data_uni(&mut self, v: u64) {
1227        self.local_transport_params.initial_max_stream_data_uni =
1228            cmp::min(v, octets::MAX_VAR_INT);
1229    }
1230
1231    /// Sets the `initial_max_streams_bidi` transport parameter.
1232    ///
1233    /// When set to a non-zero value quiche will only allow `v` number of
1234    /// concurrent remotely-initiated bidirectional streams to be open at any
1235    /// given time and will increase the limit automatically as streams are
1236    /// completed.
1237    ///
1238    /// When set to zero, either explicitly or via the default, quiche will not
1239    /// not allow the peer to open any bidirectional streams.
1240    ///
1241    /// A bidirectional stream is considered completed when all incoming data
1242    /// has been read by the application (up to the `fin` offset) or the
1243    /// stream's read direction has been shutdown, and all outgoing data has
1244    /// been acked by the peer (up to the `fin` offset) or the stream's write
1245    /// direction has been shutdown.
1246    ///
1247    /// The default value is `0`.
1248    pub fn set_initial_max_streams_bidi(&mut self, v: u64) {
1249        self.local_transport_params.initial_max_streams_bidi =
1250            cmp::min(v, octets::MAX_VAR_INT);
1251    }
1252
1253    /// Sets the `initial_max_streams_uni` transport parameter.
1254    ///
1255    /// When set to a non-zero value quiche will only allow `v` number of
1256    /// concurrent remotely-initiated unidirectional streams to be open at any
1257    /// given time and will increase the limit automatically as streams are
1258    /// completed.
1259    ///
1260    /// When set to zero, either explicitly or via the default, quiche will not
1261    /// not allow the peer to open any unidirectional streams.
1262    ///
1263    /// A unidirectional stream is considered completed when all incoming data
1264    /// has been read by the application (up to the `fin` offset) or the
1265    /// stream's read direction has been shutdown.
1266    ///
1267    /// The default value is `0`.
1268    pub fn set_initial_max_streams_uni(&mut self, v: u64) {
1269        self.local_transport_params.initial_max_streams_uni =
1270            cmp::min(v, octets::MAX_VAR_INT);
1271    }
1272
1273    /// Sets the `ack_delay_exponent` transport parameter.
1274    ///
1275    /// The default value is `3`.
1276    pub fn set_ack_delay_exponent(&mut self, v: u64) {
1277        self.local_transport_params.ack_delay_exponent =
1278            cmp::min(v, octets::MAX_VAR_INT);
1279    }
1280
1281    /// Sets the `max_ack_delay` transport parameter.
1282    ///
1283    /// The default value is `25`.
1284    pub fn set_max_ack_delay(&mut self, v: u64) {
1285        self.local_transport_params.max_ack_delay =
1286            cmp::min(v, octets::MAX_VAR_INT);
1287    }
1288
1289    /// Sets the `active_connection_id_limit` transport parameter.
1290    ///
1291    /// The default value is `2`. Lower values will be ignored.
1292    pub fn set_active_connection_id_limit(&mut self, v: u64) {
1293        if v >= 2 {
1294            self.local_transport_params.active_conn_id_limit =
1295                cmp::min(v, octets::MAX_VAR_INT);
1296        }
1297    }
1298
1299    /// Sets the `disable_active_migration` transport parameter.
1300    ///
1301    /// The default value is `false`.
1302    pub fn set_disable_active_migration(&mut self, v: bool) {
1303        self.local_transport_params.disable_active_migration = v;
1304    }
1305
1306    /// Sets the congestion control algorithm used.
1307    ///
1308    /// The default value is `CongestionControlAlgorithm::CUBIC`.
1309    pub fn set_cc_algorithm(&mut self, algo: CongestionControlAlgorithm) {
1310        self.cc_algorithm = algo;
1311    }
1312
1313    /// Sets custom BBR settings.
1314    ///
1315    /// This API is experimental and will be removed in the future.
1316    ///
1317    /// Currently this only applies if cc_algorithm is
1318    /// `CongestionControlAlgorithm::Bbr2Gcongestion` is set.
1319    ///
1320    /// The default value is `None`.
1321    #[cfg(feature = "internal")]
1322    #[doc(hidden)]
1323    pub fn set_custom_bbr_params(&mut self, custom_bbr_settings: BbrParams) {
1324        self.custom_bbr_params = Some(custom_bbr_settings);
1325    }
1326
1327    /// Sets the congestion control algorithm used by string.
1328    ///
1329    /// The default value is `cubic`. On error `Error::CongestionControl`
1330    /// will be returned.
1331    ///
1332    /// ## Examples:
1333    ///
1334    /// ```
1335    /// # let mut config = quiche::Config::new(0xbabababa)?;
1336    /// config.set_cc_algorithm_name("reno");
1337    /// # Ok::<(), quiche::Error>(())
1338    /// ```
1339    pub fn set_cc_algorithm_name(&mut self, name: &str) -> Result<()> {
1340        self.cc_algorithm = CongestionControlAlgorithm::from_str(name)?;
1341
1342        Ok(())
1343    }
1344
1345    /// Sets initial congestion window size in terms of packet count.
1346    ///
1347    /// The default value is 10.
1348    pub fn set_initial_congestion_window_packets(&mut self, packets: usize) {
1349        self.initial_congestion_window_packets = packets;
1350    }
1351
1352    /// Configure whether to enable relaxed loss detection on spurious loss.
1353    ///
1354    /// The default value is false.
1355    pub fn set_enable_relaxed_loss_threshold(&mut self, enable: bool) {
1356        self.enable_relaxed_loss_threshold = enable;
1357    }
1358
1359    /// Configures whether to enable HyStart++.
1360    ///
1361    /// The default value is `true`.
1362    pub fn enable_hystart(&mut self, v: bool) {
1363        self.hystart = v;
1364    }
1365
1366    /// Configures whether to enable pacing.
1367    ///
1368    /// The default value is `true`.
1369    pub fn enable_pacing(&mut self, v: bool) {
1370        self.pacing = v;
1371    }
1372
1373    /// Sets the max value for pacing rate.
1374    ///
1375    /// By default pacing rate is not limited.
1376    pub fn set_max_pacing_rate(&mut self, v: u64) {
1377        self.max_pacing_rate = Some(v);
1378    }
1379
1380    /// Configures whether to enable receiving DATAGRAM frames.
1381    ///
1382    /// When enabled, the `max_datagram_frame_size` transport parameter is set
1383    /// to 65536 as recommended by draft-ietf-quic-datagram-01.
1384    ///
1385    /// The default is `false`.
1386    pub fn enable_dgram(
1387        &mut self, enabled: bool, recv_queue_len: usize, send_queue_len: usize,
1388    ) {
1389        self.local_transport_params.max_datagram_frame_size = if enabled {
1390            Some(MAX_DGRAM_FRAME_SIZE)
1391        } else {
1392            None
1393        };
1394        self.dgram_recv_max_queue_len = recv_queue_len;
1395        self.dgram_send_max_queue_len = send_queue_len;
1396    }
1397
1398    /// Configures the max number of queued received PATH_CHALLENGE frames.
1399    ///
1400    /// When an endpoint receives a PATH_CHALLENGE frame and the queue is full,
1401    /// the frame is discarded.
1402    ///
1403    /// The default is 3.
1404    pub fn set_path_challenge_recv_max_queue_len(&mut self, queue_len: usize) {
1405        self.path_challenge_recv_max_queue_len = queue_len;
1406    }
1407
1408    /// Sets the maximum size of the connection window.
1409    ///
1410    /// The default value is MAX_CONNECTION_WINDOW (24MBytes).
1411    pub fn set_max_connection_window(&mut self, v: u64) {
1412        self.max_connection_window = v;
1413    }
1414
1415    /// Sets the maximum size of the stream window.
1416    ///
1417    /// The default value is MAX_STREAM_WINDOW (16MBytes).
1418    pub fn set_max_stream_window(&mut self, v: u64) {
1419        self.max_stream_window = v;
1420    }
1421
1422    /// Sets the initial stateless reset token.
1423    ///
1424    /// This value is only advertised by servers. Setting a stateless retry
1425    /// token as a client has no effect on the connection.
1426    ///
1427    /// The default value is `None`.
1428    pub fn set_stateless_reset_token(&mut self, v: Option<u128>) {
1429        self.local_transport_params.stateless_reset_token = v;
1430    }
1431
1432    /// Sets whether the QUIC connection should avoid reusing DCIDs over
1433    /// different paths.
1434    ///
1435    /// When set to `true`, it ensures that a destination Connection ID is never
1436    /// reused on different paths. Such behaviour may lead to connection stall
1437    /// if the peer performs a non-voluntary migration (e.g., NAT rebinding) and
1438    /// does not provide additional destination Connection IDs to handle such
1439    /// event.
1440    ///
1441    /// The default value is `false`.
1442    pub fn set_disable_dcid_reuse(&mut self, v: bool) {
1443        self.disable_dcid_reuse = v;
1444    }
1445
1446    /// Enables tracking unknown transport parameters.
1447    ///
1448    /// Specify the maximum number of bytes used to track unknown transport
1449    /// parameters. The size includes the identifier and its value. If storing a
1450    /// transport parameter would cause the limit to be exceeded, it is quietly
1451    /// dropped.
1452    ///
1453    /// The default is that the feature is disabled.
1454    pub fn enable_track_unknown_transport_parameters(&mut self, size: usize) {
1455        self.track_unknown_transport_params = Some(size);
1456    }
1457}
1458
1459/// A QUIC connection.
1460pub struct Connection<F = DefaultBufFactory>
1461where
1462    F: BufFactory,
1463{
1464    /// QUIC wire version used for the connection.
1465    version: u32,
1466
1467    /// Connection Identifiers.
1468    ids: cid::ConnectionIdentifiers,
1469
1470    /// Unique opaque ID for the connection that can be used for logging.
1471    trace_id: String,
1472
1473    /// Packet number spaces.
1474    pkt_num_spaces: [packet::PktNumSpace; packet::Epoch::count()],
1475
1476    /// The crypto context.
1477    crypto_ctx: [packet::CryptoContext; packet::Epoch::count()],
1478
1479    /// Next packet number.
1480    next_pkt_num: u64,
1481
1482    // TODO
1483    // combine with `next_pkt_num`
1484    /// Track the packet skip context
1485    pkt_num_manager: packet::PktNumManager,
1486
1487    /// Peer's transport parameters.
1488    peer_transport_params: TransportParams,
1489
1490    /// If tracking unknown transport parameters from a peer, how much space to
1491    /// use in bytes.
1492    peer_transport_params_track_unknown: Option<usize>,
1493
1494    /// Local transport parameters.
1495    local_transport_params: TransportParams,
1496
1497    /// TLS handshake state.
1498    handshake: tls::Handshake,
1499
1500    /// Serialized TLS session buffer.
1501    ///
1502    /// This field is populated when a new session ticket is processed on the
1503    /// client. On the server this is empty.
1504    session: Option<Vec<u8>>,
1505
1506    /// The configuration for recovery.
1507    recovery_config: recovery::RecoveryConfig,
1508
1509    /// The path manager.
1510    paths: path::PathMap,
1511
1512    /// PATH_CHALLENGE receive queue max length.
1513    path_challenge_recv_max_queue_len: usize,
1514
1515    /// Total number of received PATH_CHALLENGE frames.
1516    path_challenge_rx_count: u64,
1517
1518    /// List of supported application protocols.
1519    application_protos: Vec<Vec<u8>>,
1520
1521    /// Total number of received packets.
1522    recv_count: usize,
1523
1524    /// Total number of sent packets.
1525    sent_count: usize,
1526
1527    /// Total number of lost packets.
1528    lost_count: usize,
1529
1530    /// Total number of lost packets that were later acked.
1531    spurious_lost_count: usize,
1532
1533    /// Total number of packets sent with data retransmitted.
1534    retrans_count: usize,
1535
1536    /// Total number of sent DATAGRAM frames.
1537    dgram_sent_count: usize,
1538
1539    /// Total number of received DATAGRAM frames.
1540    dgram_recv_count: usize,
1541
1542    /// Total number of bytes received from the peer.
1543    rx_data: u64,
1544
1545    /// Receiver flow controller.
1546    flow_control: flowcontrol::FlowControl,
1547
1548    /// Whether we send MAX_DATA frame.
1549    almost_full: bool,
1550
1551    /// Number of stream data bytes that can be buffered.
1552    tx_cap: usize,
1553
1554    /// The send capacity factor.
1555    tx_cap_factor: f64,
1556
1557    /// Number of bytes buffered in the send buffer.
1558    tx_buffered: usize,
1559
1560    /// Total number of bytes sent to the peer.
1561    tx_data: u64,
1562
1563    /// Peer's flow control limit for the connection.
1564    max_tx_data: u64,
1565
1566    /// Last tx_data before running a full send() loop.
1567    last_tx_data: u64,
1568
1569    /// Total number of bytes retransmitted over the connection.
1570    /// This counts only STREAM and CRYPTO data.
1571    stream_retrans_bytes: u64,
1572
1573    /// Total number of bytes sent over the connection.
1574    sent_bytes: u64,
1575
1576    /// Total number of bytes received over the connection.
1577    recv_bytes: u64,
1578
1579    /// Total number of bytes sent acked over the connection.
1580    acked_bytes: u64,
1581
1582    /// Total number of bytes sent lost over the connection.
1583    lost_bytes: u64,
1584
1585    /// Streams map, indexed by stream ID.
1586    streams: stream::StreamMap<F>,
1587
1588    /// Peer's original destination connection ID. Used by the client to
1589    /// validate the server's transport parameter.
1590    odcid: Option<ConnectionId<'static>>,
1591
1592    /// Peer's retry source connection ID. Used by the client during stateless
1593    /// retry to validate the server's transport parameter.
1594    rscid: Option<ConnectionId<'static>>,
1595
1596    /// Received address verification token.
1597    token: Option<Vec<u8>>,
1598
1599    /// Error code and reason to be sent to the peer in a CONNECTION_CLOSE
1600    /// frame.
1601    local_error: Option<ConnectionError>,
1602
1603    /// Error code and reason received from the peer in a CONNECTION_CLOSE
1604    /// frame.
1605    peer_error: Option<ConnectionError>,
1606
1607    /// The connection-level limit at which send blocking occurred.
1608    blocked_limit: Option<u64>,
1609
1610    /// Idle timeout expiration time.
1611    idle_timer: Option<Instant>,
1612
1613    /// Draining timeout expiration time.
1614    draining_timer: Option<Instant>,
1615
1616    /// List of raw packets that were received before they could be decrypted.
1617    undecryptable_pkts: VecDeque<(Vec<u8>, RecvInfo)>,
1618
1619    /// The negotiated ALPN protocol.
1620    alpn: Vec<u8>,
1621
1622    /// Whether this is a server-side connection.
1623    is_server: bool,
1624
1625    /// Whether the initial secrets have been derived.
1626    derived_initial_secrets: bool,
1627
1628    /// Whether a version negotiation packet has already been received. Only
1629    /// relevant for client connections.
1630    did_version_negotiation: bool,
1631
1632    /// Whether stateless retry has been performed.
1633    did_retry: bool,
1634
1635    /// Whether the peer already updated its connection ID.
1636    got_peer_conn_id: bool,
1637
1638    /// Whether the peer verified our initial address.
1639    peer_verified_initial_address: bool,
1640
1641    /// Whether the peer's transport parameters were parsed.
1642    parsed_peer_transport_params: bool,
1643
1644    /// Whether the connection handshake has been completed.
1645    handshake_completed: bool,
1646
1647    /// Whether the HANDSHAKE_DONE frame has been sent.
1648    handshake_done_sent: bool,
1649
1650    /// Whether the HANDSHAKE_DONE frame has been acked.
1651    handshake_done_acked: bool,
1652
1653    /// Whether the connection handshake has been confirmed.
1654    handshake_confirmed: bool,
1655
1656    /// Key phase bit used for outgoing protected packets.
1657    key_phase: bool,
1658
1659    /// Whether an ack-eliciting packet has been sent since last receiving a
1660    /// packet.
1661    ack_eliciting_sent: bool,
1662
1663    /// Whether the connection is closed.
1664    closed: bool,
1665
1666    /// Whether the connection was timed out.
1667    timed_out: bool,
1668
1669    /// Whether to send GREASE.
1670    grease: bool,
1671
1672    /// TLS keylog writer.
1673    keylog: Option<Box<dyn std::io::Write + Send + Sync>>,
1674
1675    #[cfg(feature = "qlog")]
1676    qlog: QlogInfo,
1677
1678    /// DATAGRAM queues.
1679    dgram_recv_queue: dgram::DatagramQueue,
1680    dgram_send_queue: dgram::DatagramQueue,
1681
1682    /// Whether to emit DATAGRAM frames in the next packet.
1683    emit_dgram: bool,
1684
1685    /// Whether the connection should prevent from reusing destination
1686    /// Connection IDs when the peer migrates.
1687    disable_dcid_reuse: bool,
1688
1689    /// The number of streams reset by local.
1690    reset_stream_local_count: u64,
1691
1692    /// The number of streams stopped by local.
1693    stopped_stream_local_count: u64,
1694
1695    /// The number of streams reset by remote.
1696    reset_stream_remote_count: u64,
1697
1698    /// The number of streams stopped by remote.
1699    stopped_stream_remote_count: u64,
1700
1701    /// The anti-amplification limit factor.
1702    max_amplification_factor: usize,
1703}
1704
1705/// Creates a new server-side connection.
1706///
1707/// The `scid` parameter represents the server's source connection ID, while
1708/// the optional `odcid` parameter represents the original destination ID the
1709/// client sent before a stateless retry (this is only required when using
1710/// the [`retry()`] function).
1711///
1712/// [`retry()`]: fn.retry.html
1713///
1714/// ## Examples:
1715///
1716/// ```no_run
1717/// # let mut config = quiche::Config::new(0xbabababa)?;
1718/// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
1719/// # let local = "127.0.0.1:0".parse().unwrap();
1720/// # let peer = "127.0.0.1:1234".parse().unwrap();
1721/// let conn = quiche::accept(&scid, None, local, peer, &mut config)?;
1722/// # Ok::<(), quiche::Error>(())
1723/// ```
1724#[inline]
1725pub fn accept(
1726    scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1727    peer: SocketAddr, config: &mut Config,
1728) -> Result<Connection> {
1729    let conn = Connection::new(scid, odcid, local, peer, config, true)?;
1730
1731    Ok(conn)
1732}
1733
1734/// Creates a new server-side connection, with a custom buffer generation
1735/// method.
1736///
1737/// The buffers generated can be anything that can be drereferenced as a byte
1738/// slice. See [`accept`] and [`BufFactory`] for more info.
1739#[inline]
1740pub fn accept_with_buf_factory<F: BufFactory>(
1741    scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1742    peer: SocketAddr, config: &mut Config,
1743) -> Result<Connection<F>> {
1744    let conn = Connection::new(scid, odcid, local, peer, config, true)?;
1745
1746    Ok(conn)
1747}
1748
1749/// Creates a new client-side connection.
1750///
1751/// The `scid` parameter is used as the connection's source connection ID,
1752/// while the optional `server_name` parameter is used to verify the peer's
1753/// certificate.
1754///
1755/// ## Examples:
1756///
1757/// ```no_run
1758/// # let mut config = quiche::Config::new(0xbabababa)?;
1759/// # let server_name = "quic.tech";
1760/// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
1761/// # let local = "127.0.0.1:4321".parse().unwrap();
1762/// # let peer = "127.0.0.1:1234".parse().unwrap();
1763/// let conn =
1764///     quiche::connect(Some(&server_name), &scid, local, peer, &mut config)?;
1765/// # Ok::<(), quiche::Error>(())
1766/// ```
1767#[inline]
1768pub fn connect(
1769    server_name: Option<&str>, scid: &ConnectionId, local: SocketAddr,
1770    peer: SocketAddr, config: &mut Config,
1771) -> Result<Connection> {
1772    let mut conn = Connection::new(scid, None, local, peer, config, false)?;
1773
1774    if let Some(server_name) = server_name {
1775        conn.handshake.set_host_name(server_name)?;
1776    }
1777
1778    Ok(conn)
1779}
1780
1781/// Creates a new client-side connection, with a custom buffer generation
1782/// method.
1783///
1784/// The buffers generated can be anything that can be drereferenced as a byte
1785/// slice. See [`connect`] and [`BufFactory`] for more info.
1786#[inline]
1787pub fn connect_with_buffer_factory<F: BufFactory>(
1788    server_name: Option<&str>, scid: &ConnectionId, local: SocketAddr,
1789    peer: SocketAddr, config: &mut Config,
1790) -> Result<Connection<F>> {
1791    let mut conn = Connection::new(scid, None, local, peer, config, false)?;
1792
1793    if let Some(server_name) = server_name {
1794        conn.handshake.set_host_name(server_name)?;
1795    }
1796
1797    Ok(conn)
1798}
1799
1800/// Writes a version negotiation packet.
1801///
1802/// The `scid` and `dcid` parameters are the source connection ID and the
1803/// destination connection ID extracted from the received client's Initial
1804/// packet that advertises an unsupported version.
1805///
1806/// ## Examples:
1807///
1808/// ```no_run
1809/// # let mut buf = [0; 512];
1810/// # let mut out = [0; 512];
1811/// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
1812/// let (len, src) = socket.recv_from(&mut buf).unwrap();
1813///
1814/// let hdr =
1815///     quiche::Header::from_slice(&mut buf[..len], quiche::MAX_CONN_ID_LEN)?;
1816///
1817/// if hdr.version != quiche::PROTOCOL_VERSION {
1818///     let len = quiche::negotiate_version(&hdr.scid, &hdr.dcid, &mut out)?;
1819///     socket.send_to(&out[..len], &src).unwrap();
1820/// }
1821/// # Ok::<(), quiche::Error>(())
1822/// ```
1823#[inline]
1824pub fn negotiate_version(
1825    scid: &ConnectionId, dcid: &ConnectionId, out: &mut [u8],
1826) -> Result<usize> {
1827    packet::negotiate_version(scid, dcid, out)
1828}
1829
1830/// Writes a stateless retry packet.
1831///
1832/// The `scid` and `dcid` parameters are the source connection ID and the
1833/// destination connection ID extracted from the received client's Initial
1834/// packet, while `new_scid` is the server's new source connection ID and
1835/// `token` is the address validation token the client needs to echo back.
1836///
1837/// The application is responsible for generating the address validation
1838/// token to be sent to the client, and verifying tokens sent back by the
1839/// client. The generated token should include the `dcid` parameter, such
1840/// that it can be later extracted from the token and passed to the
1841/// [`accept()`] function as its `odcid` parameter.
1842///
1843/// [`accept()`]: fn.accept.html
1844///
1845/// ## Examples:
1846///
1847/// ```no_run
1848/// # let mut config = quiche::Config::new(0xbabababa)?;
1849/// # let mut buf = [0; 512];
1850/// # let mut out = [0; 512];
1851/// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
1852/// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
1853/// # let local = socket.local_addr().unwrap();
1854/// # fn mint_token(hdr: &quiche::Header, src: &std::net::SocketAddr) -> Vec<u8> {
1855/// #     vec![]
1856/// # }
1857/// # fn validate_token<'a>(src: &std::net::SocketAddr, token: &'a [u8]) -> Option<quiche::ConnectionId<'a>> {
1858/// #     None
1859/// # }
1860/// let (len, peer) = socket.recv_from(&mut buf).unwrap();
1861///
1862/// let hdr = quiche::Header::from_slice(&mut buf[..len], quiche::MAX_CONN_ID_LEN)?;
1863///
1864/// let token = hdr.token.as_ref().unwrap();
1865///
1866/// // No token sent by client, create a new one.
1867/// if token.is_empty() {
1868///     let new_token = mint_token(&hdr, &peer);
1869///
1870///     let len = quiche::retry(
1871///         &hdr.scid, &hdr.dcid, &scid, &new_token, hdr.version, &mut out,
1872///     )?;
1873///
1874///     socket.send_to(&out[..len], &peer).unwrap();
1875///     return Ok(());
1876/// }
1877///
1878/// // Client sent token, validate it.
1879/// let odcid = validate_token(&peer, token);
1880///
1881/// if odcid.is_none() {
1882///     // Invalid address validation token.
1883///     return Ok(());
1884/// }
1885///
1886/// let conn = quiche::accept(&scid, odcid.as_ref(), local, peer, &mut config)?;
1887/// # Ok::<(), quiche::Error>(())
1888/// ```
1889#[inline]
1890pub fn retry(
1891    scid: &ConnectionId, dcid: &ConnectionId, new_scid: &ConnectionId,
1892    token: &[u8], version: u32, out: &mut [u8],
1893) -> Result<usize> {
1894    packet::retry(scid, dcid, new_scid, token, version, out)
1895}
1896
1897/// Returns true if the given protocol version is supported.
1898#[inline]
1899pub fn version_is_supported(version: u32) -> bool {
1900    matches!(version, PROTOCOL_VERSION_V1)
1901}
1902
1903/// Pushes a frame to the output packet if there is enough space.
1904///
1905/// Returns `true` on success, `false` otherwise. In case of failure it means
1906/// there is no room to add the frame in the packet. You may retry to add the
1907/// frame later.
1908macro_rules! push_frame_to_pkt {
1909    ($out:expr, $frames:expr, $frame:expr, $left:expr) => {{
1910        if $frame.wire_len() <= $left {
1911            $left -= $frame.wire_len();
1912
1913            $frame.to_bytes(&mut $out)?;
1914
1915            $frames.push($frame);
1916
1917            true
1918        } else {
1919            false
1920        }
1921    }};
1922}
1923
1924/// Executes the provided body if the qlog feature is enabled, quiche has been
1925/// configured with a log writer, the event's importance is within the
1926/// configured level.
1927macro_rules! qlog_with_type {
1928    ($ty:expr, $qlog:expr, $qlog_streamer_ref:ident, $body:block) => {{
1929        #[cfg(feature = "qlog")]
1930        {
1931            if EventImportance::from($ty).is_contained_in(&$qlog.level) {
1932                if let Some($qlog_streamer_ref) = &mut $qlog.streamer {
1933                    $body
1934                }
1935            }
1936        }
1937    }};
1938}
1939
1940#[cfg(feature = "qlog")]
1941const QLOG_PARAMS_SET: EventType =
1942    EventType::TransportEventType(TransportEventType::ParametersSet);
1943
1944#[cfg(feature = "qlog")]
1945const QLOG_PACKET_RX: EventType =
1946    EventType::TransportEventType(TransportEventType::PacketReceived);
1947
1948#[cfg(feature = "qlog")]
1949const QLOG_PACKET_TX: EventType =
1950    EventType::TransportEventType(TransportEventType::PacketSent);
1951
1952#[cfg(feature = "qlog")]
1953const QLOG_DATA_MV: EventType =
1954    EventType::TransportEventType(TransportEventType::DataMoved);
1955
1956#[cfg(feature = "qlog")]
1957const QLOG_METRICS: EventType =
1958    EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated);
1959
1960#[cfg(feature = "qlog")]
1961const QLOG_CONNECTION_CLOSED: EventType =
1962    EventType::ConnectivityEventType(ConnectivityEventType::ConnectionClosed);
1963
1964#[cfg(feature = "qlog")]
1965struct QlogInfo {
1966    streamer: Option<qlog::streamer::QlogStreamer>,
1967    logged_peer_params: bool,
1968    level: EventImportance,
1969}
1970
1971#[cfg(feature = "qlog")]
1972impl Default for QlogInfo {
1973    fn default() -> Self {
1974        QlogInfo {
1975            streamer: None,
1976            logged_peer_params: false,
1977            level: EventImportance::Base,
1978        }
1979    }
1980}
1981
1982impl<F: BufFactory> Connection<F> {
1983    fn new(
1984        scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1985        peer: SocketAddr, config: &mut Config, is_server: bool,
1986    ) -> Result<Connection<F>> {
1987        let tls = config.tls_ctx.new_handshake()?;
1988        Connection::with_tls(scid, odcid, local, peer, config, tls, is_server)
1989    }
1990
1991    fn with_tls(
1992        scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1993        peer: SocketAddr, config: &Config, tls: tls::Handshake, is_server: bool,
1994    ) -> Result<Connection<F>> {
1995        let max_rx_data = config.local_transport_params.initial_max_data;
1996
1997        let scid_as_hex: Vec<String> =
1998            scid.iter().map(|b| format!("{b:02x}")).collect();
1999
2000        let reset_token = if is_server {
2001            config.local_transport_params.stateless_reset_token
2002        } else {
2003            None
2004        };
2005
2006        let recovery_config = recovery::RecoveryConfig::from_config(config);
2007
2008        let mut path = path::Path::new(
2009            local,
2010            peer,
2011            &recovery_config,
2012            config.path_challenge_recv_max_queue_len,
2013            true,
2014            Some(config),
2015        );
2016
2017        // If we did stateless retry assume the peer's address is verified.
2018        path.verified_peer_address = odcid.is_some();
2019        // Assume clients validate the server's address implicitly.
2020        path.peer_verified_local_address = is_server;
2021
2022        // Do not allocate more than the number of active CIDs.
2023        let paths = path::PathMap::new(
2024            path,
2025            config.local_transport_params.active_conn_id_limit as usize,
2026            is_server,
2027        );
2028
2029        let active_path_id = paths.get_active_path_id()?;
2030
2031        let ids = cid::ConnectionIdentifiers::new(
2032            config.local_transport_params.active_conn_id_limit as usize,
2033            scid,
2034            active_path_id,
2035            reset_token,
2036        );
2037
2038        let mut conn = Connection {
2039            version: config.version,
2040
2041            ids,
2042
2043            trace_id: scid_as_hex.join(""),
2044
2045            pkt_num_spaces: [
2046                packet::PktNumSpace::new(),
2047                packet::PktNumSpace::new(),
2048                packet::PktNumSpace::new(),
2049            ],
2050
2051            crypto_ctx: [
2052                packet::CryptoContext::new(),
2053                packet::CryptoContext::new(),
2054                packet::CryptoContext::new(),
2055            ],
2056
2057            next_pkt_num: 0,
2058
2059            pkt_num_manager: packet::PktNumManager::new(),
2060
2061            peer_transport_params: TransportParams::default(),
2062
2063            peer_transport_params_track_unknown: config
2064                .track_unknown_transport_params,
2065
2066            local_transport_params: config.local_transport_params.clone(),
2067
2068            handshake: tls,
2069
2070            session: None,
2071
2072            recovery_config,
2073
2074            paths,
2075            path_challenge_recv_max_queue_len: config
2076                .path_challenge_recv_max_queue_len,
2077            path_challenge_rx_count: 0,
2078
2079            application_protos: config.application_protos.clone(),
2080
2081            recv_count: 0,
2082            sent_count: 0,
2083            lost_count: 0,
2084            spurious_lost_count: 0,
2085            retrans_count: 0,
2086            dgram_sent_count: 0,
2087            dgram_recv_count: 0,
2088            sent_bytes: 0,
2089            recv_bytes: 0,
2090            acked_bytes: 0,
2091            lost_bytes: 0,
2092
2093            rx_data: 0,
2094            flow_control: flowcontrol::FlowControl::new(
2095                max_rx_data,
2096                cmp::min(max_rx_data / 2 * 3, DEFAULT_CONNECTION_WINDOW),
2097                config.max_connection_window,
2098            ),
2099            almost_full: false,
2100
2101            tx_cap: 0,
2102            tx_cap_factor: config.tx_cap_factor,
2103
2104            tx_buffered: 0,
2105
2106            tx_data: 0,
2107            max_tx_data: 0,
2108            last_tx_data: 0,
2109
2110            stream_retrans_bytes: 0,
2111
2112            streams: stream::StreamMap::new(
2113                config.local_transport_params.initial_max_streams_bidi,
2114                config.local_transport_params.initial_max_streams_uni,
2115                config.max_stream_window,
2116            ),
2117
2118            odcid: None,
2119
2120            rscid: None,
2121
2122            token: None,
2123
2124            local_error: None,
2125
2126            peer_error: None,
2127
2128            blocked_limit: None,
2129
2130            idle_timer: None,
2131
2132            draining_timer: None,
2133
2134            undecryptable_pkts: VecDeque::new(),
2135
2136            alpn: Vec::new(),
2137
2138            is_server,
2139
2140            derived_initial_secrets: false,
2141
2142            did_version_negotiation: false,
2143
2144            did_retry: false,
2145
2146            got_peer_conn_id: false,
2147
2148            // Assume clients validate the server's address implicitly.
2149            peer_verified_initial_address: is_server,
2150
2151            parsed_peer_transport_params: false,
2152
2153            handshake_completed: false,
2154
2155            handshake_done_sent: false,
2156            handshake_done_acked: false,
2157
2158            handshake_confirmed: false,
2159
2160            key_phase: false,
2161
2162            ack_eliciting_sent: false,
2163
2164            closed: false,
2165
2166            timed_out: false,
2167
2168            grease: config.grease,
2169
2170            keylog: None,
2171
2172            #[cfg(feature = "qlog")]
2173            qlog: Default::default(),
2174
2175            dgram_recv_queue: dgram::DatagramQueue::new(
2176                config.dgram_recv_max_queue_len,
2177            ),
2178
2179            dgram_send_queue: dgram::DatagramQueue::new(
2180                config.dgram_send_max_queue_len,
2181            ),
2182
2183            emit_dgram: true,
2184
2185            disable_dcid_reuse: config.disable_dcid_reuse,
2186
2187            reset_stream_local_count: 0,
2188            stopped_stream_local_count: 0,
2189            reset_stream_remote_count: 0,
2190            stopped_stream_remote_count: 0,
2191
2192            max_amplification_factor: config.max_amplification_factor,
2193        };
2194
2195        if let Some(odcid) = odcid {
2196            conn.local_transport_params
2197                .original_destination_connection_id = Some(odcid.to_vec().into());
2198
2199            conn.local_transport_params.retry_source_connection_id =
2200                Some(conn.ids.get_scid(0)?.cid.to_vec().into());
2201
2202            conn.did_retry = true;
2203        }
2204
2205        conn.local_transport_params.initial_source_connection_id =
2206            Some(conn.ids.get_scid(0)?.cid.to_vec().into());
2207
2208        conn.handshake.init(is_server)?;
2209
2210        conn.handshake
2211            .use_legacy_codepoint(config.version != PROTOCOL_VERSION_V1);
2212
2213        conn.encode_transport_params()?;
2214
2215        // Derive initial secrets for the client. We can do this here because
2216        // we already generated the random destination connection ID.
2217        if !is_server {
2218            let mut dcid = [0; 16];
2219            rand::rand_bytes(&mut dcid[..]);
2220
2221            let (aead_open, aead_seal) = crypto::derive_initial_key_material(
2222                &dcid,
2223                conn.version,
2224                conn.is_server,
2225                false,
2226            )?;
2227
2228            let reset_token = conn.peer_transport_params.stateless_reset_token;
2229            conn.set_initial_dcid(
2230                dcid.to_vec().into(),
2231                reset_token,
2232                active_path_id,
2233            )?;
2234
2235            conn.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
2236            conn.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
2237
2238            conn.derived_initial_secrets = true;
2239        }
2240
2241        Ok(conn)
2242    }
2243
2244    /// Sets keylog output to the designated [`Writer`].
2245    ///
2246    /// This needs to be called as soon as the connection is created, to avoid
2247    /// missing some early logs.
2248    ///
2249    /// [`Writer`]: https://doc.rust-lang.org/std/io/trait.Write.html
2250    #[inline]
2251    pub fn set_keylog(&mut self, writer: Box<dyn std::io::Write + Send + Sync>) {
2252        self.keylog = Some(writer);
2253    }
2254
2255    /// Sets qlog output to the designated [`Writer`].
2256    ///
2257    /// Only events included in `QlogLevel::Base` are written. The serialization
2258    /// format is JSON-SEQ.
2259    ///
2260    /// This needs to be called as soon as the connection is created, to avoid
2261    /// missing some early logs.
2262    ///
2263    /// [`Writer`]: https://doc.rust-lang.org/std/io/trait.Write.html
2264    #[cfg(feature = "qlog")]
2265    #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2266    pub fn set_qlog(
2267        &mut self, writer: Box<dyn std::io::Write + Send + Sync>, title: String,
2268        description: String,
2269    ) {
2270        self.set_qlog_with_level(writer, title, description, QlogLevel::Base)
2271    }
2272
2273    /// Sets qlog output to the designated [`Writer`].
2274    ///
2275    /// Only qlog events included in the specified `QlogLevel` are written. The
2276    /// serialization format is JSON-SEQ.
2277    ///
2278    /// This needs to be called as soon as the connection is created, to avoid
2279    /// missing some early logs.
2280    ///
2281    /// [`Writer`]: https://doc.rust-lang.org/std/io/trait.Write.html
2282    #[cfg(feature = "qlog")]
2283    #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2284    pub fn set_qlog_with_level(
2285        &mut self, writer: Box<dyn std::io::Write + Send + Sync>, title: String,
2286        description: String, qlog_level: QlogLevel,
2287    ) {
2288        let vp = if self.is_server {
2289            qlog::VantagePointType::Server
2290        } else {
2291            qlog::VantagePointType::Client
2292        };
2293
2294        let level = match qlog_level {
2295            QlogLevel::Core => EventImportance::Core,
2296
2297            QlogLevel::Base => EventImportance::Base,
2298
2299            QlogLevel::Extra => EventImportance::Extra,
2300        };
2301
2302        self.qlog.level = level;
2303
2304        let trace = qlog::TraceSeq::new(
2305            qlog::VantagePoint {
2306                name: None,
2307                ty: vp,
2308                flow: None,
2309            },
2310            Some(title.to_string()),
2311            Some(description.to_string()),
2312            Some(qlog::Configuration {
2313                time_offset: Some(0.0),
2314                original_uris: None,
2315            }),
2316            None,
2317        );
2318
2319        let mut streamer = qlog::streamer::QlogStreamer::new(
2320            qlog::QLOG_VERSION.to_string(),
2321            Some(title),
2322            Some(description),
2323            None,
2324            Instant::now(),
2325            trace,
2326            self.qlog.level,
2327            writer,
2328        );
2329
2330        streamer.start_log().ok();
2331
2332        let ev_data = self
2333            .local_transport_params
2334            .to_qlog(TransportOwner::Local, self.handshake.cipher());
2335
2336        // This event occurs very early, so just mark the relative time as 0.0.
2337        streamer.add_event(Event::with_time(0.0, ev_data)).ok();
2338
2339        self.qlog.streamer = Some(streamer);
2340    }
2341
2342    /// Returns a mutable reference to the QlogStreamer, if it exists.
2343    #[cfg(feature = "qlog")]
2344    #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2345    pub fn qlog_streamer(&mut self) -> Option<&mut qlog::streamer::QlogStreamer> {
2346        self.qlog.streamer.as_mut()
2347    }
2348
2349    /// Configures the given session for resumption.
2350    ///
2351    /// On the client, this can be used to offer the given serialized session,
2352    /// as returned by [`session()`], for resumption.
2353    ///
2354    /// This must only be called immediately after creating a connection, that
2355    /// is, before any packet is sent or received.
2356    ///
2357    /// [`session()`]: struct.Connection.html#method.session
2358    #[inline]
2359    pub fn set_session(&mut self, session: &[u8]) -> Result<()> {
2360        let mut b = octets::Octets::with_slice(session);
2361
2362        let session_len = b.get_u64()? as usize;
2363        let session_bytes = b.get_bytes(session_len)?;
2364
2365        self.handshake.set_session(session_bytes.as_ref())?;
2366
2367        let raw_params_len = b.get_u64()? as usize;
2368        let raw_params_bytes = b.get_bytes(raw_params_len)?;
2369
2370        let peer_params = TransportParams::decode(
2371            raw_params_bytes.as_ref(),
2372            self.is_server,
2373            self.peer_transport_params_track_unknown,
2374        )?;
2375
2376        self.process_peer_transport_params(peer_params)?;
2377
2378        Ok(())
2379    }
2380
2381    /// Sets the `max_idle_timeout` transport parameter, in milliseconds.
2382    ///
2383    /// This must only be called immediately after creating a connection, that
2384    /// is, before any packet is sent or received.
2385    ///
2386    /// The default value is infinite, that is, no timeout is used unless
2387    /// already configured when creating the connection.
2388    pub fn set_max_idle_timeout(&mut self, v: u64) -> Result<()> {
2389        self.local_transport_params.max_idle_timeout =
2390            cmp::min(v, octets::MAX_VAR_INT);
2391
2392        self.encode_transport_params()
2393    }
2394
2395    /// Sets the congestion control algorithm used.
2396    ///
2397    /// This function can only be called inside one of BoringSSL's handshake
2398    /// callbacks, before any packet has been sent. Calling this function any
2399    /// other time will have no effect.
2400    ///
2401    /// See [`Config::set_cc_algorithm()`].
2402    ///
2403    /// [`Config::set_cc_algorithm()`]: struct.Config.html#method.set_cc_algorithm
2404    #[cfg(feature = "boringssl-boring-crate")]
2405    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2406    pub fn set_cc_algorithm_in_handshake(
2407        ssl: &mut boring::ssl::SslRef, algo: CongestionControlAlgorithm,
2408    ) -> Result<()> {
2409        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2410
2411        ex_data.recovery_config.cc_algorithm = algo;
2412
2413        Ok(())
2414    }
2415
2416    /// Sets custom BBR settings.
2417    ///
2418    /// This API is experimental and will be removed in the future.
2419    ///
2420    /// Currently this only applies if cc_algorithm is
2421    /// `CongestionControlAlgorithm::Bbr2Gcongestion` is set.
2422    ///
2423    /// This function can only be called inside one of BoringSSL's handshake
2424    /// callbacks, before any packet has been sent. Calling this function any
2425    /// other time will have no effect.
2426    ///
2427    /// See [`Config::set_custom_bbr_settings()`].
2428    ///
2429    /// [`Config::set_custom_bbr_settings()`]: struct.Config.html#method.set_custom_bbr_settings
2430    #[cfg(all(feature = "boringssl-boring-crate", feature = "internal"))]
2431    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2432    #[doc(hidden)]
2433    pub fn set_custom_bbr_settings_in_handshake(
2434        ssl: &mut boring::ssl::SslRef, custom_bbr_params: BbrParams,
2435    ) -> Result<()> {
2436        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2437
2438        ex_data.recovery_config.custom_bbr_params = Some(custom_bbr_params);
2439
2440        Ok(())
2441    }
2442
2443    /// Sets the congestion control algorithm used by string.
2444    ///
2445    /// This function can only be called inside one of BoringSSL's handshake
2446    /// callbacks, before any packet has been sent. Calling this function any
2447    /// other time will have no effect.
2448    ///
2449    /// See [`Config::set_cc_algorithm_name()`].
2450    ///
2451    /// [`Config::set_cc_algorithm_name()`]: struct.Config.html#method.set_cc_algorithm_name
2452    #[cfg(feature = "boringssl-boring-crate")]
2453    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2454    pub fn set_cc_algorithm_name_in_handshake(
2455        ssl: &mut boring::ssl::SslRef, name: &str,
2456    ) -> Result<()> {
2457        let cc_algo = CongestionControlAlgorithm::from_str(name)?;
2458        Self::set_cc_algorithm_in_handshake(ssl, cc_algo)
2459    }
2460
2461    /// Sets initial congestion window size in terms of packet count.
2462    ///
2463    /// This function can only be called inside one of BoringSSL's handshake
2464    /// callbacks, before any packet has been sent. Calling this function any
2465    /// other time will have no effect.
2466    ///
2467    /// See [`Config::set_initial_congestion_window_packets()`].
2468    ///
2469    /// [`Config::set_initial_congestion_window_packets()`]: struct.Config.html#method.set_initial_congestion_window_packets
2470    #[cfg(feature = "boringssl-boring-crate")]
2471    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2472    pub fn set_initial_congestion_window_packets_in_handshake(
2473        ssl: &mut boring::ssl::SslRef, packets: usize,
2474    ) -> Result<()> {
2475        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2476
2477        ex_data.recovery_config.initial_congestion_window_packets = packets;
2478
2479        Ok(())
2480    }
2481
2482    /// Configure whether to enable relaxed loss detection on spurious loss.
2483    ///
2484    /// This function can only be called inside one of BoringSSL's handshake
2485    /// callbacks, before any packet has been sent. Calling this function any
2486    /// other time will have no effect.
2487    ///
2488    /// See [`Config::set_enable_relaxed_loss_threshold()`].
2489    ///
2490    /// [`Config::set_enable_relaxed_loss_threshold()`]: struct.Config.html#method.set_enable_relaxed_loss_threshold
2491    #[cfg(feature = "boringssl-boring-crate")]
2492    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2493    pub fn set_enable_relaxed_loss_threshold_in_handshake(
2494        ssl: &mut boring::ssl::SslRef, enable: bool,
2495    ) -> Result<()> {
2496        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2497
2498        ex_data.recovery_config.enable_relaxed_loss_threshold = enable;
2499
2500        Ok(())
2501    }
2502
2503    /// Configures whether to enable HyStart++.
2504    ///
2505    /// This function can only be called inside one of BoringSSL's handshake
2506    /// callbacks, before any packet has been sent. Calling this function any
2507    /// other time will have no effect.
2508    ///
2509    /// See [`Config::enable_hystart()`].
2510    ///
2511    /// [`Config::enable_hystart()`]: struct.Config.html#method.enable_hystart
2512    #[cfg(feature = "boringssl-boring-crate")]
2513    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2514    pub fn set_hystart_in_handshake(
2515        ssl: &mut boring::ssl::SslRef, v: bool,
2516    ) -> Result<()> {
2517        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2518
2519        ex_data.recovery_config.hystart = v;
2520
2521        Ok(())
2522    }
2523
2524    /// Configures whether to enable pacing.
2525    ///
2526    /// This function can only be called inside one of BoringSSL's handshake
2527    /// callbacks, before any packet has been sent. Calling this function any
2528    /// other time will have no effect.
2529    ///
2530    /// See [`Config::enable_pacing()`].
2531    ///
2532    /// [`Config::enable_pacing()`]: struct.Config.html#method.enable_pacing
2533    #[cfg(feature = "boringssl-boring-crate")]
2534    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2535    pub fn set_pacing_in_handshake(
2536        ssl: &mut boring::ssl::SslRef, v: bool,
2537    ) -> Result<()> {
2538        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2539
2540        ex_data.recovery_config.pacing = v;
2541
2542        Ok(())
2543    }
2544
2545    /// Sets the max value for pacing rate.
2546    ///
2547    /// This function can only be called inside one of BoringSSL's handshake
2548    /// callbacks, before any packet has been sent. Calling this function any
2549    /// other time will have no effect.
2550    ///
2551    /// See [`Config::set_max_pacing_rate()`].
2552    ///
2553    /// [`Config::set_max_pacing_rate()`]: struct.Config.html#method.set_max_pacing_rate
2554    #[cfg(feature = "boringssl-boring-crate")]
2555    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2556    pub fn set_max_pacing_rate_in_handshake(
2557        ssl: &mut boring::ssl::SslRef, v: Option<u64>,
2558    ) -> Result<()> {
2559        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2560
2561        ex_data.recovery_config.max_pacing_rate = v;
2562
2563        Ok(())
2564    }
2565
2566    /// Sets the maximum outgoing UDP payload size.
2567    ///
2568    /// This function can only be called inside one of BoringSSL's handshake
2569    /// callbacks, before any packet has been sent. Calling this function any
2570    /// other time will have no effect.
2571    ///
2572    /// See [`Config::set_max_send_udp_payload_size()`].
2573    ///
2574    /// [`Config::set_max_send_udp_payload_size()`]: struct.Config.html#method.set_max_send_udp_payload_size
2575    #[cfg(feature = "boringssl-boring-crate")]
2576    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2577    pub fn set_max_send_udp_payload_size_in_handshake(
2578        ssl: &mut boring::ssl::SslRef, v: usize,
2579    ) -> Result<()> {
2580        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2581
2582        ex_data.recovery_config.max_send_udp_payload_size = v;
2583
2584        Ok(())
2585    }
2586
2587    /// Sets the send capacity factor.
2588    ///
2589    /// This function can only be called inside one of BoringSSL's handshake
2590    /// callbacks, before any packet has been sent. Calling this function any
2591    /// other time will have no effect.
2592    ///
2593    /// See [`Config::set_send_capacity_factor()`].
2594    ///
2595    /// [`Config::set_max_send_udp_payload_size()`]: struct.Config.html#method.set_send_capacity_factor
2596    #[cfg(feature = "boringssl-boring-crate")]
2597    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2598    pub fn set_send_capacity_factor_in_handshake(
2599        ssl: &mut boring::ssl::SslRef, v: f64,
2600    ) -> Result<()> {
2601        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2602
2603        ex_data.tx_cap_factor = v;
2604
2605        Ok(())
2606    }
2607
2608    /// Configures whether to do path MTU discovery.
2609    ///
2610    /// This function can only be called inside one of BoringSSL's handshake
2611    /// callbacks, before any packet has been sent. Calling this function any
2612    /// other time will have no effect.
2613    ///
2614    /// See [`Config::discover_pmtu()`].
2615    ///
2616    /// [`Config::discover_pmtu()`]: struct.Config.html#method.discover_pmtu
2617    #[cfg(feature = "boringssl-boring-crate")]
2618    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2619    pub fn set_discover_pmtu_in_handshake(
2620        ssl: &mut boring::ssl::SslRef, discover: bool,
2621    ) -> Result<()> {
2622        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2623
2624        ex_data.pmtud = Some(discover);
2625
2626        Ok(())
2627    }
2628
2629    /// Sets the `max_idle_timeout` transport parameter, in milliseconds.
2630    ///
2631    /// This function can only be called inside one of BoringSSL's handshake
2632    /// callbacks, before any packet has been sent. Calling this function any
2633    /// other time will have no effect.
2634    ///
2635    /// See [`Config::set_max_idle_timeout()`].
2636    ///
2637    /// [`Config::set_max_idle_timeout()`]: struct.Config.html#method.set_max_idle_timeout
2638    #[cfg(feature = "boringssl-boring-crate")]
2639    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2640    pub fn set_max_idle_timeout_in_handshake(
2641        ssl: &mut boring::ssl::SslRef, v: u64,
2642    ) -> Result<()> {
2643        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2644
2645        ex_data.local_transport_params.max_idle_timeout = v;
2646
2647        Self::set_transport_parameters_in_hanshake(
2648            ex_data.local_transport_params.clone(),
2649            ex_data.is_server,
2650            ssl,
2651        )
2652    }
2653
2654    /// Sets the `initial_max_streams_bidi` transport parameter.
2655    ///
2656    /// This function can only be called inside one of BoringSSL's handshake
2657    /// callbacks, before any packet has been sent. Calling this function any
2658    /// other time will have no effect.
2659    ///
2660    /// See [`Config::set_initial_max_streams_bidi()`].
2661    ///
2662    /// [`Config::set_initial_max_streams_bidi()`]: struct.Config.html#method.set_initial_max_streams_bidi
2663    #[cfg(feature = "boringssl-boring-crate")]
2664    #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2665    pub fn set_initial_max_streams_bidi_in_handshake(
2666        ssl: &mut boring::ssl::SslRef, v: u64,
2667    ) -> Result<()> {
2668        let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2669
2670        ex_data.local_transport_params.initial_max_streams_bidi = v;
2671
2672        Self::set_transport_parameters_in_hanshake(
2673            ex_data.local_transport_params.clone(),
2674            ex_data.is_server,
2675            ssl,
2676        )
2677    }
2678
2679    #[cfg(feature = "boringssl-boring-crate")]
2680    fn set_transport_parameters_in_hanshake(
2681        params: TransportParams, is_server: bool, ssl: &mut boring::ssl::SslRef,
2682    ) -> Result<()> {
2683        use foreign_types_shared::ForeignTypeRef;
2684
2685        // In order to apply the new parameter to the TLS state before TPs are
2686        // written into a TLS message, we need to re-encode all TPs immediately.
2687        //
2688        // Since we don't have direct access to the main `Connection` object, we
2689        // need to re-create the `Handshake` state from the `SslRef`.
2690        //
2691        // SAFETY: the `Handshake` object must not be drop()ed, otherwise it
2692        // would free the underlying BoringSSL structure.
2693        let mut handshake =
2694            unsafe { tls::Handshake::from_ptr(ssl.as_ptr() as _) };
2695        handshake.set_quic_transport_params(&params, is_server)?;
2696
2697        // Avoid running `drop(handshake)` as that would free the underlying
2698        // handshake state.
2699        std::mem::forget(handshake);
2700
2701        Ok(())
2702    }
2703
2704    /// Processes QUIC packets received from the peer.
2705    ///
2706    /// On success the number of bytes processed from the input buffer is
2707    /// returned. On error the connection will be closed by calling [`close()`]
2708    /// with the appropriate error code.
2709    ///
2710    /// Coalesced packets will be processed as necessary.
2711    ///
2712    /// Note that the contents of the input buffer `buf` might be modified by
2713    /// this function due to, for example, in-place decryption.
2714    ///
2715    /// [`close()`]: struct.Connection.html#method.close
2716    ///
2717    /// ## Examples:
2718    ///
2719    /// ```no_run
2720    /// # let mut buf = [0; 512];
2721    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
2722    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
2723    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
2724    /// # let peer = "127.0.0.1:1234".parse().unwrap();
2725    /// # let local = socket.local_addr().unwrap();
2726    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
2727    /// loop {
2728    ///     let (read, from) = socket.recv_from(&mut buf).unwrap();
2729    ///
2730    ///     let recv_info = quiche::RecvInfo {
2731    ///         from,
2732    ///         to: local,
2733    ///     };
2734    ///
2735    ///     let read = match conn.recv(&mut buf[..read], recv_info) {
2736    ///         Ok(v) => v,
2737    ///
2738    ///         Err(e) => {
2739    ///             // An error occurred, handle it.
2740    ///             break;
2741    ///         },
2742    ///     };
2743    /// }
2744    /// # Ok::<(), quiche::Error>(())
2745    /// ```
2746    pub fn recv(&mut self, buf: &mut [u8], info: RecvInfo) -> Result<usize> {
2747        let len = buf.len();
2748
2749        if len == 0 {
2750            return Err(Error::BufferTooShort);
2751        }
2752
2753        let recv_pid = self.paths.path_id_from_addrs(&(info.to, info.from));
2754
2755        if let Some(recv_pid) = recv_pid {
2756            let recv_path = self.paths.get_mut(recv_pid)?;
2757
2758            // Keep track of how many bytes we received from the client, so we
2759            // can limit bytes sent back before address validation, to a
2760            // multiple of this. The limit needs to be increased early on, so
2761            // that if there is an error there is enough credit to send a
2762            // CONNECTION_CLOSE.
2763            //
2764            // It doesn't matter if the packets received were valid or not, we
2765            // only need to track the total amount of bytes received.
2766            //
2767            // Note that we also need to limit the number of bytes we sent on a
2768            // path if we are not the host that initiated its usage.
2769            if self.is_server && !recv_path.verified_peer_address {
2770                recv_path.max_send_bytes += len * self.max_amplification_factor;
2771            }
2772        } else if !self.is_server {
2773            // If a client receives packets from an unknown server address,
2774            // the client MUST discard these packets.
2775            trace!(
2776                "{} client received packet from unknown address {:?}, dropping",
2777                self.trace_id,
2778                info,
2779            );
2780
2781            return Ok(len);
2782        }
2783
2784        let mut done = 0;
2785        let mut left = len;
2786
2787        // Process coalesced packets.
2788        while left > 0 {
2789            let read = match self.recv_single(
2790                &mut buf[len - left..len],
2791                &info,
2792                recv_pid,
2793            ) {
2794                Ok(v) => v,
2795
2796                Err(Error::Done) => {
2797                    // If the packet can't be processed or decrypted, check if
2798                    // it's a stateless reset.
2799                    if self.is_stateless_reset(&buf[len - left..len]) {
2800                        trace!("{} packet is a stateless reset", self.trace_id);
2801
2802                        self.mark_closed();
2803                    }
2804
2805                    left
2806                },
2807
2808                Err(e) => {
2809                    // In case of error processing the incoming packet, close
2810                    // the connection.
2811                    self.close(false, e.to_wire(), b"").ok();
2812                    return Err(e);
2813                },
2814            };
2815
2816            done += read;
2817            left -= read;
2818        }
2819
2820        // Even though the packet was previously "accepted", it
2821        // should be safe to forward the error, as it also comes
2822        // from the `recv()` method.
2823        self.process_undecrypted_0rtt_packets()?;
2824
2825        Ok(done)
2826    }
2827
2828    fn process_undecrypted_0rtt_packets(&mut self) -> Result<()> {
2829        // Process previously undecryptable 0-RTT packets if the decryption key
2830        // is now available.
2831        if self.crypto_ctx[packet::Epoch::Application]
2832            .crypto_0rtt_open
2833            .is_some()
2834        {
2835            while let Some((mut pkt, info)) = self.undecryptable_pkts.pop_front()
2836            {
2837                if let Err(e) = self.recv(&mut pkt, info) {
2838                    self.undecryptable_pkts.clear();
2839
2840                    return Err(e);
2841                }
2842            }
2843        }
2844        Ok(())
2845    }
2846
2847    /// Returns true if a QUIC packet is a stateless reset.
2848    fn is_stateless_reset(&self, buf: &[u8]) -> bool {
2849        // If the packet is too small, then we just throw it away.
2850        let buf_len = buf.len();
2851        if buf_len < 21 {
2852            return false;
2853        }
2854
2855        // TODO: we should iterate over all active destination connection IDs
2856        // and check against their reset token.
2857        match self.peer_transport_params.stateless_reset_token {
2858            Some(token) => {
2859                let token_len = 16;
2860
2861                crypto::verify_slices_are_equal(
2862                    &token.to_be_bytes(),
2863                    &buf[buf_len - token_len..buf_len],
2864                )
2865                .is_ok()
2866            },
2867
2868            None => false,
2869        }
2870    }
2871
2872    /// Processes a single QUIC packet received from the peer.
2873    ///
2874    /// On success the number of bytes processed from the input buffer is
2875    /// returned. When the [`Done`] error is returned, processing of the
2876    /// remainder of the incoming UDP datagram should be interrupted.
2877    ///
2878    /// Note that a server might observe a new 4-tuple, preventing to
2879    /// know in advance to which path the incoming packet belongs to (`recv_pid`
2880    /// is `None`). As a client, packets from unknown 4-tuple are dropped
2881    /// beforehand (see `recv()`).
2882    ///
2883    /// On error, an error other than [`Done`] is returned.
2884    ///
2885    /// [`Done`]: enum.Error.html#variant.Done
2886    fn recv_single(
2887        &mut self, buf: &mut [u8], info: &RecvInfo, recv_pid: Option<usize>,
2888    ) -> Result<usize> {
2889        let now = Instant::now();
2890
2891        if buf.is_empty() {
2892            return Err(Error::Done);
2893        }
2894
2895        if self.is_closed() || self.is_draining() {
2896            return Err(Error::Done);
2897        }
2898
2899        let is_closing = self.local_error.is_some();
2900
2901        if is_closing {
2902            return Err(Error::Done);
2903        }
2904
2905        let buf_len = buf.len();
2906
2907        let mut b = octets::OctetsMut::with_slice(buf);
2908
2909        let mut hdr = Header::from_bytes(&mut b, self.source_id().len())
2910            .map_err(|e| {
2911                drop_pkt_on_err(
2912                    e,
2913                    self.recv_count,
2914                    self.is_server,
2915                    &self.trace_id,
2916                )
2917            })?;
2918
2919        if hdr.ty == Type::VersionNegotiation {
2920            // Version negotiation packets can only be sent by the server.
2921            if self.is_server {
2922                return Err(Error::Done);
2923            }
2924
2925            // Ignore duplicate version negotiation.
2926            if self.did_version_negotiation {
2927                return Err(Error::Done);
2928            }
2929
2930            // Ignore version negotiation if any other packet has already been
2931            // successfully processed.
2932            if self.recv_count > 0 {
2933                return Err(Error::Done);
2934            }
2935
2936            if hdr.dcid != self.source_id() {
2937                return Err(Error::Done);
2938            }
2939
2940            if hdr.scid != self.destination_id() {
2941                return Err(Error::Done);
2942            }
2943
2944            trace!("{} rx pkt {:?}", self.trace_id, hdr);
2945
2946            let versions = hdr.versions.ok_or(Error::Done)?;
2947
2948            // Ignore version negotiation if the version already selected is
2949            // listed.
2950            if versions.contains(&self.version) {
2951                return Err(Error::Done);
2952            }
2953
2954            let supported_versions =
2955                versions.iter().filter(|&&v| version_is_supported(v));
2956
2957            let mut found_version = false;
2958
2959            for &v in supported_versions {
2960                found_version = true;
2961
2962                // The final version takes precedence over draft ones.
2963                if v == PROTOCOL_VERSION_V1 {
2964                    self.version = v;
2965                    break;
2966                }
2967
2968                self.version = cmp::max(self.version, v);
2969            }
2970
2971            if !found_version {
2972                // We don't support any of the versions offered.
2973                //
2974                // While a man-in-the-middle attacker might be able to
2975                // inject a version negotiation packet that triggers this
2976                // failure, the window of opportunity is very small and
2977                // this error is quite useful for debugging, so don't just
2978                // ignore the packet.
2979                return Err(Error::UnknownVersion);
2980            }
2981
2982            self.did_version_negotiation = true;
2983
2984            // Derive Initial secrets based on the new version.
2985            let (aead_open, aead_seal) = crypto::derive_initial_key_material(
2986                &self.destination_id(),
2987                self.version,
2988                self.is_server,
2989                true,
2990            )?;
2991
2992            // Reset connection state to force sending another Initial packet.
2993            self.drop_epoch_state(packet::Epoch::Initial, now);
2994            self.got_peer_conn_id = false;
2995            self.handshake.clear()?;
2996
2997            self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
2998            self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
2999
3000            self.handshake
3001                .use_legacy_codepoint(self.version != PROTOCOL_VERSION_V1);
3002
3003            // Encode transport parameters again, as the new version might be
3004            // using a different format.
3005            self.encode_transport_params()?;
3006
3007            return Err(Error::Done);
3008        }
3009
3010        if hdr.ty == Type::Retry {
3011            // Retry packets can only be sent by the server.
3012            if self.is_server {
3013                return Err(Error::Done);
3014            }
3015
3016            // Ignore duplicate retry.
3017            if self.did_retry {
3018                return Err(Error::Done);
3019            }
3020
3021            // Check if Retry packet is valid.
3022            if packet::verify_retry_integrity(
3023                &b,
3024                &self.destination_id(),
3025                self.version,
3026            )
3027            .is_err()
3028            {
3029                return Err(Error::Done);
3030            }
3031
3032            trace!("{} rx pkt {:?}", self.trace_id, hdr);
3033
3034            self.token = hdr.token;
3035            self.did_retry = true;
3036
3037            // Remember peer's new connection ID.
3038            self.odcid = Some(self.destination_id().into_owned());
3039
3040            self.set_initial_dcid(
3041                hdr.scid.clone(),
3042                None,
3043                self.paths.get_active_path_id()?,
3044            )?;
3045
3046            self.rscid = Some(self.destination_id().into_owned());
3047
3048            // Derive Initial secrets using the new connection ID.
3049            let (aead_open, aead_seal) = crypto::derive_initial_key_material(
3050                &hdr.scid,
3051                self.version,
3052                self.is_server,
3053                true,
3054            )?;
3055
3056            // Reset connection state to force sending another Initial packet.
3057            self.drop_epoch_state(packet::Epoch::Initial, now);
3058            self.got_peer_conn_id = false;
3059            self.handshake.clear()?;
3060
3061            self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
3062            self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
3063
3064            return Err(Error::Done);
3065        }
3066
3067        if self.is_server && !self.did_version_negotiation {
3068            if !version_is_supported(hdr.version) {
3069                return Err(Error::UnknownVersion);
3070            }
3071
3072            self.version = hdr.version;
3073            self.did_version_negotiation = true;
3074
3075            self.handshake
3076                .use_legacy_codepoint(self.version != PROTOCOL_VERSION_V1);
3077
3078            // Encode transport parameters again, as the new version might be
3079            // using a different format.
3080            self.encode_transport_params()?;
3081        }
3082
3083        if hdr.ty != Type::Short && hdr.version != self.version {
3084            // At this point version negotiation was already performed, so
3085            // ignore packets that don't match the connection's version.
3086            return Err(Error::Done);
3087        }
3088
3089        // Long header packets have an explicit payload length, but short
3090        // packets don't so just use the remaining capacity in the buffer.
3091        let payload_len = if hdr.ty == Type::Short {
3092            b.cap()
3093        } else {
3094            b.get_varint().map_err(|e| {
3095                drop_pkt_on_err(
3096                    e.into(),
3097                    self.recv_count,
3098                    self.is_server,
3099                    &self.trace_id,
3100                )
3101            })? as usize
3102        };
3103
3104        // Make sure the buffer is same or larger than an explicit
3105        // payload length.
3106        if payload_len > b.cap() {
3107            return Err(drop_pkt_on_err(
3108                Error::InvalidPacket,
3109                self.recv_count,
3110                self.is_server,
3111                &self.trace_id,
3112            ));
3113        }
3114
3115        // Derive initial secrets on the server.
3116        if !self.derived_initial_secrets {
3117            let (aead_open, aead_seal) = crypto::derive_initial_key_material(
3118                &hdr.dcid,
3119                self.version,
3120                self.is_server,
3121                false,
3122            )?;
3123
3124            self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
3125            self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
3126
3127            self.derived_initial_secrets = true;
3128        }
3129
3130        // Select packet number space epoch based on the received packet's type.
3131        let epoch = hdr.ty.to_epoch()?;
3132
3133        // Select AEAD context used to open incoming packet.
3134        let aead = if hdr.ty == Type::ZeroRTT {
3135            // Only use 0-RTT key if incoming packet is 0-RTT.
3136            self.crypto_ctx[epoch].crypto_0rtt_open.as_ref()
3137        } else {
3138            // Otherwise use the packet number space's main key.
3139            self.crypto_ctx[epoch].crypto_open.as_ref()
3140        };
3141
3142        // Finally, discard packet if no usable key is available.
3143        let mut aead = match aead {
3144            Some(v) => v,
3145
3146            None => {
3147                if hdr.ty == Type::ZeroRTT &&
3148                    self.undecryptable_pkts.len() < MAX_UNDECRYPTABLE_PACKETS &&
3149                    !self.is_established()
3150                {
3151                    // Buffer 0-RTT packets when the required read key is not
3152                    // available yet, and process them later.
3153                    //
3154                    // TODO: in the future we might want to buffer other types
3155                    // of undecryptable packets as well.
3156                    let pkt_len = b.off() + payload_len;
3157                    let pkt = (b.buf()[..pkt_len]).to_vec();
3158
3159                    self.undecryptable_pkts.push_back((pkt, *info));
3160                    return Ok(pkt_len);
3161                }
3162
3163                let e = drop_pkt_on_err(
3164                    Error::CryptoFail,
3165                    self.recv_count,
3166                    self.is_server,
3167                    &self.trace_id,
3168                );
3169
3170                return Err(e);
3171            },
3172        };
3173
3174        let aead_tag_len = aead.alg().tag_len();
3175
3176        packet::decrypt_hdr(&mut b, &mut hdr, aead).map_err(|e| {
3177            drop_pkt_on_err(e, self.recv_count, self.is_server, &self.trace_id)
3178        })?;
3179
3180        let pn = packet::decode_pkt_num(
3181            self.pkt_num_spaces[epoch].largest_rx_pkt_num,
3182            hdr.pkt_num,
3183            hdr.pkt_num_len,
3184        );
3185
3186        let pn_len = hdr.pkt_num_len;
3187
3188        trace!(
3189            "{} rx pkt {:?} len={} pn={} {}",
3190            self.trace_id,
3191            hdr,
3192            payload_len,
3193            pn,
3194            AddrTupleFmt(info.from, info.to)
3195        );
3196
3197        #[cfg(feature = "qlog")]
3198        let mut qlog_frames = vec![];
3199
3200        // Check for key update.
3201        let mut aead_next = None;
3202
3203        if self.handshake_confirmed &&
3204            hdr.ty != Type::ZeroRTT &&
3205            hdr.key_phase != self.key_phase
3206        {
3207            // Check if this packet arrived before key update.
3208            if let Some(key_update) = self.crypto_ctx[epoch]
3209                .key_update
3210                .as_ref()
3211                .and_then(|key_update| {
3212                    (pn < key_update.pn_on_update).then_some(key_update)
3213                })
3214            {
3215                aead = &key_update.crypto_open;
3216            } else {
3217                trace!("{} peer-initiated key update", self.trace_id);
3218
3219                aead_next = Some((
3220                    self.crypto_ctx[epoch]
3221                        .crypto_open
3222                        .as_ref()
3223                        .unwrap()
3224                        .derive_next_packet_key()?,
3225                    self.crypto_ctx[epoch]
3226                        .crypto_seal
3227                        .as_ref()
3228                        .unwrap()
3229                        .derive_next_packet_key()?,
3230                ));
3231
3232                // `aead_next` is always `Some()` at this point, so the `unwrap()`
3233                // will never fail.
3234                aead = &aead_next.as_ref().unwrap().0;
3235            }
3236        }
3237
3238        let mut payload = packet::decrypt_pkt(
3239            &mut b,
3240            pn,
3241            pn_len,
3242            payload_len,
3243            aead,
3244        )
3245        .map_err(|e| {
3246            drop_pkt_on_err(e, self.recv_count, self.is_server, &self.trace_id)
3247        })?;
3248
3249        if self.pkt_num_spaces[epoch].recv_pkt_num.contains(pn) {
3250            trace!("{} ignored duplicate packet {}", self.trace_id, pn);
3251            return Err(Error::Done);
3252        }
3253
3254        // Packets with no frames are invalid.
3255        if payload.cap() == 0 {
3256            return Err(Error::InvalidPacket);
3257        }
3258
3259        // Now that we decrypted the packet, let's see if we can map it to an
3260        // existing path.
3261        let recv_pid = if hdr.ty == Type::Short && self.got_peer_conn_id {
3262            let pkt_dcid = ConnectionId::from_ref(&hdr.dcid);
3263            self.get_or_create_recv_path_id(recv_pid, &pkt_dcid, buf_len, info)?
3264        } else {
3265            // During handshake, we are on the initial path.
3266            self.paths.get_active_path_id()?
3267        };
3268
3269        // The key update is verified once a packet is successfully decrypted
3270        // using the new keys.
3271        if let Some((open_next, seal_next)) = aead_next {
3272            if !self.crypto_ctx[epoch]
3273                .key_update
3274                .as_ref()
3275                .is_none_or(|prev| prev.update_acked)
3276            {
3277                // Peer has updated keys twice without awaiting confirmation.
3278                return Err(Error::KeyUpdate);
3279            }
3280
3281            trace!("{} key update verified", self.trace_id);
3282
3283            let _ = self.crypto_ctx[epoch].crypto_seal.replace(seal_next);
3284
3285            let open_prev = self.crypto_ctx[epoch]
3286                .crypto_open
3287                .replace(open_next)
3288                .unwrap();
3289
3290            let recv_path = self.paths.get_mut(recv_pid)?;
3291
3292            self.crypto_ctx[epoch].key_update = Some(packet::KeyUpdate {
3293                crypto_open: open_prev,
3294                pn_on_update: pn,
3295                update_acked: false,
3296                timer: now + (recv_path.recovery.pto() * 3),
3297            });
3298
3299            self.key_phase = !self.key_phase;
3300
3301            qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3302                let trigger = Some(
3303                    qlog::events::security::KeyUpdateOrRetiredTrigger::RemoteUpdate,
3304                );
3305
3306                let ev_data_client =
3307                    EventData::KeyUpdated(qlog::events::security::KeyUpdated {
3308                        key_type:
3309                            qlog::events::security::KeyType::Client1RttSecret,
3310                        trigger: trigger.clone(),
3311                        ..Default::default()
3312                    });
3313
3314                q.add_event_data_with_instant(ev_data_client, now).ok();
3315
3316                let ev_data_server =
3317                    EventData::KeyUpdated(qlog::events::security::KeyUpdated {
3318                        key_type:
3319                            qlog::events::security::KeyType::Server1RttSecret,
3320                        trigger,
3321                        ..Default::default()
3322                    });
3323
3324                q.add_event_data_with_instant(ev_data_server, now).ok();
3325            });
3326        }
3327
3328        if !self.is_server && !self.got_peer_conn_id {
3329            if self.odcid.is_none() {
3330                self.odcid = Some(self.destination_id().into_owned());
3331            }
3332
3333            // Replace the randomly generated destination connection ID with
3334            // the one supplied by the server.
3335            self.set_initial_dcid(
3336                hdr.scid.clone(),
3337                self.peer_transport_params.stateless_reset_token,
3338                recv_pid,
3339            )?;
3340
3341            self.got_peer_conn_id = true;
3342        }
3343
3344        if self.is_server && !self.got_peer_conn_id {
3345            self.set_initial_dcid(hdr.scid.clone(), None, recv_pid)?;
3346
3347            if !self.did_retry {
3348                self.local_transport_params
3349                    .original_destination_connection_id =
3350                    Some(hdr.dcid.to_vec().into());
3351
3352                self.encode_transport_params()?;
3353            }
3354
3355            self.got_peer_conn_id = true;
3356        }
3357
3358        // To avoid sending an ACK in response to an ACK-only packet, we need
3359        // to keep track of whether this packet contains any frame other than
3360        // ACK and PADDING.
3361        let mut ack_elicited = false;
3362
3363        // Process packet payload. If a frame cannot be processed, store the
3364        // error and stop further packet processing.
3365        let mut frame_processing_err = None;
3366
3367        // To know if the peer migrated the connection, we need to keep track
3368        // whether this is a non-probing packet.
3369        let mut probing = true;
3370
3371        // Process packet payload.
3372        while payload.cap() > 0 {
3373            let frame = frame::Frame::from_bytes(&mut payload, hdr.ty)?;
3374
3375            qlog_with_type!(QLOG_PACKET_RX, self.qlog, _q, {
3376                qlog_frames.push(frame.to_qlog());
3377            });
3378
3379            if frame.ack_eliciting() {
3380                ack_elicited = true;
3381            }
3382
3383            if !frame.probing() {
3384                probing = false;
3385            }
3386
3387            if let Err(e) = self.process_frame(frame, &hdr, recv_pid, epoch, now)
3388            {
3389                frame_processing_err = Some(e);
3390                break;
3391            }
3392        }
3393
3394        qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3395            let packet_size = b.len();
3396
3397            let qlog_pkt_hdr = qlog::events::quic::PacketHeader::with_type(
3398                hdr.ty.to_qlog(),
3399                Some(pn),
3400                Some(hdr.version),
3401                Some(&hdr.scid),
3402                Some(&hdr.dcid),
3403            );
3404
3405            let qlog_raw_info = RawInfo {
3406                length: Some(packet_size as u64),
3407                payload_length: Some(payload_len as u64),
3408                data: None,
3409            };
3410
3411            let ev_data =
3412                EventData::PacketReceived(qlog::events::quic::PacketReceived {
3413                    header: qlog_pkt_hdr,
3414                    frames: Some(qlog_frames),
3415                    raw: Some(qlog_raw_info),
3416                    ..Default::default()
3417                });
3418
3419            q.add_event_data_with_instant(ev_data, now).ok();
3420        });
3421
3422        qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3423            let recv_path = self.paths.get_mut(recv_pid)?;
3424            recv_path.recovery.maybe_qlog(q, now);
3425        });
3426
3427        if let Some(e) = frame_processing_err {
3428            // Any frame error is terminal, so now just return.
3429            return Err(e);
3430        }
3431
3432        // Only log the remote transport parameters once the connection is
3433        // established (i.e. after frames have been fully parsed) and only
3434        // once per connection.
3435        if self.is_established() {
3436            qlog_with_type!(QLOG_PARAMS_SET, self.qlog, q, {
3437                if !self.qlog.logged_peer_params {
3438                    let ev_data = self
3439                        .peer_transport_params
3440                        .to_qlog(TransportOwner::Remote, self.handshake.cipher());
3441
3442                    q.add_event_data_with_instant(ev_data, now).ok();
3443
3444                    self.qlog.logged_peer_params = true;
3445                }
3446            });
3447        }
3448
3449        // Process acked frames. Note that several packets from several paths
3450        // might have been acked by the received packet.
3451        for (_, p) in self.paths.iter_mut() {
3452            for acked in p.recovery.get_acked_frames(epoch) {
3453                match acked {
3454                    frame::Frame::Ping {
3455                        mtu_probe: Some(mtu_probe),
3456                    } =>
3457                        if let Some(pmtud) = p.pmtud.as_mut() {
3458                            trace!(
3459                                "{} pmtud probe acked; probe size {:?}",
3460                                self.trace_id,
3461                                mtu_probe
3462                            );
3463
3464                            // Ensure the probe is within the supported MTU range
3465                            // before updating the max datagram size
3466                            if let Some(current_mtu) =
3467                                pmtud.successful_probe(mtu_probe)
3468                            {
3469                                qlog_with_type!(
3470                                    EventType::ConnectivityEventType(
3471                                        ConnectivityEventType::MtuUpdated
3472                                    ),
3473                                    self.qlog,
3474                                    q,
3475                                    {
3476                                        let pmtu_data = EventData::MtuUpdated(
3477                                            qlog::events::connectivity::MtuUpdated {
3478                                                old: Some(
3479                                                    p.recovery.max_datagram_size()
3480                                                        as u16,
3481                                                ),
3482                                                new: current_mtu as u16,
3483                                                done: Some(true),
3484                                            },
3485                                        );
3486
3487                                        q.add_event_data_with_instant(
3488                                            pmtu_data, now,
3489                                        )
3490                                        .ok();
3491                                    }
3492                                );
3493
3494                                p.recovery
3495                                    .pmtud_update_max_datagram_size(current_mtu);
3496                            }
3497                        },
3498
3499                    frame::Frame::ACK { ranges, .. } => {
3500                        // Stop acknowledging packets less than or equal to the
3501                        // largest acknowledged in the sent ACK frame that, in
3502                        // turn, got acked.
3503                        if let Some(largest_acked) = ranges.last() {
3504                            self.pkt_num_spaces[epoch]
3505                                .recv_pkt_need_ack
3506                                .remove_until(largest_acked);
3507                        }
3508                    },
3509
3510                    frame::Frame::CryptoHeader { offset, length } => {
3511                        self.crypto_ctx[epoch]
3512                            .crypto_stream
3513                            .send
3514                            .ack_and_drop(offset, length);
3515                    },
3516
3517                    frame::Frame::StreamHeader {
3518                        stream_id,
3519                        offset,
3520                        length,
3521                        ..
3522                    } => {
3523                        let stream = match self.streams.get_mut(stream_id) {
3524                            Some(v) => v,
3525
3526                            None => continue,
3527                        };
3528
3529                        stream.send.ack_and_drop(offset, length);
3530
3531                        self.tx_buffered =
3532                            self.tx_buffered.saturating_sub(length);
3533
3534                        qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
3535                            let ev_data = EventData::DataMoved(
3536                                qlog::events::quic::DataMoved {
3537                                    stream_id: Some(stream_id),
3538                                    offset: Some(offset),
3539                                    length: Some(length as u64),
3540                                    from: Some(DataRecipient::Transport),
3541                                    to: Some(DataRecipient::Dropped),
3542                                    ..Default::default()
3543                                },
3544                            );
3545
3546                            q.add_event_data_with_instant(ev_data, now).ok();
3547                        });
3548
3549                        // Only collect the stream if it is complete and not
3550                        // readable. If it is readable, it will get collected when
3551                        // stream_recv() is used.
3552                        if stream.is_complete() && !stream.is_readable() {
3553                            let local = stream.local;
3554                            self.streams.collect(stream_id, local);
3555                        }
3556                    },
3557
3558                    frame::Frame::HandshakeDone => {
3559                        // Explicitly set this to true, so that if the frame was
3560                        // already scheduled for retransmission, it is aborted.
3561                        self.handshake_done_sent = true;
3562
3563                        self.handshake_done_acked = true;
3564                    },
3565
3566                    frame::Frame::ResetStream { stream_id, .. } => {
3567                        let stream = match self.streams.get_mut(stream_id) {
3568                            Some(v) => v,
3569
3570                            None => continue,
3571                        };
3572
3573                        // Only collect the stream if it is complete and not
3574                        // readable. If it is readable, it will get collected when
3575                        // stream_recv() is used.
3576                        if stream.is_complete() && !stream.is_readable() {
3577                            let local = stream.local;
3578                            self.streams.collect(stream_id, local);
3579                        }
3580                    },
3581
3582                    _ => (),
3583                }
3584            }
3585        }
3586
3587        // Now that we processed all the frames, if there is a path that has no
3588        // Destination CID, try to allocate one.
3589        let no_dcid = self
3590            .paths
3591            .iter_mut()
3592            .filter(|(_, p)| p.active_dcid_seq.is_none());
3593
3594        for (pid, p) in no_dcid {
3595            if self.ids.zero_length_dcid() {
3596                p.active_dcid_seq = Some(0);
3597                continue;
3598            }
3599
3600            let dcid_seq = match self.ids.lowest_available_dcid_seq() {
3601                Some(seq) => seq,
3602                None => break,
3603            };
3604
3605            self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
3606
3607            p.active_dcid_seq = Some(dcid_seq);
3608        }
3609
3610        // We only record the time of arrival of the largest packet number
3611        // that still needs to be acked, to be used for ACK delay calculation.
3612        if self.pkt_num_spaces[epoch].recv_pkt_need_ack.last() < Some(pn) {
3613            self.pkt_num_spaces[epoch].largest_rx_pkt_time = now;
3614        }
3615
3616        self.pkt_num_spaces[epoch].recv_pkt_num.insert(pn);
3617
3618        self.pkt_num_spaces[epoch].recv_pkt_need_ack.push_item(pn);
3619
3620        self.pkt_num_spaces[epoch].ack_elicited =
3621            cmp::max(self.pkt_num_spaces[epoch].ack_elicited, ack_elicited);
3622
3623        self.pkt_num_spaces[epoch].largest_rx_pkt_num =
3624            cmp::max(self.pkt_num_spaces[epoch].largest_rx_pkt_num, pn);
3625
3626        if !probing {
3627            self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num = cmp::max(
3628                self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num,
3629                pn,
3630            );
3631
3632            // Did the peer migrated to another path?
3633            let active_path_id = self.paths.get_active_path_id()?;
3634
3635            if self.is_server &&
3636                recv_pid != active_path_id &&
3637                self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num == pn
3638            {
3639                self.on_peer_migrated(recv_pid, self.disable_dcid_reuse, now)?;
3640            }
3641        }
3642
3643        if let Some(idle_timeout) = self.idle_timeout() {
3644            self.idle_timer = Some(now + idle_timeout);
3645        }
3646
3647        // Update send capacity.
3648        self.update_tx_cap();
3649
3650        self.recv_count += 1;
3651        self.paths.get_mut(recv_pid)?.recv_count += 1;
3652
3653        let read = b.off() + aead_tag_len;
3654
3655        self.recv_bytes += read as u64;
3656        self.paths.get_mut(recv_pid)?.recv_bytes += read as u64;
3657
3658        // An Handshake packet has been received from the client and has been
3659        // successfully processed, so we can drop the initial state and consider
3660        // the client's address to be verified.
3661        if self.is_server && hdr.ty == Type::Handshake {
3662            self.drop_epoch_state(packet::Epoch::Initial, now);
3663
3664            self.paths.get_mut(recv_pid)?.verified_peer_address = true;
3665        }
3666
3667        self.ack_eliciting_sent = false;
3668
3669        Ok(read)
3670    }
3671
3672    /// Writes a single QUIC packet to be sent to the peer.
3673    ///
3674    /// On success the number of bytes written to the output buffer is
3675    /// returned, or [`Done`] if there was nothing to write.
3676    ///
3677    /// The application should call `send()` multiple times until [`Done`] is
3678    /// returned, indicating that there are no more packets to send. It is
3679    /// recommended that `send()` be called in the following cases:
3680    ///
3681    ///  * When the application receives QUIC packets from the peer (that is,
3682    ///    any time [`recv()`] is also called).
3683    ///
3684    ///  * When the connection timer expires (that is, any time [`on_timeout()`]
3685    ///    is also called).
3686    ///
3687    ///  * When the application sends data to the peer (for example, any time
3688    ///    [`stream_send()`] or [`stream_shutdown()`] are called).
3689    ///
3690    ///  * When the application receives data from the peer (for example any
3691    ///    time [`stream_recv()`] is called).
3692    ///
3693    /// Once [`is_draining()`] returns `true`, it is no longer necessary to call
3694    /// `send()` and all calls will return [`Done`].
3695    ///
3696    /// [`Done`]: enum.Error.html#variant.Done
3697    /// [`recv()`]: struct.Connection.html#method.recv
3698    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
3699    /// [`stream_send()`]: struct.Connection.html#method.stream_send
3700    /// [`stream_shutdown()`]: struct.Connection.html#method.stream_shutdown
3701    /// [`stream_recv()`]: struct.Connection.html#method.stream_recv
3702    /// [`is_draining()`]: struct.Connection.html#method.is_draining
3703    ///
3704    /// ## Examples:
3705    ///
3706    /// ```no_run
3707    /// # let mut out = [0; 512];
3708    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
3709    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
3710    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
3711    /// # let peer = "127.0.0.1:1234".parse().unwrap();
3712    /// # let local = socket.local_addr().unwrap();
3713    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
3714    /// loop {
3715    ///     let (write, send_info) = match conn.send(&mut out) {
3716    ///         Ok(v) => v,
3717    ///
3718    ///         Err(quiche::Error::Done) => {
3719    ///             // Done writing.
3720    ///             break;
3721    ///         },
3722    ///
3723    ///         Err(e) => {
3724    ///             // An error occurred, handle it.
3725    ///             break;
3726    ///         },
3727    ///     };
3728    ///
3729    ///     socket.send_to(&out[..write], &send_info.to).unwrap();
3730    /// }
3731    /// # Ok::<(), quiche::Error>(())
3732    /// ```
3733    pub fn send(&mut self, out: &mut [u8]) -> Result<(usize, SendInfo)> {
3734        self.send_on_path(out, None, None)
3735    }
3736
3737    /// Writes a single QUIC packet to be sent to the peer from the specified
3738    /// local address `from` to the destination address `to`.
3739    ///
3740    /// The behavior of this method differs depending on the value of the `from`
3741    /// and `to` parameters:
3742    ///
3743    ///  * If both are `Some`, then the method only consider the 4-tuple
3744    ///    (`from`, `to`). Application can monitor the 4-tuple availability,
3745    ///    either by monitoring [`path_event_next()`] events or by relying on
3746    ///    the [`paths_iter()`] method. If the provided 4-tuple does not exist
3747    ///    on the connection (anymore), it returns an [`InvalidState`].
3748    ///
3749    ///  * If `from` is `Some` and `to` is `None`, then the method only
3750    ///    considers sending packets on paths having `from` as local address.
3751    ///
3752    ///  * If `to` is `Some` and `from` is `None`, then the method only
3753    ///    considers sending packets on paths having `to` as peer address.
3754    ///
3755    ///  * If both are `None`, all available paths are considered.
3756    ///
3757    /// On success the number of bytes written to the output buffer is
3758    /// returned, or [`Done`] if there was nothing to write.
3759    ///
3760    /// The application should call `send_on_path()` multiple times until
3761    /// [`Done`] is returned, indicating that there are no more packets to
3762    /// send. It is recommended that `send_on_path()` be called in the
3763    /// following cases:
3764    ///
3765    ///  * When the application receives QUIC packets from the peer (that is,
3766    ///    any time [`recv()`] is also called).
3767    ///
3768    ///  * When the connection timer expires (that is, any time [`on_timeout()`]
3769    ///    is also called).
3770    ///
3771    ///  * When the application sends data to the peer (for examples, any time
3772    ///    [`stream_send()`] or [`stream_shutdown()`] are called).
3773    ///
3774    ///  * When the application receives data from the peer (for example any
3775    ///    time [`stream_recv()`] is called).
3776    ///
3777    /// Once [`is_draining()`] returns `true`, it is no longer necessary to call
3778    /// `send_on_path()` and all calls will return [`Done`].
3779    ///
3780    /// [`Done`]: enum.Error.html#variant.Done
3781    /// [`InvalidState`]: enum.Error.html#InvalidState
3782    /// [`recv()`]: struct.Connection.html#method.recv
3783    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
3784    /// [`stream_send()`]: struct.Connection.html#method.stream_send
3785    /// [`stream_shutdown()`]: struct.Connection.html#method.stream_shutdown
3786    /// [`stream_recv()`]: struct.Connection.html#method.stream_recv
3787    /// [`path_event_next()`]: struct.Connection.html#method.path_event_next
3788    /// [`paths_iter()`]: struct.Connection.html#method.paths_iter
3789    /// [`is_draining()`]: struct.Connection.html#method.is_draining
3790    ///
3791    /// ## Examples:
3792    ///
3793    /// ```no_run
3794    /// # let mut out = [0; 512];
3795    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
3796    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
3797    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
3798    /// # let peer = "127.0.0.1:1234".parse().unwrap();
3799    /// # let local = socket.local_addr().unwrap();
3800    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
3801    /// loop {
3802    ///     let (write, send_info) = match conn.send_on_path(&mut out, Some(local), Some(peer)) {
3803    ///         Ok(v) => v,
3804    ///
3805    ///         Err(quiche::Error::Done) => {
3806    ///             // Done writing.
3807    ///             break;
3808    ///         },
3809    ///
3810    ///         Err(e) => {
3811    ///             // An error occurred, handle it.
3812    ///             break;
3813    ///         },
3814    ///     };
3815    ///
3816    ///     socket.send_to(&out[..write], &send_info.to).unwrap();
3817    /// }
3818    /// # Ok::<(), quiche::Error>(())
3819    /// ```
3820    pub fn send_on_path(
3821        &mut self, out: &mut [u8], from: Option<SocketAddr>,
3822        to: Option<SocketAddr>,
3823    ) -> Result<(usize, SendInfo)> {
3824        if out.is_empty() {
3825            return Err(Error::BufferTooShort);
3826        }
3827
3828        if self.is_closed() || self.is_draining() {
3829            return Err(Error::Done);
3830        }
3831
3832        let now = Instant::now();
3833
3834        if self.local_error.is_none() {
3835            self.do_handshake(now)?;
3836        }
3837
3838        // Forwarding the error value here could confuse
3839        // applications, as they may not expect getting a `recv()`
3840        // error when calling `send()`.
3841        //
3842        // We simply fall-through to sending packets, which should
3843        // take care of terminating the connection as needed.
3844        let _ = self.process_undecrypted_0rtt_packets();
3845
3846        // There's no point in trying to send a packet if the Initial secrets
3847        // have not been derived yet, so return early.
3848        if !self.derived_initial_secrets {
3849            return Err(Error::Done);
3850        }
3851
3852        let mut has_initial = false;
3853
3854        let mut done = 0;
3855
3856        // Limit output packet size to respect the sender and receiver's
3857        // maximum UDP payload size limit.
3858        let mut left = cmp::min(out.len(), self.max_send_udp_payload_size());
3859
3860        let send_pid = match (from, to) {
3861            (Some(f), Some(t)) => self
3862                .paths
3863                .path_id_from_addrs(&(f, t))
3864                .ok_or(Error::InvalidState)?,
3865
3866            _ => self.get_send_path_id(from, to)?,
3867        };
3868
3869        let send_path = self.paths.get_mut(send_pid)?;
3870
3871        // Update max datagram size to allow path MTU discovery probe to be sent.
3872        if let Some(pmtud) = send_path.pmtud.as_mut() {
3873            if pmtud.should_probe() {
3874                let size = if self.handshake_confirmed || self.handshake_completed
3875                {
3876                    pmtud.get_probe_size()
3877                } else {
3878                    pmtud.get_current_mtu()
3879                };
3880
3881                send_path.recovery.pmtud_update_max_datagram_size(size);
3882
3883                left =
3884                    cmp::min(out.len(), send_path.recovery.max_datagram_size());
3885            }
3886        }
3887
3888        // Limit data sent by the server based on the amount of data received
3889        // from the client before its address is validated.
3890        if !send_path.verified_peer_address && self.is_server {
3891            left = cmp::min(left, send_path.max_send_bytes);
3892        }
3893
3894        // Generate coalesced packets.
3895        while left > 0 {
3896            let (ty, written) = match self.send_single(
3897                &mut out[done..done + left],
3898                send_pid,
3899                has_initial,
3900                now,
3901            ) {
3902                Ok(v) => v,
3903
3904                Err(Error::BufferTooShort) | Err(Error::Done) => break,
3905
3906                Err(e) => return Err(e),
3907            };
3908
3909            done += written;
3910            left -= written;
3911
3912            match ty {
3913                Type::Initial => has_initial = true,
3914
3915                // No more packets can be coalesced after a 1-RTT.
3916                Type::Short => break,
3917
3918                _ => (),
3919            };
3920
3921            // When sending multiple PTO probes, don't coalesce them together,
3922            // so they are sent on separate UDP datagrams.
3923            if let Ok(epoch) = ty.to_epoch() {
3924                if self.paths.get_mut(send_pid)?.recovery.loss_probes(epoch) > 0 {
3925                    break;
3926                }
3927            }
3928
3929            // Don't coalesce packets that must go on different paths.
3930            if !(from.is_some() && to.is_some()) &&
3931                self.get_send_path_id(from, to)? != send_pid
3932            {
3933                break;
3934            }
3935        }
3936
3937        if done == 0 {
3938            self.last_tx_data = self.tx_data;
3939
3940            return Err(Error::Done);
3941        }
3942
3943        // Pad UDP datagram if it contains a QUIC Initial packet.
3944        #[cfg(not(feature = "fuzzing"))]
3945        if has_initial && left > 0 && done < MIN_CLIENT_INITIAL_LEN {
3946            let pad_len = cmp::min(left, MIN_CLIENT_INITIAL_LEN - done);
3947
3948            // Fill padding area with null bytes, to avoid leaking information
3949            // in case the application reuses the packet buffer.
3950            out[done..done + pad_len].fill(0);
3951
3952            done += pad_len;
3953        }
3954
3955        let send_path = self.paths.get(send_pid)?;
3956
3957        let info = SendInfo {
3958            from: send_path.local_addr(),
3959            to: send_path.peer_addr(),
3960
3961            at: send_path.recovery.get_packet_send_time(now),
3962        };
3963
3964        Ok((done, info))
3965    }
3966
3967    fn send_single(
3968        &mut self, out: &mut [u8], send_pid: usize, has_initial: bool,
3969        now: Instant,
3970    ) -> Result<(Type, usize)> {
3971        if out.is_empty() {
3972            return Err(Error::BufferTooShort);
3973        }
3974
3975        if self.is_draining() {
3976            return Err(Error::Done);
3977        }
3978
3979        let is_closing = self.local_error.is_some();
3980
3981        let out_len = out.len();
3982
3983        let mut b = octets::OctetsMut::with_slice(out);
3984
3985        let pkt_type = self.write_pkt_type(send_pid)?;
3986
3987        let max_dgram_len = if !self.dgram_send_queue.is_empty() {
3988            self.dgram_max_writable_len()
3989        } else {
3990            None
3991        };
3992
3993        let epoch = pkt_type.to_epoch()?;
3994        let pkt_space = &mut self.pkt_num_spaces[epoch];
3995        let crypto_ctx = &mut self.crypto_ctx[epoch];
3996
3997        // Process lost frames. There might be several paths having lost frames.
3998        for (_, p) in self.paths.iter_mut() {
3999            for lost in p.recovery.get_lost_frames(epoch) {
4000                match lost {
4001                    frame::Frame::CryptoHeader { offset, length } => {
4002                        crypto_ctx.crypto_stream.send.retransmit(offset, length);
4003
4004                        self.stream_retrans_bytes += length as u64;
4005                        p.stream_retrans_bytes += length as u64;
4006
4007                        self.retrans_count += 1;
4008                        p.retrans_count += 1;
4009                    },
4010
4011                    frame::Frame::StreamHeader {
4012                        stream_id,
4013                        offset,
4014                        length,
4015                        fin,
4016                    } => {
4017                        let stream = match self.streams.get_mut(stream_id) {
4018                            Some(v) => v,
4019
4020                            None => continue,
4021                        };
4022
4023                        let was_flushable = stream.is_flushable();
4024
4025                        let empty_fin = length == 0 && fin;
4026
4027                        stream.send.retransmit(offset, length);
4028
4029                        // If the stream is now flushable push it to the
4030                        // flushable queue, but only if it wasn't already
4031                        // queued.
4032                        //
4033                        // Consider the stream flushable also when we are
4034                        // sending a zero-length frame that has the fin flag
4035                        // set.
4036                        if (stream.is_flushable() || empty_fin) && !was_flushable
4037                        {
4038                            let priority_key = Arc::clone(&stream.priority_key);
4039                            self.streams.insert_flushable(&priority_key);
4040                        }
4041
4042                        self.stream_retrans_bytes += length as u64;
4043                        p.stream_retrans_bytes += length as u64;
4044
4045                        self.retrans_count += 1;
4046                        p.retrans_count += 1;
4047                    },
4048
4049                    frame::Frame::ACK { .. } => {
4050                        pkt_space.ack_elicited = true;
4051                    },
4052
4053                    frame::Frame::ResetStream {
4054                        stream_id,
4055                        error_code,
4056                        final_size,
4057                    } =>
4058                        if self.streams.get(stream_id).is_some() {
4059                            self.streams
4060                                .insert_reset(stream_id, error_code, final_size);
4061                        },
4062
4063                    // Retransmit HANDSHAKE_DONE only if it hasn't been acked at
4064                    // least once already.
4065                    frame::Frame::HandshakeDone if !self.handshake_done_acked => {
4066                        self.handshake_done_sent = false;
4067                    },
4068
4069                    frame::Frame::MaxStreamData { stream_id, .. } => {
4070                        if self.streams.get(stream_id).is_some() {
4071                            self.streams.insert_almost_full(stream_id);
4072                        }
4073                    },
4074
4075                    frame::Frame::MaxData { .. } => {
4076                        self.almost_full = true;
4077                    },
4078
4079                    frame::Frame::NewConnectionId { seq_num, .. } => {
4080                        self.ids.mark_advertise_new_scid_seq(seq_num, true);
4081                    },
4082
4083                    frame::Frame::RetireConnectionId { seq_num } => {
4084                        self.ids.mark_retire_dcid_seq(seq_num, true)?;
4085                    },
4086
4087                    frame::Frame::Ping {
4088                        mtu_probe: Some(failed_probe),
4089                    } =>
4090                        if let Some(pmtud) = p.pmtud.as_mut() {
4091                            trace!("pmtud probe dropped: {failed_probe}");
4092                            pmtud.failed_probe(failed_probe);
4093                        },
4094
4095                    _ => (),
4096                }
4097            }
4098        }
4099
4100        let is_app_limited = self.delivery_rate_check_if_app_limited();
4101        let n_paths = self.paths.len();
4102        let path = self.paths.get_mut(send_pid)?;
4103        let flow_control = &mut self.flow_control;
4104        let pkt_space = &mut self.pkt_num_spaces[epoch];
4105        let crypto_ctx = &mut self.crypto_ctx[epoch];
4106        let pkt_num_manager = &mut self.pkt_num_manager;
4107
4108        let mut left = if let Some(pmtud) = path.pmtud.as_mut() {
4109            // Limit output buffer size by estimated path MTU.
4110            cmp::min(pmtud.get_current_mtu(), b.cap())
4111        } else {
4112            b.cap()
4113        };
4114
4115        if pkt_num_manager.should_skip_pn(self.handshake_completed) {
4116            pkt_num_manager.set_skip_pn(Some(self.next_pkt_num));
4117            self.next_pkt_num += 1;
4118        };
4119        let pn = self.next_pkt_num;
4120
4121        let largest_acked_pkt =
4122            path.recovery.get_largest_acked_on_epoch(epoch).unwrap_or(0);
4123        let pn_len = packet::pkt_num_len(pn, largest_acked_pkt);
4124
4125        // The AEAD overhead at the current encryption level.
4126        let crypto_overhead = crypto_ctx.crypto_overhead().ok_or(Error::Done)?;
4127
4128        let dcid_seq = path.active_dcid_seq.ok_or(Error::OutOfIdentifiers)?;
4129
4130        let dcid =
4131            ConnectionId::from_ref(self.ids.get_dcid(dcid_seq)?.cid.as_ref());
4132
4133        let scid = if let Some(scid_seq) = path.active_scid_seq {
4134            ConnectionId::from_ref(self.ids.get_scid(scid_seq)?.cid.as_ref())
4135        } else if pkt_type == Type::Short {
4136            ConnectionId::default()
4137        } else {
4138            return Err(Error::InvalidState);
4139        };
4140
4141        let hdr = Header {
4142            ty: pkt_type,
4143
4144            version: self.version,
4145
4146            dcid,
4147            scid,
4148
4149            pkt_num: 0,
4150            pkt_num_len: pn_len,
4151
4152            // Only clone token for Initial packets, as other packets don't have
4153            // this field (Retry doesn't count, as it's not encoded as part of
4154            // this code path).
4155            token: if pkt_type == Type::Initial {
4156                self.token.clone()
4157            } else {
4158                None
4159            },
4160
4161            versions: None,
4162            key_phase: self.key_phase,
4163        };
4164
4165        hdr.to_bytes(&mut b)?;
4166
4167        let hdr_trace = if log::max_level() == log::LevelFilter::Trace {
4168            Some(format!("{hdr:?}"))
4169        } else {
4170            None
4171        };
4172
4173        let hdr_ty = hdr.ty;
4174
4175        #[cfg(feature = "qlog")]
4176        let qlog_pkt_hdr = self.qlog.streamer.as_ref().map(|_q| {
4177            qlog::events::quic::PacketHeader::with_type(
4178                hdr.ty.to_qlog(),
4179                Some(pn),
4180                Some(hdr.version),
4181                Some(&hdr.scid),
4182                Some(&hdr.dcid),
4183            )
4184        });
4185
4186        // Calculate the space required for the packet, including the header
4187        // the payload length, the packet number and the AEAD overhead.
4188        let mut overhead = b.off() + pn_len + crypto_overhead;
4189
4190        // We assume that the payload length, which is only present in long
4191        // header packets, can always be encoded with a 2-byte varint.
4192        if pkt_type != Type::Short {
4193            overhead += PAYLOAD_LENGTH_LEN;
4194        }
4195
4196        // Make sure we have enough space left for the packet overhead.
4197        match left.checked_sub(overhead) {
4198            Some(v) => left = v,
4199
4200            None => {
4201                // We can't send more because there isn't enough space available
4202                // in the output buffer.
4203                //
4204                // This usually happens when we try to send a new packet but
4205                // failed because cwnd is almost full. In such case app_limited
4206                // is set to false here to make cwnd grow when ACK is received.
4207                path.recovery.update_app_limited(false);
4208                return Err(Error::Done);
4209            },
4210        }
4211
4212        // Make sure there is enough space for the minimum payload length.
4213        if left < PAYLOAD_MIN_LEN {
4214            path.recovery.update_app_limited(false);
4215            return Err(Error::Done);
4216        }
4217
4218        let mut frames: SmallVec<[frame::Frame; 1]> = SmallVec::new();
4219
4220        let mut ack_eliciting = false;
4221        let mut in_flight = false;
4222        let mut is_pmtud_probe = false;
4223        let mut has_data = false;
4224
4225        // Whether or not we should explicitly elicit an ACK via PING frame if we
4226        // implicitly elicit one otherwise.
4227        let ack_elicit_required = path.recovery.should_elicit_ack(epoch);
4228
4229        let header_offset = b.off();
4230
4231        // Reserve space for payload length in advance. Since we don't yet know
4232        // what the final length will be, we reserve 2 bytes in all cases.
4233        //
4234        // Only long header packets have an explicit length field.
4235        if pkt_type != Type::Short {
4236            b.skip(PAYLOAD_LENGTH_LEN)?;
4237        }
4238
4239        packet::encode_pkt_num(pn, pn_len, &mut b)?;
4240
4241        let payload_offset = b.off();
4242
4243        let cwnd_available =
4244            path.recovery.cwnd_available().saturating_sub(overhead);
4245
4246        let left_before_packing_ack_frame = left;
4247
4248        // Create ACK frame.
4249        //
4250        // When we need to explicitly elicit an ACK via PING later, go ahead and
4251        // generate an ACK (if there's anything to ACK) since we're going to
4252        // send a packet with PING anyways, even if we haven't received anything
4253        // ACK eliciting.
4254        if pkt_space.recv_pkt_need_ack.len() > 0 &&
4255            (pkt_space.ack_elicited || ack_elicit_required) &&
4256            (!is_closing ||
4257                (pkt_type == Type::Handshake &&
4258                    self.local_error
4259                        .as_ref()
4260                        .is_some_and(|le| le.is_app))) &&
4261            path.active()
4262        {
4263            let ack_delay = pkt_space.largest_rx_pkt_time.elapsed();
4264
4265            let ack_delay = ack_delay.as_micros() as u64 /
4266                2_u64
4267                    .pow(self.local_transport_params.ack_delay_exponent as u32);
4268
4269            let frame = frame::Frame::ACK {
4270                ack_delay,
4271                ranges: pkt_space.recv_pkt_need_ack.clone(),
4272                ecn_counts: None, // sending ECN is not supported at this time
4273            };
4274
4275            // When a PING frame needs to be sent, avoid sending the ACK if
4276            // there is not enough cwnd available for both (note that PING
4277            // frames are always 1 byte, so we just need to check that the
4278            // ACK's length is lower than cwnd).
4279            if pkt_space.ack_elicited || frame.wire_len() < cwnd_available {
4280                // ACK-only packets are not congestion controlled so ACKs must
4281                // be bundled considering the buffer capacity only, and not the
4282                // available cwnd.
4283                if push_frame_to_pkt!(b, frames, frame, left) {
4284                    pkt_space.ack_elicited = false;
4285                }
4286            }
4287        }
4288
4289        // Limit output packet size by congestion window size.
4290        left = cmp::min(
4291            left,
4292            // Bytes consumed by ACK frames.
4293            cwnd_available.saturating_sub(left_before_packing_ack_frame - left),
4294        );
4295
4296        let mut challenge_data = None;
4297
4298        let active_path = self.paths.get_active_mut()?;
4299
4300        if pkt_type == Type::Short {
4301            // Create PMTUD probe.
4302            //
4303            // In order to send a PMTUD probe the current `left` value, which was
4304            // already limited by the current PMTU measure, needs to be ignored,
4305            // but the outgoing packet still needs to be limited by
4306            // the output buffer size, as well as the congestion
4307            // window.
4308            //
4309            // In addition, the PMTUD probe is only generated when the handshake
4310            // is confirmed, to avoid interfering with the handshake
4311            // (e.g. due to the anti-amplification limits).
4312            let should_probe_pmtu = active_path.should_send_pmtu_probe(
4313                self.handshake_confirmed,
4314                self.handshake_completed,
4315                out_len,
4316                is_closing,
4317                frames.is_empty(),
4318            );
4319
4320            if should_probe_pmtu {
4321                if let Some(pmtud) = active_path.pmtud.as_mut() {
4322                    let probe_size = pmtud.get_probe_size();
4323                    trace!(
4324                        "{} sending pmtud probe pmtu_probe={} estimated_pmtu={}",
4325                        self.trace_id,
4326                        probe_size,
4327                        pmtud.get_current_mtu(),
4328                    );
4329
4330                    left = probe_size;
4331
4332                    match left.checked_sub(overhead) {
4333                        Some(v) => left = v,
4334
4335                        None => {
4336                            // We can't send more because there isn't enough space
4337                            // available in the output buffer.
4338                            //
4339                            // This usually happens when we try to send a new
4340                            // packet but failed
4341                            // because cwnd is almost full.
4342                            //
4343                            // In such case app_limited is set to false here to
4344                            // make cwnd grow when ACK
4345                            // is received.
4346                            active_path.recovery.update_app_limited(false);
4347                            return Err(Error::Done);
4348                        },
4349                    }
4350
4351                    let frame = frame::Frame::Padding {
4352                        len: probe_size - overhead - 1,
4353                    };
4354
4355                    if push_frame_to_pkt!(b, frames, frame, left) {
4356                        let frame = frame::Frame::Ping {
4357                            mtu_probe: Some(probe_size),
4358                        };
4359
4360                        if push_frame_to_pkt!(b, frames, frame, left) {
4361                            ack_eliciting = true;
4362                            in_flight = true;
4363                        }
4364                    }
4365
4366                    // Reset probe flag after sending to prevent duplicate probes
4367                    // in a single flight.
4368                    pmtud.set_in_flight(true);
4369                    is_pmtud_probe = true;
4370                }
4371            }
4372
4373            let path = self.paths.get_mut(send_pid)?;
4374            // Create PATH_RESPONSE frame if needed.
4375            // We do not try to ensure that these are really sent.
4376            while let Some(challenge) = path.pop_received_challenge() {
4377                let frame = frame::Frame::PathResponse { data: challenge };
4378
4379                if push_frame_to_pkt!(b, frames, frame, left) {
4380                    ack_eliciting = true;
4381                    in_flight = true;
4382                } else {
4383                    // If there are other pending PATH_RESPONSE, don't lose them
4384                    // now.
4385                    break;
4386                }
4387            }
4388
4389            // Create PATH_CHALLENGE frame if needed.
4390            if path.validation_requested() {
4391                // TODO: ensure that data is unique over paths.
4392                let data = rand::rand_u64().to_be_bytes();
4393
4394                let frame = frame::Frame::PathChallenge { data };
4395
4396                if push_frame_to_pkt!(b, frames, frame, left) {
4397                    // Let's notify the path once we know the packet size.
4398                    challenge_data = Some(data);
4399
4400                    ack_eliciting = true;
4401                    in_flight = true;
4402                }
4403            }
4404
4405            if let Some(key_update) = crypto_ctx.key_update.as_mut() {
4406                key_update.update_acked = true;
4407            }
4408        }
4409
4410        let path = self.paths.get_mut(send_pid)?;
4411
4412        if pkt_type == Type::Short && !is_closing {
4413            // Create NEW_CONNECTION_ID frames as needed.
4414            while let Some(seq_num) = self.ids.next_advertise_new_scid_seq() {
4415                let frame = self.ids.get_new_connection_id_frame_for(seq_num)?;
4416
4417                if push_frame_to_pkt!(b, frames, frame, left) {
4418                    self.ids.mark_advertise_new_scid_seq(seq_num, false);
4419
4420                    ack_eliciting = true;
4421                    in_flight = true;
4422                } else {
4423                    break;
4424                }
4425            }
4426        }
4427
4428        if pkt_type == Type::Short && !is_closing && path.active() {
4429            // Create HANDSHAKE_DONE frame.
4430            // self.should_send_handshake_done() but without the need to borrow
4431            if self.handshake_completed &&
4432                !self.handshake_done_sent &&
4433                self.is_server
4434            {
4435                let frame = frame::Frame::HandshakeDone;
4436
4437                if push_frame_to_pkt!(b, frames, frame, left) {
4438                    self.handshake_done_sent = true;
4439
4440                    ack_eliciting = true;
4441                    in_flight = true;
4442                }
4443            }
4444
4445            // Create MAX_STREAMS_BIDI frame.
4446            if self.streams.should_update_max_streams_bidi() {
4447                let frame = frame::Frame::MaxStreamsBidi {
4448                    max: self.streams.max_streams_bidi_next(),
4449                };
4450
4451                if push_frame_to_pkt!(b, frames, frame, left) {
4452                    self.streams.update_max_streams_bidi();
4453
4454                    ack_eliciting = true;
4455                    in_flight = true;
4456                }
4457            }
4458
4459            // Create MAX_STREAMS_UNI frame.
4460            if self.streams.should_update_max_streams_uni() {
4461                let frame = frame::Frame::MaxStreamsUni {
4462                    max: self.streams.max_streams_uni_next(),
4463                };
4464
4465                if push_frame_to_pkt!(b, frames, frame, left) {
4466                    self.streams.update_max_streams_uni();
4467
4468                    ack_eliciting = true;
4469                    in_flight = true;
4470                }
4471            }
4472
4473            // Create DATA_BLOCKED frame.
4474            if let Some(limit) = self.blocked_limit {
4475                let frame = frame::Frame::DataBlocked { limit };
4476
4477                if push_frame_to_pkt!(b, frames, frame, left) {
4478                    self.blocked_limit = None;
4479
4480                    ack_eliciting = true;
4481                    in_flight = true;
4482                }
4483            }
4484
4485            // Create MAX_STREAM_DATA frames as needed.
4486            for stream_id in self.streams.almost_full() {
4487                let stream = match self.streams.get_mut(stream_id) {
4488                    Some(v) => v,
4489
4490                    None => {
4491                        // The stream doesn't exist anymore, so remove it from
4492                        // the almost full set.
4493                        self.streams.remove_almost_full(stream_id);
4494                        continue;
4495                    },
4496                };
4497
4498                // Autotune the stream window size.
4499                stream.recv.autotune_window(now, path.recovery.rtt());
4500
4501                let frame = frame::Frame::MaxStreamData {
4502                    stream_id,
4503                    max: stream.recv.max_data_next(),
4504                };
4505
4506                if push_frame_to_pkt!(b, frames, frame, left) {
4507                    let recv_win = stream.recv.window();
4508
4509                    stream.recv.update_max_data(now);
4510
4511                    self.streams.remove_almost_full(stream_id);
4512
4513                    ack_eliciting = true;
4514                    in_flight = true;
4515
4516                    // Make sure the connection window always has some
4517                    // room compared to the stream window.
4518                    flow_control.ensure_window_lower_bound(
4519                        (recv_win as f64 * CONNECTION_WINDOW_FACTOR) as u64,
4520                    );
4521
4522                    // Also send MAX_DATA when MAX_STREAM_DATA is sent, to avoid a
4523                    // potential race condition.
4524                    self.almost_full = true;
4525                }
4526            }
4527
4528            // Create MAX_DATA frame as needed.
4529            if self.almost_full &&
4530                flow_control.max_data() < flow_control.max_data_next()
4531            {
4532                // Autotune the connection window size.
4533                flow_control.autotune_window(now, path.recovery.rtt());
4534
4535                let frame = frame::Frame::MaxData {
4536                    max: flow_control.max_data_next(),
4537                };
4538
4539                if push_frame_to_pkt!(b, frames, frame, left) {
4540                    self.almost_full = false;
4541
4542                    // Commits the new max_rx_data limit.
4543                    flow_control.update_max_data(now);
4544
4545                    ack_eliciting = true;
4546                    in_flight = true;
4547                }
4548            }
4549
4550            // Create STOP_SENDING frames as needed.
4551            for (stream_id, error_code) in self
4552                .streams
4553                .stopped()
4554                .map(|(&k, &v)| (k, v))
4555                .collect::<Vec<(u64, u64)>>()
4556            {
4557                let frame = frame::Frame::StopSending {
4558                    stream_id,
4559                    error_code,
4560                };
4561
4562                if push_frame_to_pkt!(b, frames, frame, left) {
4563                    self.streams.remove_stopped(stream_id);
4564
4565                    ack_eliciting = true;
4566                    in_flight = true;
4567                }
4568            }
4569
4570            // Create RESET_STREAM frames as needed.
4571            for (stream_id, (error_code, final_size)) in self
4572                .streams
4573                .reset()
4574                .map(|(&k, &v)| (k, v))
4575                .collect::<Vec<(u64, (u64, u64))>>()
4576            {
4577                let frame = frame::Frame::ResetStream {
4578                    stream_id,
4579                    error_code,
4580                    final_size,
4581                };
4582
4583                if push_frame_to_pkt!(b, frames, frame, left) {
4584                    self.streams.remove_reset(stream_id);
4585
4586                    ack_eliciting = true;
4587                    in_flight = true;
4588                }
4589            }
4590
4591            // Create STREAM_DATA_BLOCKED frames as needed.
4592            for (stream_id, limit) in self
4593                .streams
4594                .blocked()
4595                .map(|(&k, &v)| (k, v))
4596                .collect::<Vec<(u64, u64)>>()
4597            {
4598                let frame = frame::Frame::StreamDataBlocked { stream_id, limit };
4599
4600                if push_frame_to_pkt!(b, frames, frame, left) {
4601                    self.streams.remove_blocked(stream_id);
4602
4603                    ack_eliciting = true;
4604                    in_flight = true;
4605                }
4606            }
4607
4608            // Create RETIRE_CONNECTION_ID frames as needed.
4609            let retire_dcid_seqs = self.ids.retire_dcid_seqs();
4610
4611            for seq_num in retire_dcid_seqs {
4612                // The sequence number specified in a RETIRE_CONNECTION_ID frame
4613                // MUST NOT refer to the Destination Connection ID field of the
4614                // packet in which the frame is contained.
4615                let dcid_seq = path.active_dcid_seq.ok_or(Error::InvalidState)?;
4616
4617                if seq_num == dcid_seq {
4618                    continue;
4619                }
4620
4621                let frame = frame::Frame::RetireConnectionId { seq_num };
4622
4623                if push_frame_to_pkt!(b, frames, frame, left) {
4624                    self.ids.mark_retire_dcid_seq(seq_num, false)?;
4625
4626                    ack_eliciting = true;
4627                    in_flight = true;
4628                } else {
4629                    break;
4630                }
4631            }
4632        }
4633
4634        // Create CONNECTION_CLOSE frame. Try to send this only on the active
4635        // path, unless it is the last one available.
4636        if path.active() || n_paths == 1 {
4637            if let Some(conn_err) = self.local_error.as_ref() {
4638                if conn_err.is_app {
4639                    // Create ApplicationClose frame.
4640                    if pkt_type == Type::Short {
4641                        let frame = frame::Frame::ApplicationClose {
4642                            error_code: conn_err.error_code,
4643                            reason: conn_err.reason.clone(),
4644                        };
4645
4646                        if push_frame_to_pkt!(b, frames, frame, left) {
4647                            let pto = path.recovery.pto();
4648                            self.draining_timer = Some(now + (pto * 3));
4649
4650                            ack_eliciting = true;
4651                            in_flight = true;
4652                        }
4653                    }
4654                } else {
4655                    // Create ConnectionClose frame.
4656                    let frame = frame::Frame::ConnectionClose {
4657                        error_code: conn_err.error_code,
4658                        frame_type: 0,
4659                        reason: conn_err.reason.clone(),
4660                    };
4661
4662                    if push_frame_to_pkt!(b, frames, frame, left) {
4663                        let pto = path.recovery.pto();
4664                        self.draining_timer = Some(now + (pto * 3));
4665
4666                        ack_eliciting = true;
4667                        in_flight = true;
4668                    }
4669                }
4670            }
4671        }
4672
4673        // Create CRYPTO frame.
4674        if crypto_ctx.crypto_stream.is_flushable() &&
4675            left > frame::MAX_CRYPTO_OVERHEAD &&
4676            !is_closing &&
4677            path.active()
4678        {
4679            let crypto_off = crypto_ctx.crypto_stream.send.off_front();
4680
4681            // Encode the frame.
4682            //
4683            // Instead of creating a `frame::Frame` object, encode the frame
4684            // directly into the packet buffer.
4685            //
4686            // First we reserve some space in the output buffer for writing the
4687            // frame header (we assume the length field is always a 2-byte
4688            // varint as we don't know the value yet).
4689            //
4690            // Then we emit the data from the crypto stream's send buffer.
4691            //
4692            // Finally we go back and encode the frame header with the now
4693            // available information.
4694            let hdr_off = b.off();
4695            let hdr_len = 1 + // frame type
4696                octets::varint_len(crypto_off) + // offset
4697                2; // length, always encode as 2-byte varint
4698
4699            if let Some(max_len) = left.checked_sub(hdr_len) {
4700                let (mut crypto_hdr, mut crypto_payload) =
4701                    b.split_at(hdr_off + hdr_len)?;
4702
4703                // Write stream data into the packet buffer.
4704                let (len, _) = crypto_ctx
4705                    .crypto_stream
4706                    .send
4707                    .emit(&mut crypto_payload.as_mut()[..max_len])?;
4708
4709                // Encode the frame's header.
4710                //
4711                // Due to how `OctetsMut::split_at()` works, `crypto_hdr` starts
4712                // from the initial offset of `b` (rather than the current
4713                // offset), so it needs to be advanced to the
4714                // initial frame offset.
4715                crypto_hdr.skip(hdr_off)?;
4716
4717                frame::encode_crypto_header(
4718                    crypto_off,
4719                    len as u64,
4720                    &mut crypto_hdr,
4721                )?;
4722
4723                // Advance the packet buffer's offset.
4724                b.skip(hdr_len + len)?;
4725
4726                let frame = frame::Frame::CryptoHeader {
4727                    offset: crypto_off,
4728                    length: len,
4729                };
4730
4731                if push_frame_to_pkt!(b, frames, frame, left) {
4732                    ack_eliciting = true;
4733                    in_flight = true;
4734                    has_data = true;
4735                }
4736            }
4737        }
4738
4739        // The preference of data-bearing frame to include in a packet
4740        // is managed by `self.emit_dgram`. However, whether any frames
4741        // can be sent depends on the state of their buffers. In the case
4742        // where one type is preferred but its buffer is empty, fall back
4743        // to the other type in order not to waste this function call.
4744        let mut dgram_emitted = false;
4745        let dgrams_to_emit = max_dgram_len.is_some();
4746        let stream_to_emit = self.streams.has_flushable();
4747
4748        let mut do_dgram = self.emit_dgram && dgrams_to_emit;
4749        let do_stream = !self.emit_dgram && stream_to_emit;
4750
4751        if !do_stream && dgrams_to_emit {
4752            do_dgram = true;
4753        }
4754
4755        // Create DATAGRAM frame.
4756        if (pkt_type == Type::Short || pkt_type == Type::ZeroRTT) &&
4757            left > frame::MAX_DGRAM_OVERHEAD &&
4758            !is_closing &&
4759            path.active() &&
4760            do_dgram
4761        {
4762            if let Some(max_dgram_payload) = max_dgram_len {
4763                while let Some(len) = self.dgram_send_queue.peek_front_len() {
4764                    let hdr_off = b.off();
4765                    let hdr_len = 1 + // frame type
4766                        2; // length, always encode as 2-byte varint
4767
4768                    if (hdr_len + len) <= left {
4769                        // Front of the queue fits this packet, send it.
4770                        match self.dgram_send_queue.pop() {
4771                            Some(data) => {
4772                                // Encode the frame.
4773                                //
4774                                // Instead of creating a `frame::Frame` object,
4775                                // encode the frame directly into the packet
4776                                // buffer.
4777                                //
4778                                // First we reserve some space in the output
4779                                // buffer for writing the frame header (we
4780                                // assume the length field is always a 2-byte
4781                                // varint as we don't know the value yet).
4782                                //
4783                                // Then we emit the data from the DATAGRAM's
4784                                // buffer.
4785                                //
4786                                // Finally we go back and encode the frame
4787                                // header with the now available information.
4788                                let (mut dgram_hdr, mut dgram_payload) =
4789                                    b.split_at(hdr_off + hdr_len)?;
4790
4791                                dgram_payload.as_mut()[..len]
4792                                    .copy_from_slice(&data);
4793
4794                                // Encode the frame's header.
4795                                //
4796                                // Due to how `OctetsMut::split_at()` works,
4797                                // `dgram_hdr` starts from the initial offset
4798                                // of `b` (rather than the current offset), so
4799                                // it needs to be advanced to the initial frame
4800                                // offset.
4801                                dgram_hdr.skip(hdr_off)?;
4802
4803                                frame::encode_dgram_header(
4804                                    len as u64,
4805                                    &mut dgram_hdr,
4806                                )?;
4807
4808                                // Advance the packet buffer's offset.
4809                                b.skip(hdr_len + len)?;
4810
4811                                let frame =
4812                                    frame::Frame::DatagramHeader { length: len };
4813
4814                                if push_frame_to_pkt!(b, frames, frame, left) {
4815                                    ack_eliciting = true;
4816                                    in_flight = true;
4817                                    dgram_emitted = true;
4818                                    let _ =
4819                                        self.dgram_sent_count.saturating_add(1);
4820                                    let _ =
4821                                        path.dgram_sent_count.saturating_add(1);
4822                                }
4823                            },
4824
4825                            None => continue,
4826                        };
4827                    } else if len > max_dgram_payload {
4828                        // This dgram frame will never fit. Let's purge it.
4829                        self.dgram_send_queue.pop();
4830                    } else {
4831                        break;
4832                    }
4833                }
4834            }
4835        }
4836
4837        // Create a single STREAM frame for the first stream that is flushable.
4838        if (pkt_type == Type::Short || pkt_type == Type::ZeroRTT) &&
4839            left > frame::MAX_STREAM_OVERHEAD &&
4840            !is_closing &&
4841            path.active() &&
4842            !dgram_emitted
4843        {
4844            while let Some(priority_key) = self.streams.peek_flushable() {
4845                let stream_id = priority_key.id;
4846                let stream = match self.streams.get_mut(stream_id) {
4847                    // Avoid sending frames for streams that were already stopped.
4848                    //
4849                    // This might happen if stream data was buffered but not yet
4850                    // flushed on the wire when a STOP_SENDING frame is received.
4851                    Some(v) if !v.send.is_stopped() => v,
4852                    _ => {
4853                        self.streams.remove_flushable(&priority_key);
4854                        continue;
4855                    },
4856                };
4857
4858                let stream_off = stream.send.off_front();
4859
4860                // Encode the frame.
4861                //
4862                // Instead of creating a `frame::Frame` object, encode the frame
4863                // directly into the packet buffer.
4864                //
4865                // First we reserve some space in the output buffer for writing
4866                // the frame header (we assume the length field is always a
4867                // 2-byte varint as we don't know the value yet).
4868                //
4869                // Then we emit the data from the stream's send buffer.
4870                //
4871                // Finally we go back and encode the frame header with the now
4872                // available information.
4873                let hdr_off = b.off();
4874                let hdr_len = 1 + // frame type
4875                    octets::varint_len(stream_id) + // stream_id
4876                    octets::varint_len(stream_off) + // offset
4877                    2; // length, always encode as 2-byte varint
4878
4879                let max_len = match left.checked_sub(hdr_len) {
4880                    Some(v) => v,
4881                    None => {
4882                        let priority_key = Arc::clone(&stream.priority_key);
4883                        self.streams.remove_flushable(&priority_key);
4884
4885                        continue;
4886                    },
4887                };
4888
4889                let (mut stream_hdr, mut stream_payload) =
4890                    b.split_at(hdr_off + hdr_len)?;
4891
4892                // Write stream data into the packet buffer.
4893                let (len, fin) =
4894                    stream.send.emit(&mut stream_payload.as_mut()[..max_len])?;
4895
4896                // Encode the frame's header.
4897                //
4898                // Due to how `OctetsMut::split_at()` works, `stream_hdr` starts
4899                // from the initial offset of `b` (rather than the current
4900                // offset), so it needs to be advanced to the initial frame
4901                // offset.
4902                stream_hdr.skip(hdr_off)?;
4903
4904                frame::encode_stream_header(
4905                    stream_id,
4906                    stream_off,
4907                    len as u64,
4908                    fin,
4909                    &mut stream_hdr,
4910                )?;
4911
4912                // Advance the packet buffer's offset.
4913                b.skip(hdr_len + len)?;
4914
4915                let frame = frame::Frame::StreamHeader {
4916                    stream_id,
4917                    offset: stream_off,
4918                    length: len,
4919                    fin,
4920                };
4921
4922                if push_frame_to_pkt!(b, frames, frame, left) {
4923                    ack_eliciting = true;
4924                    in_flight = true;
4925                    has_data = true;
4926                }
4927
4928                let priority_key = Arc::clone(&stream.priority_key);
4929                // If the stream is no longer flushable, remove it from the queue
4930                if !stream.is_flushable() {
4931                    self.streams.remove_flushable(&priority_key);
4932                } else if stream.incremental {
4933                    // Shuffle the incremental stream to the back of the
4934                    // queue.
4935                    self.streams.remove_flushable(&priority_key);
4936                    self.streams.insert_flushable(&priority_key);
4937                }
4938
4939                #[cfg(feature = "fuzzing")]
4940                // Coalesce STREAM frames when fuzzing.
4941                if left > frame::MAX_STREAM_OVERHEAD {
4942                    continue;
4943                }
4944
4945                break;
4946            }
4947        }
4948
4949        // Alternate trying to send DATAGRAMs next time.
4950        self.emit_dgram = !dgram_emitted;
4951
4952        // If no other ack-eliciting frame is sent, include a PING frame
4953        // - if PTO probe needed; OR
4954        // - if we've sent too many non ack-eliciting packets without having
4955        // sent an ACK eliciting one; OR
4956        // - the application requested an ack-eliciting frame be sent.
4957        if (ack_elicit_required || path.needs_ack_eliciting) &&
4958            !ack_eliciting &&
4959            left >= 1 &&
4960            !is_closing
4961        {
4962            let frame = frame::Frame::Ping { mtu_probe: None };
4963
4964            if push_frame_to_pkt!(b, frames, frame, left) {
4965                ack_eliciting = true;
4966                in_flight = true;
4967            }
4968        }
4969
4970        if ack_eliciting && !is_pmtud_probe {
4971            path.needs_ack_eliciting = false;
4972            path.recovery.ping_sent(epoch);
4973        }
4974
4975        if !has_data &&
4976            !dgram_emitted &&
4977            cwnd_available > frame::MAX_STREAM_OVERHEAD
4978        {
4979            path.recovery.on_app_limited();
4980        }
4981
4982        if frames.is_empty() {
4983            // When we reach this point we are not able to write more, so set
4984            // app_limited to false.
4985            path.recovery.update_app_limited(false);
4986            return Err(Error::Done);
4987        }
4988
4989        // When coalescing a 1-RTT packet, we can't add padding in the UDP
4990        // datagram, so use PADDING frames instead.
4991        //
4992        // This is only needed if
4993        // 1) an Initial packet has already been written to the UDP datagram,
4994        // as Initial always requires padding.
4995        //
4996        // 2) this is a probing packet towards an unvalidated peer address.
4997        if (has_initial || !path.validated()) &&
4998            pkt_type == Type::Short &&
4999            left >= 1
5000        {
5001            let frame = frame::Frame::Padding { len: left };
5002
5003            if push_frame_to_pkt!(b, frames, frame, left) {
5004                in_flight = true;
5005            }
5006        }
5007
5008        // Pad payload so that it's always at least 4 bytes.
5009        if b.off() - payload_offset < PAYLOAD_MIN_LEN {
5010            let payload_len = b.off() - payload_offset;
5011
5012            let frame = frame::Frame::Padding {
5013                len: PAYLOAD_MIN_LEN - payload_len,
5014            };
5015
5016            #[allow(unused_assignments)]
5017            if push_frame_to_pkt!(b, frames, frame, left) {
5018                in_flight = true;
5019            }
5020        }
5021
5022        let payload_len = b.off() - payload_offset;
5023
5024        // Fill in payload length.
5025        if pkt_type != Type::Short {
5026            let len = pn_len + payload_len + crypto_overhead;
5027
5028            let (_, mut payload_with_len) = b.split_at(header_offset)?;
5029            payload_with_len
5030                .put_varint_with_len(len as u64, PAYLOAD_LENGTH_LEN)?;
5031        }
5032
5033        trace!(
5034            "{} tx pkt {} len={} pn={} {}",
5035            self.trace_id,
5036            hdr_trace.unwrap_or_default(),
5037            payload_len,
5038            pn,
5039            AddrTupleFmt(path.local_addr(), path.peer_addr())
5040        );
5041
5042        #[cfg(feature = "qlog")]
5043        let mut qlog_frames: SmallVec<
5044            [qlog::events::quic::QuicFrame; 1],
5045        > = SmallVec::with_capacity(frames.len());
5046
5047        for frame in &mut frames {
5048            trace!("{} tx frm {:?}", self.trace_id, frame);
5049
5050            qlog_with_type!(QLOG_PACKET_TX, self.qlog, _q, {
5051                qlog_frames.push(frame.to_qlog());
5052            });
5053        }
5054
5055        qlog_with_type!(QLOG_PACKET_TX, self.qlog, q, {
5056            if let Some(header) = qlog_pkt_hdr {
5057                // Qlog packet raw info described at
5058                // https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema-00#section-5.1
5059                //
5060                // `length` includes packet headers and trailers (AEAD tag).
5061                let length = payload_len + payload_offset + crypto_overhead;
5062                let qlog_raw_info = RawInfo {
5063                    length: Some(length as u64),
5064                    payload_length: Some(payload_len as u64),
5065                    data: None,
5066                };
5067
5068                let send_at_time =
5069                    now.duration_since(q.start_time()).as_secs_f32() * 1000.0;
5070
5071                let ev_data =
5072                    EventData::PacketSent(qlog::events::quic::PacketSent {
5073                        header,
5074                        frames: Some(qlog_frames),
5075                        raw: Some(qlog_raw_info),
5076                        send_at_time: Some(send_at_time),
5077                        ..Default::default()
5078                    });
5079
5080                q.add_event_data_with_instant(ev_data, now).ok();
5081            }
5082        });
5083
5084        let aead = match crypto_ctx.crypto_seal {
5085            Some(ref v) => v,
5086            None => return Err(Error::InvalidState),
5087        };
5088
5089        let written = packet::encrypt_pkt(
5090            &mut b,
5091            pn,
5092            pn_len,
5093            payload_len,
5094            payload_offset,
5095            None,
5096            aead,
5097        )?;
5098
5099        let sent_pkt_has_data = if path.recovery.gcongestion_enabled() {
5100            has_data || dgram_emitted
5101        } else {
5102            has_data
5103        };
5104
5105        let sent_pkt = recovery::Sent {
5106            pkt_num: pn,
5107            frames,
5108            time_sent: now,
5109            time_acked: None,
5110            time_lost: None,
5111            size: if ack_eliciting { written } else { 0 },
5112            ack_eliciting,
5113            in_flight,
5114            delivered: 0,
5115            delivered_time: now,
5116            first_sent_time: now,
5117            is_app_limited: false,
5118            tx_in_flight: 0,
5119            lost: 0,
5120            has_data: sent_pkt_has_data,
5121            is_pmtud_probe,
5122        };
5123
5124        if in_flight && is_app_limited {
5125            path.recovery.delivery_rate_update_app_limited(true);
5126        }
5127
5128        self.next_pkt_num += 1;
5129
5130        let handshake_status = recovery::HandshakeStatus {
5131            has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
5132                .has_keys(),
5133            peer_verified_address: self.peer_verified_initial_address,
5134            completed: self.handshake_completed,
5135        };
5136
5137        self.on_packet_sent(send_pid, sent_pkt, epoch, handshake_status, now)?;
5138
5139        let path = self.paths.get_mut(send_pid)?;
5140        qlog_with_type!(QLOG_METRICS, self.qlog, q, {
5141            path.recovery.maybe_qlog(q, now);
5142        });
5143
5144        // Record sent packet size if we probe the path.
5145        if let Some(data) = challenge_data {
5146            path.add_challenge_sent(data, written, now);
5147        }
5148
5149        self.sent_count += 1;
5150        self.sent_bytes += written as u64;
5151        path.sent_count += 1;
5152        path.sent_bytes += written as u64;
5153
5154        if self.dgram_send_queue.byte_size() > path.recovery.cwnd_available() {
5155            path.recovery.update_app_limited(false);
5156        }
5157
5158        path.max_send_bytes = path.max_send_bytes.saturating_sub(written);
5159
5160        // On the client, drop initial state after sending an Handshake packet.
5161        if !self.is_server && hdr_ty == Type::Handshake {
5162            self.drop_epoch_state(packet::Epoch::Initial, now);
5163        }
5164
5165        // (Re)start the idle timer if we are sending the first ack-eliciting
5166        // packet since last receiving a packet.
5167        if ack_eliciting && !self.ack_eliciting_sent {
5168            if let Some(idle_timeout) = self.idle_timeout() {
5169                self.idle_timer = Some(now + idle_timeout);
5170            }
5171        }
5172
5173        if ack_eliciting {
5174            self.ack_eliciting_sent = true;
5175        }
5176
5177        Ok((pkt_type, written))
5178    }
5179
5180    fn on_packet_sent(
5181        &mut self, send_pid: usize, sent_pkt: recovery::Sent,
5182        epoch: packet::Epoch, handshake_status: recovery::HandshakeStatus,
5183        now: Instant,
5184    ) -> Result<()> {
5185        let path = self.paths.get_mut(send_pid)?;
5186
5187        // It's fine to set the skip counter based on a non-active path's values.
5188        let cwnd = path.recovery.cwnd();
5189        let max_datagram_size = path.recovery.max_datagram_size();
5190        self.pkt_num_spaces[epoch].on_packet_sent(&sent_pkt);
5191        self.pkt_num_manager.on_packet_sent(
5192            cwnd,
5193            max_datagram_size,
5194            self.handshake_completed,
5195        );
5196
5197        path.recovery.on_packet_sent(
5198            sent_pkt,
5199            epoch,
5200            handshake_status,
5201            now,
5202            &self.trace_id,
5203        );
5204
5205        Ok(())
5206    }
5207
5208    /// Returns the desired send time for the next packet.
5209    #[inline]
5210    pub fn get_next_release_time(&self) -> Option<ReleaseDecision> {
5211        Some(
5212            self.paths
5213                .get_active()
5214                .ok()?
5215                .recovery
5216                .get_next_release_time(),
5217        )
5218    }
5219
5220    /// Returns whether gcongestion is enabled.
5221    #[inline]
5222    pub fn gcongestion_enabled(&self) -> Option<bool> {
5223        Some(self.paths.get_active().ok()?.recovery.gcongestion_enabled())
5224    }
5225
5226    /// Returns the maximum pacing into the future.
5227    ///
5228    /// Equals 1/8 of the smoothed RTT, but at least 1ms and not greater than
5229    /// 5ms.
5230    pub fn max_release_into_future(&self) -> Duration {
5231        self.paths
5232            .get_active()
5233            .map(|p| p.recovery.rtt().mul_f64(0.125))
5234            .unwrap_or(Duration::from_millis(1))
5235            .max(Duration::from_millis(1))
5236            .min(Duration::from_millis(5))
5237    }
5238
5239    /// Returns whether pacing is enabled.
5240    #[inline]
5241    pub fn pacing_enabled(&self) -> bool {
5242        self.recovery_config.pacing
5243    }
5244
5245    /// Returns the size of the send quantum, in bytes.
5246    ///
5247    /// This represents the maximum size of a packet burst as determined by the
5248    /// congestion control algorithm in use.
5249    ///
5250    /// Applications can, for example, use it in conjunction with segmentation
5251    /// offloading mechanisms as the maximum limit for outgoing aggregates of
5252    /// multiple packets.
5253    #[inline]
5254    pub fn send_quantum(&self) -> usize {
5255        match self.paths.get_active() {
5256            Ok(p) => p.recovery.send_quantum(),
5257            _ => 0,
5258        }
5259    }
5260
5261    /// Returns the size of the send quantum over the given 4-tuple, in bytes.
5262    ///
5263    /// This represents the maximum size of a packet burst as determined by the
5264    /// congestion control algorithm in use.
5265    ///
5266    /// Applications can, for example, use it in conjunction with segmentation
5267    /// offloading mechanisms as the maximum limit for outgoing aggregates of
5268    /// multiple packets.
5269    ///
5270    /// If the (`local_addr`, peer_addr`) 4-tuple relates to a non-existing
5271    /// path, this method returns 0.
5272    pub fn send_quantum_on_path(
5273        &self, local_addr: SocketAddr, peer_addr: SocketAddr,
5274    ) -> usize {
5275        self.paths
5276            .path_id_from_addrs(&(local_addr, peer_addr))
5277            .and_then(|pid| self.paths.get(pid).ok())
5278            .map(|path| path.recovery.send_quantum())
5279            .unwrap_or(0)
5280    }
5281
5282    /// Reads contiguous data from a stream into the provided slice.
5283    ///
5284    /// The slice must be sized by the caller and will be populated up to its
5285    /// capacity.
5286    ///
5287    /// On success the amount of bytes read and a flag indicating the fin state
5288    /// is returned as a tuple, or [`Done`] if there is no data to read.
5289    ///
5290    /// Reading data from a stream may trigger queueing of control messages
5291    /// (e.g. MAX_STREAM_DATA). [`send()`] should be called after reading.
5292    ///
5293    /// [`Done`]: enum.Error.html#variant.Done
5294    /// [`send()`]: struct.Connection.html#method.send
5295    ///
5296    /// ## Examples:
5297    ///
5298    /// ```no_run
5299    /// # let mut buf = [0; 512];
5300    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5301    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5302    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5303    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5304    /// # let local = socket.local_addr().unwrap();
5305    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5306    /// # let stream_id = 0;
5307    /// while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
5308    ///     println!("Got {} bytes on stream {}", read, stream_id);
5309    /// }
5310    /// # Ok::<(), quiche::Error>(())
5311    /// ```
5312    pub fn stream_recv(
5313        &mut self, stream_id: u64, out: &mut [u8],
5314    ) -> Result<(usize, bool)> {
5315        // We can't read on our own unidirectional streams.
5316        if !stream::is_bidi(stream_id) &&
5317            stream::is_local(stream_id, self.is_server)
5318        {
5319            return Err(Error::InvalidStreamState(stream_id));
5320        }
5321
5322        let stream = self
5323            .streams
5324            .get_mut(stream_id)
5325            .ok_or(Error::InvalidStreamState(stream_id))?;
5326
5327        if !stream.is_readable() {
5328            return Err(Error::Done);
5329        }
5330
5331        let local = stream.local;
5332        let priority_key = Arc::clone(&stream.priority_key);
5333
5334        #[cfg(feature = "qlog")]
5335        let offset = stream.recv.off_front();
5336
5337        let (read, fin) = match stream.recv.emit(out) {
5338            Ok(v) => v,
5339
5340            Err(e) => {
5341                // Collect the stream if it is now complete. This can happen if
5342                // we got a `StreamReset` error which will now be propagated to
5343                // the application, so we don't need to keep the stream's state
5344                // anymore.
5345                if stream.is_complete() {
5346                    self.streams.collect(stream_id, local);
5347                }
5348
5349                self.streams.remove_readable(&priority_key);
5350                return Err(e);
5351            },
5352        };
5353
5354        self.flow_control.add_consumed(read as u64);
5355
5356        let readable = stream.is_readable();
5357
5358        let complete = stream.is_complete();
5359
5360        if stream.recv.almost_full() {
5361            self.streams.insert_almost_full(stream_id);
5362        }
5363
5364        if !readable {
5365            self.streams.remove_readable(&priority_key);
5366        }
5367
5368        if complete {
5369            self.streams.collect(stream_id, local);
5370        }
5371
5372        qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
5373            let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
5374                stream_id: Some(stream_id),
5375                offset: Some(offset),
5376                length: Some(read as u64),
5377                from: Some(DataRecipient::Transport),
5378                to: Some(DataRecipient::Application),
5379                ..Default::default()
5380            });
5381
5382            let now = Instant::now();
5383            q.add_event_data_with_instant(ev_data, now).ok();
5384        });
5385
5386        if self.should_update_max_data() {
5387            self.almost_full = true;
5388        }
5389
5390        if priority_key.incremental && readable {
5391            // Shuffle the incremental stream to the back of the queue.
5392            self.streams.remove_readable(&priority_key);
5393            self.streams.insert_readable(&priority_key);
5394        }
5395
5396        Ok((read, fin))
5397    }
5398
5399    /// Writes data to a stream.
5400    ///
5401    /// On success the number of bytes written is returned, or [`Done`] if no
5402    /// data was written (e.g. because the stream has no capacity).
5403    ///
5404    /// Applications can provide a 0-length buffer with the fin flag set to
5405    /// true. This will lead to a 0-length FIN STREAM frame being sent at the
5406    /// latest offset. The `Ok(0)` value is only returned when the application
5407    /// provided a 0-length buffer.
5408    ///
5409    /// In addition, if the peer has signalled that it doesn't want to receive
5410    /// any more data from this stream by sending the `STOP_SENDING` frame, the
5411    /// [`StreamStopped`] error will be returned instead of any data.
5412    ///
5413    /// Note that in order to avoid buffering an infinite amount of data in the
5414    /// stream's send buffer, streams are only allowed to buffer outgoing data
5415    /// up to the amount that the peer allows it to send (that is, up to the
5416    /// stream's outgoing flow control capacity).
5417    ///
5418    /// This means that the number of written bytes returned can be lower than
5419    /// the length of the input buffer when the stream doesn't have enough
5420    /// capacity for the operation to complete. The application should retry the
5421    /// operation once the stream is reported as writable again.
5422    ///
5423    /// Applications should call this method only after the handshake is
5424    /// completed (whenever [`is_established()`] returns `true`) or during
5425    /// early data if enabled (whenever [`is_in_early_data()`] returns `true`).
5426    ///
5427    /// [`Done`]: enum.Error.html#variant.Done
5428    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
5429    /// [`is_established()`]: struct.Connection.html#method.is_established
5430    /// [`is_in_early_data()`]: struct.Connection.html#method.is_in_early_data
5431    ///
5432    /// ## Examples:
5433    ///
5434    /// ```no_run
5435    /// # let mut buf = [0; 512];
5436    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5437    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5438    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5439    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5440    /// # let local = "127.0.0.1:4321".parse().unwrap();
5441    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5442    /// # let stream_id = 0;
5443    /// conn.stream_send(stream_id, b"hello", true)?;
5444    /// # Ok::<(), quiche::Error>(())
5445    /// ```
5446    pub fn stream_send(
5447        &mut self, stream_id: u64, buf: &[u8], fin: bool,
5448    ) -> Result<usize> {
5449        self.stream_do_send(
5450            stream_id,
5451            buf,
5452            fin,
5453            |stream: &mut stream::Stream<F>,
5454             buf: &[u8],
5455             cap: usize,
5456             fin: bool| {
5457                stream.send.write(&buf[..cap], fin).map(|v| (v, v))
5458            },
5459        )
5460    }
5461
5462    /// Writes data to a stream with zero copying, instead, it appends the
5463    /// provided buffer directly to the send queue if the capacity allows
5464    /// it.
5465    ///
5466    /// When a partial write happens (including when [`Error::Done`] is
5467    /// returned) the remaining (unwritten) buffer will also be returned.
5468    /// The application should retry the operation once the stream is
5469    /// reported as writable again.
5470    pub fn stream_send_zc(
5471        &mut self, stream_id: u64, buf: F::Buf, len: Option<usize>, fin: bool,
5472    ) -> Result<(usize, Option<F::Buf>)>
5473    where
5474        F::Buf: BufSplit,
5475    {
5476        self.stream_do_send(
5477            stream_id,
5478            buf,
5479            fin,
5480            |stream: &mut stream::Stream<F>,
5481             buf: F::Buf,
5482             cap: usize,
5483             fin: bool| {
5484                let len = len.unwrap_or(usize::MAX).min(cap);
5485                let (sent, remaining) = stream.send.append_buf(buf, len, fin)?;
5486                Ok((sent, (sent, remaining)))
5487            },
5488        )
5489    }
5490
5491    fn stream_do_send<B, R, SND>(
5492        &mut self, stream_id: u64, buf: B, fin: bool, write_fn: SND,
5493    ) -> Result<R>
5494    where
5495        B: AsRef<[u8]>,
5496        SND: FnOnce(&mut stream::Stream<F>, B, usize, bool) -> Result<(usize, R)>,
5497    {
5498        // We can't write on the peer's unidirectional streams.
5499        if !stream::is_bidi(stream_id) &&
5500            !stream::is_local(stream_id, self.is_server)
5501        {
5502            return Err(Error::InvalidStreamState(stream_id));
5503        }
5504
5505        let len = buf.as_ref().len();
5506
5507        // Mark the connection as blocked if the connection-level flow control
5508        // limit doesn't let us buffer all the data.
5509        //
5510        // Note that this is separate from "send capacity" as that also takes
5511        // congestion control into consideration.
5512        if self.max_tx_data - self.tx_data < len as u64 {
5513            self.blocked_limit = Some(self.max_tx_data);
5514        }
5515
5516        let cap = self.tx_cap;
5517
5518        // Get existing stream or create a new one.
5519        let stream = self.get_or_create_stream(stream_id, true)?;
5520
5521        #[cfg(feature = "qlog")]
5522        let offset = stream.send.off_back();
5523
5524        let was_writable = stream.is_writable();
5525
5526        let was_flushable = stream.is_flushable();
5527
5528        let priority_key = Arc::clone(&stream.priority_key);
5529
5530        // Truncate the input buffer based on the connection's send capacity if
5531        // necessary.
5532        //
5533        // When the cap is zero, the method returns Ok(0) *only* when the passed
5534        // buffer is empty. We return Error::Done otherwise.
5535        if cap == 0 && len > 0 {
5536            if was_writable {
5537                // When `stream_writable_next()` returns a stream, the writable
5538                // mark is removed, but because the stream is blocked by the
5539                // connection-level send capacity it won't be marked as writable
5540                // again once the capacity increases.
5541                //
5542                // Since the stream is writable already, mark it here instead.
5543                self.streams.insert_writable(&priority_key);
5544            }
5545
5546            return Err(Error::Done);
5547        }
5548
5549        let (cap, fin, blocked_by_cap) = if cap < len {
5550            (cap, false, true)
5551        } else {
5552            (len, fin, false)
5553        };
5554
5555        let (sent, ret) = match write_fn(stream, buf, cap, fin) {
5556            Ok(v) => v,
5557
5558            Err(e) => {
5559                self.streams.remove_writable(&priority_key);
5560                return Err(e);
5561            },
5562        };
5563
5564        let incremental = stream.incremental;
5565        let priority_key = Arc::clone(&stream.priority_key);
5566
5567        let flushable = stream.is_flushable();
5568
5569        let writable = stream.is_writable();
5570
5571        let empty_fin = len == 0 && fin;
5572
5573        if sent < cap {
5574            let max_off = stream.send.max_off();
5575
5576            if stream.send.blocked_at() != Some(max_off) {
5577                stream.send.update_blocked_at(Some(max_off));
5578                self.streams.insert_blocked(stream_id, max_off);
5579            }
5580        } else {
5581            stream.send.update_blocked_at(None);
5582            self.streams.remove_blocked(stream_id);
5583        }
5584
5585        // If the stream is now flushable push it to the flushable queue, but
5586        // only if it wasn't already queued.
5587        //
5588        // Consider the stream flushable also when we are sending a zero-length
5589        // frame that has the fin flag set.
5590        if (flushable || empty_fin) && !was_flushable {
5591            self.streams.insert_flushable(&priority_key);
5592        }
5593
5594        if !writable {
5595            self.streams.remove_writable(&priority_key);
5596        } else if was_writable && blocked_by_cap {
5597            // When `stream_writable_next()` returns a stream, the writable
5598            // mark is removed, but because the stream is blocked by the
5599            // connection-level send capacity it won't be marked as writable
5600            // again once the capacity increases.
5601            //
5602            // Since the stream is writable already, mark it here instead.
5603            self.streams.insert_writable(&priority_key);
5604        }
5605
5606        self.tx_cap -= sent;
5607
5608        self.tx_data += sent as u64;
5609
5610        self.tx_buffered += sent;
5611
5612        qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
5613            let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
5614                stream_id: Some(stream_id),
5615                offset: Some(offset),
5616                length: Some(sent as u64),
5617                from: Some(DataRecipient::Application),
5618                to: Some(DataRecipient::Transport),
5619                ..Default::default()
5620            });
5621
5622            let now = Instant::now();
5623            q.add_event_data_with_instant(ev_data, now).ok();
5624        });
5625
5626        if sent == 0 && cap > 0 {
5627            return Err(Error::Done);
5628        }
5629
5630        if incremental && writable {
5631            // Shuffle the incremental stream to the back of the queue.
5632            self.streams.remove_writable(&priority_key);
5633            self.streams.insert_writable(&priority_key);
5634        }
5635
5636        Ok(ret)
5637    }
5638
5639    /// Sets the priority for a stream.
5640    ///
5641    /// A stream's priority determines the order in which stream data is sent
5642    /// on the wire (streams with lower priority are sent first). Streams are
5643    /// created with a default priority of `127`.
5644    ///
5645    /// The target stream is created if it did not exist before calling this
5646    /// method.
5647    pub fn stream_priority(
5648        &mut self, stream_id: u64, urgency: u8, incremental: bool,
5649    ) -> Result<()> {
5650        // Get existing stream or create a new one, but if the stream
5651        // has already been closed and collected, ignore the prioritization.
5652        let stream = match self.get_or_create_stream(stream_id, true) {
5653            Ok(v) => v,
5654
5655            Err(Error::Done) => return Ok(()),
5656
5657            Err(e) => return Err(e),
5658        };
5659
5660        if stream.urgency == urgency && stream.incremental == incremental {
5661            return Ok(());
5662        }
5663
5664        stream.urgency = urgency;
5665        stream.incremental = incremental;
5666
5667        let new_priority_key = Arc::new(StreamPriorityKey {
5668            urgency: stream.urgency,
5669            incremental: stream.incremental,
5670            id: stream_id,
5671            ..Default::default()
5672        });
5673
5674        let old_priority_key =
5675            std::mem::replace(&mut stream.priority_key, new_priority_key.clone());
5676
5677        self.streams
5678            .update_priority(&old_priority_key, &new_priority_key);
5679
5680        Ok(())
5681    }
5682
5683    /// Shuts down reading or writing from/to the specified stream.
5684    ///
5685    /// When the `direction` argument is set to [`Shutdown::Read`], outstanding
5686    /// data in the stream's receive buffer is dropped, and no additional data
5687    /// is added to it. Data received after calling this method is still
5688    /// validated and acked but not stored, and [`stream_recv()`] will not
5689    /// return it to the application. In addition, a `STOP_SENDING` frame will
5690    /// be sent to the peer to signal it to stop sending data.
5691    ///
5692    /// When the `direction` argument is set to [`Shutdown::Write`], outstanding
5693    /// data in the stream's send buffer is dropped, and no additional data is
5694    /// added to it. Data passed to [`stream_send()`] after calling this method
5695    /// will be ignored. In addition, a `RESET_STREAM` frame will be sent to the
5696    /// peer to signal the reset.
5697    ///
5698    /// Locally-initiated unidirectional streams can only be closed in the
5699    /// [`Shutdown::Write`] direction. Remotely-initiated unidirectional streams
5700    /// can only be closed in the [`Shutdown::Read`] direction. Using an
5701    /// incorrect direction will return [`InvalidStreamState`].
5702    ///
5703    /// [`Shutdown::Read`]: enum.Shutdown.html#variant.Read
5704    /// [`Shutdown::Write`]: enum.Shutdown.html#variant.Write
5705    /// [`stream_recv()`]: struct.Connection.html#method.stream_recv
5706    /// [`stream_send()`]: struct.Connection.html#method.stream_send
5707    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
5708    pub fn stream_shutdown(
5709        &mut self, stream_id: u64, direction: Shutdown, err: u64,
5710    ) -> Result<()> {
5711        // Don't try to stop a local unidirectional stream.
5712        if direction == Shutdown::Read &&
5713            stream::is_local(stream_id, self.is_server) &&
5714            !stream::is_bidi(stream_id)
5715        {
5716            return Err(Error::InvalidStreamState(stream_id));
5717        }
5718
5719        // Don't try to reset a remote unidirectional stream.
5720        if direction == Shutdown::Write &&
5721            !stream::is_local(stream_id, self.is_server) &&
5722            !stream::is_bidi(stream_id)
5723        {
5724            return Err(Error::InvalidStreamState(stream_id));
5725        }
5726
5727        // Get existing stream.
5728        let stream = self.streams.get_mut(stream_id).ok_or(Error::Done)?;
5729
5730        let priority_key = Arc::clone(&stream.priority_key);
5731
5732        match direction {
5733            Shutdown::Read => {
5734                stream.recv.shutdown()?;
5735
5736                if !stream.recv.is_fin() {
5737                    self.streams.insert_stopped(stream_id, err);
5738                }
5739
5740                // Once shutdown, the stream is guaranteed to be non-readable.
5741                self.streams.remove_readable(&priority_key);
5742
5743                self.stopped_stream_local_count =
5744                    self.stopped_stream_local_count.saturating_add(1);
5745            },
5746
5747            Shutdown::Write => {
5748                let (final_size, unsent) = stream.send.shutdown()?;
5749
5750                // Claw back some flow control allowance from data that was
5751                // buffered but not actually sent before the stream was reset.
5752                self.tx_data = self.tx_data.saturating_sub(unsent);
5753
5754                self.tx_buffered =
5755                    self.tx_buffered.saturating_sub(unsent as usize);
5756
5757                // Update send capacity.
5758                self.update_tx_cap();
5759
5760                self.streams.insert_reset(stream_id, err, final_size);
5761
5762                // Once shutdown, the stream is guaranteed to be non-writable.
5763                self.streams.remove_writable(&priority_key);
5764
5765                self.reset_stream_local_count =
5766                    self.reset_stream_local_count.saturating_add(1);
5767            },
5768        }
5769
5770        Ok(())
5771    }
5772
5773    /// Returns the stream's send capacity in bytes.
5774    ///
5775    /// If the specified stream doesn't exist (including when it has already
5776    /// been completed and closed), the [`InvalidStreamState`] error will be
5777    /// returned.
5778    ///
5779    /// In addition, if the peer has signalled that it doesn't want to receive
5780    /// any more data from this stream by sending the `STOP_SENDING` frame, the
5781    /// [`StreamStopped`] error will be returned.
5782    ///
5783    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
5784    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
5785    #[inline]
5786    pub fn stream_capacity(&self, stream_id: u64) -> Result<usize> {
5787        if let Some(stream) = self.streams.get(stream_id) {
5788            let cap = cmp::min(self.tx_cap, stream.send.cap()?);
5789            return Ok(cap);
5790        };
5791
5792        Err(Error::InvalidStreamState(stream_id))
5793    }
5794
5795    /// Returns the next stream that has data to read.
5796    ///
5797    /// Note that once returned by this method, a stream ID will not be returned
5798    /// again until it is "re-armed".
5799    ///
5800    /// The application will need to read all of the pending data on the stream,
5801    /// and new data has to be received before the stream is reported again.
5802    ///
5803    /// This is unlike the [`readable()`] method, that returns the same list of
5804    /// readable streams when called multiple times in succession.
5805    ///
5806    /// [`readable()`]: struct.Connection.html#method.readable
5807    pub fn stream_readable_next(&mut self) -> Option<u64> {
5808        let priority_key = self.streams.readable.front().clone_pointer()?;
5809
5810        self.streams.remove_readable(&priority_key);
5811
5812        Some(priority_key.id)
5813    }
5814
5815    /// Returns true if the stream has data that can be read.
5816    pub fn stream_readable(&self, stream_id: u64) -> bool {
5817        let stream = match self.streams.get(stream_id) {
5818            Some(v) => v,
5819
5820            None => return false,
5821        };
5822
5823        stream.is_readable()
5824    }
5825
5826    /// Returns the next stream that can be written to.
5827    ///
5828    /// Note that once returned by this method, a stream ID will not be returned
5829    /// again until it is "re-armed".
5830    ///
5831    /// This is unlike the [`writable()`] method, that returns the same list of
5832    /// writable streams when called multiple times in succession. It is not
5833    /// advised to use both `stream_writable_next()` and [`writable()`] on the
5834    /// same connection, as it may lead to unexpected results.
5835    ///
5836    /// The [`stream_writable()`] method can also be used to fine-tune when a
5837    /// stream is reported as writable again.
5838    ///
5839    /// [`stream_writable()`]: struct.Connection.html#method.stream_writable
5840    /// [`writable()`]: struct.Connection.html#method.writable
5841    pub fn stream_writable_next(&mut self) -> Option<u64> {
5842        // If there is not enough connection-level send capacity, none of the
5843        // streams are writable.
5844        if self.tx_cap == 0 {
5845            return None;
5846        }
5847
5848        let mut cursor = self.streams.writable.front();
5849
5850        while let Some(priority_key) = cursor.clone_pointer() {
5851            if let Some(stream) = self.streams.get(priority_key.id) {
5852                let cap = match stream.send.cap() {
5853                    Ok(v) => v,
5854
5855                    // Return the stream to the application immediately if it's
5856                    // stopped.
5857                    Err(_) =>
5858                        return {
5859                            self.streams.remove_writable(&priority_key);
5860
5861                            Some(priority_key.id)
5862                        },
5863                };
5864
5865                if cmp::min(self.tx_cap, cap) >= stream.send_lowat {
5866                    self.streams.remove_writable(&priority_key);
5867                    return Some(priority_key.id);
5868                }
5869            }
5870
5871            cursor.move_next();
5872        }
5873
5874        None
5875    }
5876
5877    /// Returns true if the stream has enough send capacity.
5878    ///
5879    /// When `len` more bytes can be buffered into the given stream's send
5880    /// buffer, `true` will be returned, `false` otherwise.
5881    ///
5882    /// In the latter case, if the additional data can't be buffered due to
5883    /// flow control limits, the peer will also be notified, and a "low send
5884    /// watermark" will be set for the stream, such that it is not going to be
5885    /// reported as writable again by [`stream_writable_next()`] until its send
5886    /// capacity reaches `len`.
5887    ///
5888    /// If the specified stream doesn't exist (including when it has already
5889    /// been completed and closed), the [`InvalidStreamState`] error will be
5890    /// returned.
5891    ///
5892    /// In addition, if the peer has signalled that it doesn't want to receive
5893    /// any more data from this stream by sending the `STOP_SENDING` frame, the
5894    /// [`StreamStopped`] error will be returned.
5895    ///
5896    /// [`stream_writable_next()`]: struct.Connection.html#method.stream_writable_next
5897    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
5898    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
5899    #[inline]
5900    pub fn stream_writable(
5901        &mut self, stream_id: u64, len: usize,
5902    ) -> Result<bool> {
5903        if self.stream_capacity(stream_id)? >= len {
5904            return Ok(true);
5905        }
5906
5907        let stream = match self.streams.get_mut(stream_id) {
5908            Some(v) => v,
5909
5910            None => return Err(Error::InvalidStreamState(stream_id)),
5911        };
5912
5913        stream.send_lowat = cmp::max(1, len);
5914
5915        let is_writable = stream.is_writable();
5916
5917        let priority_key = Arc::clone(&stream.priority_key);
5918
5919        if self.max_tx_data - self.tx_data < len as u64 {
5920            self.blocked_limit = Some(self.max_tx_data);
5921        }
5922
5923        if stream.send.cap()? < len {
5924            let max_off = stream.send.max_off();
5925            if stream.send.blocked_at() != Some(max_off) {
5926                stream.send.update_blocked_at(Some(max_off));
5927                self.streams.insert_blocked(stream_id, max_off);
5928            }
5929        } else if is_writable {
5930            // When `stream_writable_next()` returns a stream, the writable
5931            // mark is removed, but because the stream is blocked by the
5932            // connection-level send capacity it won't be marked as writable
5933            // again once the capacity increases.
5934            //
5935            // Since the stream is writable already, mark it here instead.
5936            self.streams.insert_writable(&priority_key);
5937        }
5938
5939        Ok(false)
5940    }
5941
5942    /// Returns true if all the data has been read from the specified stream.
5943    ///
5944    /// This instructs the application that all the data received from the
5945    /// peer on the stream has been read, and there won't be anymore in the
5946    /// future.
5947    ///
5948    /// Basically this returns true when the peer either set the `fin` flag
5949    /// for the stream, or sent `RESET_STREAM`.
5950    #[inline]
5951    pub fn stream_finished(&self, stream_id: u64) -> bool {
5952        let stream = match self.streams.get(stream_id) {
5953            Some(v) => v,
5954
5955            None => return true,
5956        };
5957
5958        stream.recv.is_fin()
5959    }
5960
5961    /// Returns the number of bidirectional streams that can be created
5962    /// before the peer's stream count limit is reached.
5963    ///
5964    /// This can be useful to know if it's possible to create a bidirectional
5965    /// stream without trying it first.
5966    #[inline]
5967    pub fn peer_streams_left_bidi(&self) -> u64 {
5968        self.streams.peer_streams_left_bidi()
5969    }
5970
5971    /// Returns the number of unidirectional streams that can be created
5972    /// before the peer's stream count limit is reached.
5973    ///
5974    /// This can be useful to know if it's possible to create a unidirectional
5975    /// stream without trying it first.
5976    #[inline]
5977    pub fn peer_streams_left_uni(&self) -> u64 {
5978        self.streams.peer_streams_left_uni()
5979    }
5980
5981    /// Returns an iterator over streams that have outstanding data to read.
5982    ///
5983    /// Note that the iterator will only include streams that were readable at
5984    /// the time the iterator itself was created (i.e. when `readable()` was
5985    /// called). To account for newly readable streams, the iterator needs to
5986    /// be created again.
5987    ///
5988    /// ## Examples:
5989    ///
5990    /// ```no_run
5991    /// # let mut buf = [0; 512];
5992    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5993    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5994    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5995    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5996    /// # let local = socket.local_addr().unwrap();
5997    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5998    /// // Iterate over readable streams.
5999    /// for stream_id in conn.readable() {
6000    ///     // Stream is readable, read until there's no more data.
6001    ///     while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
6002    ///         println!("Got {} bytes on stream {}", read, stream_id);
6003    ///     }
6004    /// }
6005    /// # Ok::<(), quiche::Error>(())
6006    /// ```
6007    #[inline]
6008    pub fn readable(&self) -> StreamIter {
6009        self.streams.readable()
6010    }
6011
6012    /// Returns an iterator over streams that can be written in priority order.
6013    ///
6014    /// The priority order is based on RFC 9218 scheduling recommendations.
6015    /// Stream priority can be controlled using [`stream_priority()`]. In order
6016    /// to support fairness requirements, each time this method is called,
6017    /// internal state is updated. Therefore the iterator ordering can change
6018    /// between calls, even if no streams were added or removed.
6019    ///
6020    /// A "writable" stream is a stream that has enough flow control capacity to
6021    /// send data to the peer. To avoid buffering an infinite amount of data,
6022    /// streams are only allowed to buffer outgoing data up to the amount that
6023    /// the peer allows to send.
6024    ///
6025    /// Note that the iterator will only include streams that were writable at
6026    /// the time the iterator itself was created (i.e. when `writable()` was
6027    /// called). To account for newly writable streams, the iterator needs to be
6028    /// created again.
6029    ///
6030    /// ## Examples:
6031    ///
6032    /// ```no_run
6033    /// # let mut buf = [0; 512];
6034    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6035    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6036    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6037    /// # let local = socket.local_addr().unwrap();
6038    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6039    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6040    /// // Iterate over writable streams.
6041    /// for stream_id in conn.writable() {
6042    ///     // Stream is writable, write some data.
6043    ///     if let Ok(written) = conn.stream_send(stream_id, &buf, false) {
6044    ///         println!("Written {} bytes on stream {}", written, stream_id);
6045    ///     }
6046    /// }
6047    /// # Ok::<(), quiche::Error>(())
6048    /// ```
6049    /// [`stream_priority()`]: struct.Connection.html#method.stream_priority
6050    #[inline]
6051    pub fn writable(&self) -> StreamIter {
6052        // If there is not enough connection-level send capacity, none of the
6053        // streams are writable, so return an empty iterator.
6054        if self.tx_cap == 0 {
6055            return StreamIter::default();
6056        }
6057
6058        self.streams.writable()
6059    }
6060
6061    /// Returns the maximum possible size of egress UDP payloads.
6062    ///
6063    /// This is the maximum size of UDP payloads that can be sent, and depends
6064    /// on both the configured maximum send payload size of the local endpoint
6065    /// (as configured with [`set_max_send_udp_payload_size()`]), as well as
6066    /// the transport parameter advertised by the remote peer.
6067    ///
6068    /// Note that this value can change during the lifetime of the connection,
6069    /// but should remain stable across consecutive calls to [`send()`].
6070    ///
6071    /// [`set_max_send_udp_payload_size()`]:
6072    ///     struct.Config.html#method.set_max_send_udp_payload_size
6073    /// [`send()`]: struct.Connection.html#method.send
6074    pub fn max_send_udp_payload_size(&self) -> usize {
6075        let max_datagram_size = self
6076            .paths
6077            .get_active()
6078            .ok()
6079            .map(|p| p.recovery.max_datagram_size());
6080
6081        if let Some(max_datagram_size) = max_datagram_size {
6082            if self.is_established() {
6083                // We cap the maximum packet size to 16KB or so, so that it can be
6084                // always encoded with a 2-byte varint.
6085                return cmp::min(16383, max_datagram_size);
6086            }
6087        }
6088
6089        // Allow for 1200 bytes (minimum QUIC packet size) during the
6090        // handshake.
6091        MIN_CLIENT_INITIAL_LEN
6092    }
6093
6094    /// Schedule an ack-eliciting packet on the active path.
6095    ///
6096    /// QUIC packets might not contain ack-eliciting frames during normal
6097    /// operating conditions. If the packet would already contain
6098    /// ack-eliciting frames, this method does not change any behavior.
6099    /// However, if the packet would not ordinarily contain ack-eliciting
6100    /// frames, this method ensures that a PING frame sent.
6101    ///
6102    /// Calling this method multiple times before [`send()`] has no effect.
6103    ///
6104    /// [`send()`]: struct.Connection.html#method.send
6105    pub fn send_ack_eliciting(&mut self) -> Result<()> {
6106        if self.is_closed() || self.is_draining() {
6107            return Ok(());
6108        }
6109        self.paths.get_active_mut()?.needs_ack_eliciting = true;
6110        Ok(())
6111    }
6112
6113    /// Schedule an ack-eliciting packet on the specified path.
6114    ///
6115    /// See [`send_ack_eliciting()`] for more detail. [`InvalidState`] is
6116    /// returned if there is no record of the path.
6117    ///
6118    /// [`send_ack_eliciting()`]: struct.Connection.html#method.send_ack_eliciting
6119    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
6120    pub fn send_ack_eliciting_on_path(
6121        &mut self, local: SocketAddr, peer: SocketAddr,
6122    ) -> Result<()> {
6123        if self.is_closed() || self.is_draining() {
6124            return Ok(());
6125        }
6126        let path_id = self
6127            .paths
6128            .path_id_from_addrs(&(local, peer))
6129            .ok_or(Error::InvalidState)?;
6130        self.paths.get_mut(path_id)?.needs_ack_eliciting = true;
6131        Ok(())
6132    }
6133
6134    /// Reads the first received DATAGRAM.
6135    ///
6136    /// On success the DATAGRAM's data is returned along with its size.
6137    ///
6138    /// [`Done`] is returned if there is no data to read.
6139    ///
6140    /// [`BufferTooShort`] is returned if the provided buffer is too small for
6141    /// the DATAGRAM.
6142    ///
6143    /// [`Done`]: enum.Error.html#variant.Done
6144    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
6145    ///
6146    /// ## Examples:
6147    ///
6148    /// ```no_run
6149    /// # let mut buf = [0; 512];
6150    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6151    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6152    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6153    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6154    /// # let local = socket.local_addr().unwrap();
6155    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6156    /// let mut dgram_buf = [0; 512];
6157    /// while let Ok((len)) = conn.dgram_recv(&mut dgram_buf) {
6158    ///     println!("Got {} bytes of DATAGRAM", len);
6159    /// }
6160    /// # Ok::<(), quiche::Error>(())
6161    /// ```
6162    #[inline]
6163    pub fn dgram_recv(&mut self, buf: &mut [u8]) -> Result<usize> {
6164        match self.dgram_recv_queue.pop() {
6165            Some(d) => {
6166                if d.len() > buf.len() {
6167                    return Err(Error::BufferTooShort);
6168                }
6169
6170                buf[..d.len()].copy_from_slice(&d);
6171                Ok(d.len())
6172            },
6173
6174            None => Err(Error::Done),
6175        }
6176    }
6177
6178    /// Reads the first received DATAGRAM.
6179    ///
6180    /// This is the same as [`dgram_recv()`] but returns the DATAGRAM as a
6181    /// `Vec<u8>` instead of copying into the provided buffer.
6182    ///
6183    /// [`dgram_recv()`]: struct.Connection.html#method.dgram_recv
6184    #[inline]
6185    pub fn dgram_recv_vec(&mut self) -> Result<Vec<u8>> {
6186        match self.dgram_recv_queue.pop() {
6187            Some(d) => Ok(d),
6188
6189            None => Err(Error::Done),
6190        }
6191    }
6192
6193    /// Reads the first received DATAGRAM without removing it from the queue.
6194    ///
6195    /// On success the DATAGRAM's data is returned along with the actual number
6196    /// of bytes peeked. The requested length cannot exceed the DATAGRAM's
6197    /// actual length.
6198    ///
6199    /// [`Done`] is returned if there is no data to read.
6200    ///
6201    /// [`BufferTooShort`] is returned if the provided buffer is smaller the
6202    /// number of bytes to peek.
6203    ///
6204    /// [`Done`]: enum.Error.html#variant.Done
6205    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
6206    #[inline]
6207    pub fn dgram_recv_peek(&self, buf: &mut [u8], len: usize) -> Result<usize> {
6208        self.dgram_recv_queue.peek_front_bytes(buf, len)
6209    }
6210
6211    /// Returns the length of the first stored DATAGRAM.
6212    #[inline]
6213    pub fn dgram_recv_front_len(&self) -> Option<usize> {
6214        self.dgram_recv_queue.peek_front_len()
6215    }
6216
6217    /// Returns the number of items in the DATAGRAM receive queue.
6218    #[inline]
6219    pub fn dgram_recv_queue_len(&self) -> usize {
6220        self.dgram_recv_queue.len()
6221    }
6222
6223    /// Returns the total size of all items in the DATAGRAM receive queue.
6224    #[inline]
6225    pub fn dgram_recv_queue_byte_size(&self) -> usize {
6226        self.dgram_recv_queue.byte_size()
6227    }
6228
6229    /// Returns the number of items in the DATAGRAM send queue.
6230    #[inline]
6231    pub fn dgram_send_queue_len(&self) -> usize {
6232        self.dgram_send_queue.len()
6233    }
6234
6235    /// Returns the total size of all items in the DATAGRAM send queue.
6236    #[inline]
6237    pub fn dgram_send_queue_byte_size(&self) -> usize {
6238        self.dgram_send_queue.byte_size()
6239    }
6240
6241    /// Returns whether or not the DATAGRAM send queue is full.
6242    #[inline]
6243    pub fn is_dgram_send_queue_full(&self) -> bool {
6244        self.dgram_send_queue.is_full()
6245    }
6246
6247    /// Returns whether or not the DATAGRAM recv queue is full.
6248    #[inline]
6249    pub fn is_dgram_recv_queue_full(&self) -> bool {
6250        self.dgram_recv_queue.is_full()
6251    }
6252
6253    /// Sends data in a DATAGRAM frame.
6254    ///
6255    /// [`Done`] is returned if no data was written.
6256    /// [`InvalidState`] is returned if the peer does not support DATAGRAM.
6257    /// [`BufferTooShort`] is returned if the DATAGRAM frame length is larger
6258    /// than peer's supported DATAGRAM frame length. Use
6259    /// [`dgram_max_writable_len()`] to get the largest supported DATAGRAM
6260    /// frame length.
6261    ///
6262    /// Note that there is no flow control of DATAGRAM frames, so in order to
6263    /// avoid buffering an infinite amount of frames we apply an internal
6264    /// limit.
6265    ///
6266    /// [`Done`]: enum.Error.html#variant.Done
6267    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
6268    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
6269    /// [`dgram_max_writable_len()`]:
6270    /// struct.Connection.html#method.dgram_max_writable_len
6271    ///
6272    /// ## Examples:
6273    ///
6274    /// ```no_run
6275    /// # let mut buf = [0; 512];
6276    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6277    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6278    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6279    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6280    /// # let local = socket.local_addr().unwrap();
6281    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6282    /// conn.dgram_send(b"hello")?;
6283    /// # Ok::<(), quiche::Error>(())
6284    /// ```
6285    pub fn dgram_send(&mut self, buf: &[u8]) -> Result<()> {
6286        let max_payload_len = match self.dgram_max_writable_len() {
6287            Some(v) => v,
6288
6289            None => return Err(Error::InvalidState),
6290        };
6291
6292        if buf.len() > max_payload_len {
6293            return Err(Error::BufferTooShort);
6294        }
6295
6296        self.dgram_send_queue.push(buf.to_vec())?;
6297
6298        let active_path = self.paths.get_active_mut()?;
6299
6300        if self.dgram_send_queue.byte_size() >
6301            active_path.recovery.cwnd_available()
6302        {
6303            active_path.recovery.update_app_limited(false);
6304        }
6305
6306        Ok(())
6307    }
6308
6309    /// Sends data in a DATAGRAM frame.
6310    ///
6311    /// This is the same as [`dgram_send()`] but takes a `Vec<u8>` instead of
6312    /// a slice.
6313    ///
6314    /// [`dgram_send()`]: struct.Connection.html#method.dgram_send
6315    pub fn dgram_send_vec(&mut self, buf: Vec<u8>) -> Result<()> {
6316        let max_payload_len = match self.dgram_max_writable_len() {
6317            Some(v) => v,
6318
6319            None => return Err(Error::InvalidState),
6320        };
6321
6322        if buf.len() > max_payload_len {
6323            return Err(Error::BufferTooShort);
6324        }
6325
6326        self.dgram_send_queue.push(buf)?;
6327
6328        let active_path = self.paths.get_active_mut()?;
6329
6330        if self.dgram_send_queue.byte_size() >
6331            active_path.recovery.cwnd_available()
6332        {
6333            active_path.recovery.update_app_limited(false);
6334        }
6335
6336        Ok(())
6337    }
6338
6339    /// Purges queued outgoing DATAGRAMs matching the predicate.
6340    ///
6341    /// In other words, remove all elements `e` such that `f(&e)` returns true.
6342    ///
6343    /// ## Examples:
6344    /// ```no_run
6345    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6346    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6347    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6348    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6349    /// # let local = socket.local_addr().unwrap();
6350    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6351    /// conn.dgram_send(b"hello")?;
6352    /// conn.dgram_purge_outgoing(&|d: &[u8]| -> bool { d[0] == 0 });
6353    /// # Ok::<(), quiche::Error>(())
6354    /// ```
6355    #[inline]
6356    pub fn dgram_purge_outgoing<FN: Fn(&[u8]) -> bool>(&mut self, f: FN) {
6357        self.dgram_send_queue.purge(f);
6358    }
6359
6360    /// Returns the maximum DATAGRAM payload that can be sent.
6361    ///
6362    /// [`None`] is returned if the peer hasn't advertised a maximum DATAGRAM
6363    /// frame size.
6364    ///
6365    /// ## Examples:
6366    ///
6367    /// ```no_run
6368    /// # let mut buf = [0; 512];
6369    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6370    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6371    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6372    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6373    /// # let local = socket.local_addr().unwrap();
6374    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6375    /// if let Some(payload_size) = conn.dgram_max_writable_len() {
6376    ///     if payload_size > 5 {
6377    ///         conn.dgram_send(b"hello")?;
6378    ///     }
6379    /// }
6380    /// # Ok::<(), quiche::Error>(())
6381    /// ```
6382    #[inline]
6383    pub fn dgram_max_writable_len(&self) -> Option<usize> {
6384        match self.peer_transport_params.max_datagram_frame_size {
6385            None => None,
6386            Some(peer_frame_len) => {
6387                let dcid = self.destination_id();
6388                // Start from the maximum packet size...
6389                let mut max_len = self.max_send_udp_payload_size();
6390                // ...subtract the Short packet header overhead...
6391                // (1 byte of pkt_len + len of dcid)
6392                max_len = max_len.saturating_sub(1 + dcid.len());
6393                // ...subtract the packet number (max len)...
6394                max_len = max_len.saturating_sub(packet::MAX_PKT_NUM_LEN);
6395                // ...subtract the crypto overhead...
6396                max_len = max_len.saturating_sub(
6397                    self.crypto_ctx[packet::Epoch::Application]
6398                        .crypto_overhead()?,
6399                );
6400                // ...clamp to what peer can support...
6401                max_len = cmp::min(peer_frame_len as usize, max_len);
6402                // ...subtract frame overhead, checked for underflow.
6403                // (1 byte of frame type + len of length )
6404                max_len.checked_sub(1 + frame::MAX_DGRAM_OVERHEAD)
6405            },
6406        }
6407    }
6408
6409    fn dgram_enabled(&self) -> bool {
6410        self.local_transport_params
6411            .max_datagram_frame_size
6412            .is_some()
6413    }
6414
6415    /// Returns when the next timeout event will occur.
6416    ///
6417    /// Once the timeout Instant has been reached, the [`on_timeout()`] method
6418    /// should be called. A timeout of `None` means that the timer should be
6419    /// disarmed.
6420    ///
6421    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
6422    pub fn timeout_instant(&self) -> Option<Instant> {
6423        if self.is_closed() {
6424            return None;
6425        }
6426
6427        if self.is_draining() {
6428            // Draining timer takes precedence over all other timers. If it is
6429            // set it means the connection is closing so there's no point in
6430            // processing the other timers.
6431            self.draining_timer
6432        } else {
6433            // Use the lowest timer value (i.e. "sooner") among idle and loss
6434            // detection timers. If they are both unset (i.e. `None`) then the
6435            // result is `None`, but if at least one of them is set then a
6436            // `Some(...)` value is returned.
6437            let path_timer = self
6438                .paths
6439                .iter()
6440                .filter_map(|(_, p)| p.recovery.loss_detection_timer())
6441                .min();
6442
6443            let key_update_timer = self.crypto_ctx[packet::Epoch::Application]
6444                .key_update
6445                .as_ref()
6446                .map(|key_update| key_update.timer);
6447
6448            let timers = [self.idle_timer, path_timer, key_update_timer];
6449
6450            timers.iter().filter_map(|&x| x).min()
6451        }
6452    }
6453
6454    /// Returns the amount of time until the next timeout event.
6455    ///
6456    /// Once the given duration has elapsed, the [`on_timeout()`] method should
6457    /// be called. A timeout of `None` means that the timer should be disarmed.
6458    ///
6459    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
6460    pub fn timeout(&self) -> Option<Duration> {
6461        self.timeout_instant().map(|timeout| {
6462            let now = Instant::now();
6463
6464            if timeout <= now {
6465                Duration::ZERO
6466            } else {
6467                timeout.duration_since(now)
6468            }
6469        })
6470    }
6471
6472    /// Processes a timeout event.
6473    ///
6474    /// If no timeout has occurred it does nothing.
6475    pub fn on_timeout(&mut self) {
6476        let now = Instant::now();
6477
6478        if let Some(draining_timer) = self.draining_timer {
6479            if draining_timer <= now {
6480                trace!("{} draining timeout expired", self.trace_id);
6481
6482                self.mark_closed();
6483            }
6484
6485            // Draining timer takes precedence over all other timers. If it is
6486            // set it means the connection is closing so there's no point in
6487            // processing the other timers.
6488            return;
6489        }
6490
6491        if let Some(timer) = self.idle_timer {
6492            if timer <= now {
6493                trace!("{} idle timeout expired", self.trace_id);
6494
6495                self.mark_closed();
6496                self.timed_out = true;
6497                return;
6498            }
6499        }
6500
6501        if let Some(timer) = self.crypto_ctx[packet::Epoch::Application]
6502            .key_update
6503            .as_ref()
6504            .map(|key_update| key_update.timer)
6505        {
6506            if timer <= now {
6507                // Discard previous key once key update timer expired.
6508                let _ = self.crypto_ctx[packet::Epoch::Application]
6509                    .key_update
6510                    .take();
6511            }
6512        }
6513
6514        let handshake_status = self.handshake_status();
6515
6516        for (_, p) in self.paths.iter_mut() {
6517            if let Some(timer) = p.recovery.loss_detection_timer() {
6518                if timer <= now {
6519                    trace!("{} loss detection timeout expired", self.trace_id);
6520
6521                    let OnLossDetectionTimeoutOutcome {
6522                        lost_packets,
6523                        lost_bytes,
6524                    } = p.on_loss_detection_timeout(
6525                        handshake_status,
6526                        now,
6527                        self.is_server,
6528                        &self.trace_id,
6529                    );
6530
6531                    self.lost_count += lost_packets;
6532                    self.lost_bytes += lost_bytes as u64;
6533
6534                    qlog_with_type!(QLOG_METRICS, self.qlog, q, {
6535                        p.recovery.maybe_qlog(q, now);
6536                    });
6537                }
6538            }
6539        }
6540
6541        // Notify timeout events to the application.
6542        self.paths.notify_failed_validations();
6543
6544        // If the active path failed, try to find a new candidate.
6545        if self.paths.get_active_path_id().is_err() {
6546            match self.paths.find_candidate_path() {
6547                Some(pid) => {
6548                    if self.set_active_path(pid, now).is_err() {
6549                        // The connection cannot continue.
6550                        self.mark_closed();
6551                    }
6552                },
6553
6554                // The connection cannot continue.
6555                None => {
6556                    self.mark_closed();
6557                },
6558            }
6559        }
6560    }
6561
6562    /// Requests the stack to perform path validation of the proposed 4-tuple.
6563    ///
6564    /// Probing new paths requires spare Connection IDs at both the host and the
6565    /// peer sides. If it is not the case, it raises an [`OutOfIdentifiers`].
6566    ///
6567    /// The probing of new addresses can only be done by the client. The server
6568    /// can only probe network paths that were previously advertised by
6569    /// [`PathEvent::New`]. If the server tries to probe such an unseen network
6570    /// path, this call raises an [`InvalidState`].
6571    ///
6572    /// The caller might also want to probe an existing path. In such case, it
6573    /// triggers a PATH_CHALLENGE frame, but it does not require spare CIDs.
6574    ///
6575    /// A server always probes a new path it observes. Calling this method is
6576    /// hence not required to validate a new path. However, a server can still
6577    /// request an additional path validation of the proposed 4-tuple.
6578    ///
6579    /// Calling this method several times before calling [`send()`] or
6580    /// [`send_on_path()`] results in a single probe being generated. An
6581    /// application wanting to send multiple in-flight probes must call this
6582    /// method again after having sent packets.
6583    ///
6584    /// Returns the Destination Connection ID sequence number associated to that
6585    /// path.
6586    ///
6587    /// [`PathEvent::New`]: enum.PathEvent.html#variant.New
6588    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
6589    /// [`InvalidState`]: enum.Error.html#InvalidState
6590    /// [`send()`]: struct.Connection.html#method.send
6591    /// [`send_on_path()`]: struct.Connection.html#method.send_on_path
6592    pub fn probe_path(
6593        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
6594    ) -> Result<u64> {
6595        // We may want to probe an existing path.
6596        let pid = match self.paths.path_id_from_addrs(&(local_addr, peer_addr)) {
6597            Some(pid) => pid,
6598            None => self.create_path_on_client(local_addr, peer_addr)?,
6599        };
6600
6601        let path = self.paths.get_mut(pid)?;
6602        path.request_validation();
6603
6604        path.active_dcid_seq.ok_or(Error::InvalidState)
6605    }
6606
6607    /// Migrates the connection to a new local address `local_addr`.
6608    ///
6609    /// The behavior is similar to [`migrate()`], with the nuance that the
6610    /// connection only changes the local address, but not the peer one.
6611    ///
6612    /// See [`migrate()`] for the full specification of this method.
6613    ///
6614    /// [`migrate()`]: struct.Connection.html#method.migrate
6615    pub fn migrate_source(&mut self, local_addr: SocketAddr) -> Result<u64> {
6616        let peer_addr = self.paths.get_active()?.peer_addr();
6617        self.migrate(local_addr, peer_addr)
6618    }
6619
6620    /// Migrates the connection over the given network path between `local_addr`
6621    /// and `peer_addr`.
6622    ///
6623    /// Connection migration can only be initiated by the client. Calling this
6624    /// method as a server returns [`InvalidState`].
6625    ///
6626    /// To initiate voluntary migration, there should be enough Connection IDs
6627    /// at both sides. If this requirement is not satisfied, this call returns
6628    /// [`OutOfIdentifiers`].
6629    ///
6630    /// Returns the Destination Connection ID associated to that migrated path.
6631    ///
6632    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
6633    /// [`InvalidState`]: enum.Error.html#InvalidState
6634    pub fn migrate(
6635        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
6636    ) -> Result<u64> {
6637        if self.is_server {
6638            return Err(Error::InvalidState);
6639        }
6640
6641        // If the path already exists, mark it as the active one.
6642        let (pid, dcid_seq) = if let Some(pid) =
6643            self.paths.path_id_from_addrs(&(local_addr, peer_addr))
6644        {
6645            let path = self.paths.get_mut(pid)?;
6646
6647            // If it is already active, do nothing.
6648            if path.active() {
6649                return path.active_dcid_seq.ok_or(Error::OutOfIdentifiers);
6650            }
6651
6652            // Ensures that a Source Connection ID has been dedicated to this
6653            // path, or a free one is available. This is only required if the
6654            // host uses non-zero length Source Connection IDs.
6655            if !self.ids.zero_length_scid() &&
6656                path.active_scid_seq.is_none() &&
6657                self.ids.available_scids() == 0
6658            {
6659                return Err(Error::OutOfIdentifiers);
6660            }
6661
6662            // Ensures that the migrated path has a Destination Connection ID.
6663            let dcid_seq = if let Some(dcid_seq) = path.active_dcid_seq {
6664                dcid_seq
6665            } else {
6666                let dcid_seq = self
6667                    .ids
6668                    .lowest_available_dcid_seq()
6669                    .ok_or(Error::OutOfIdentifiers)?;
6670
6671                self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
6672                path.active_dcid_seq = Some(dcid_seq);
6673
6674                dcid_seq
6675            };
6676
6677            (pid, dcid_seq)
6678        } else {
6679            let pid = self.create_path_on_client(local_addr, peer_addr)?;
6680
6681            let dcid_seq = self
6682                .paths
6683                .get(pid)?
6684                .active_dcid_seq
6685                .ok_or(Error::InvalidState)?;
6686
6687            (pid, dcid_seq)
6688        };
6689
6690        // Change the active path.
6691        self.set_active_path(pid, Instant::now())?;
6692
6693        Ok(dcid_seq)
6694    }
6695
6696    /// Provides additional source Connection IDs that the peer can use to reach
6697    /// this host.
6698    ///
6699    /// This triggers sending NEW_CONNECTION_ID frames if the provided Source
6700    /// Connection ID is not already present. In the case the caller tries to
6701    /// reuse a Connection ID with a different reset token, this raises an
6702    /// `InvalidState`.
6703    ///
6704    /// At any time, the peer cannot have more Destination Connection IDs than
6705    /// the maximum number of active Connection IDs it negotiated. In such case
6706    /// (i.e., when [`scids_left()`] returns 0), if the host agrees to
6707    /// request the removal of previous connection IDs, it sets the
6708    /// `retire_if_needed` parameter. Otherwise, an [`IdLimit`] is returned.
6709    ///
6710    /// Note that setting `retire_if_needed` does not prevent this function from
6711    /// returning an [`IdLimit`] in the case the caller wants to retire still
6712    /// unannounced Connection IDs.
6713    ///
6714    /// The caller is responsible for ensuring that the provided `scid` is not
6715    /// repeated several times over the connection. quiche ensures that as long
6716    /// as the provided Connection ID is still in use (i.e., not retired), it
6717    /// does not assign a different sequence number.
6718    ///
6719    /// Note that if the host uses zero-length Source Connection IDs, it cannot
6720    /// advertise Source Connection IDs and calling this method returns an
6721    /// [`InvalidState`].
6722    ///
6723    /// Returns the sequence number associated to the provided Connection ID.
6724    ///
6725    /// [`scids_left()`]: struct.Connection.html#method.scids_left
6726    /// [`IdLimit`]: enum.Error.html#IdLimit
6727    /// [`InvalidState`]: enum.Error.html#InvalidState
6728    pub fn new_scid(
6729        &mut self, scid: &ConnectionId, reset_token: u128, retire_if_needed: bool,
6730    ) -> Result<u64> {
6731        self.ids.new_scid(
6732            scid.to_vec().into(),
6733            Some(reset_token),
6734            true,
6735            None,
6736            retire_if_needed,
6737        )
6738    }
6739
6740    /// Returns the number of source Connection IDs that are active. This is
6741    /// only meaningful if the host uses non-zero length Source Connection IDs.
6742    pub fn active_scids(&self) -> usize {
6743        self.ids.active_source_cids()
6744    }
6745
6746    /// Returns the number of source Connection IDs that should be provided
6747    /// to the peer without exceeding the limit it advertised.
6748    ///
6749    /// This will automatically limit the number of Connection IDs to the
6750    /// minimum between the locally configured active connection ID limit,
6751    /// and the one sent by the peer.
6752    ///
6753    /// To obtain the maximum possible value allowed by the peer an application
6754    /// can instead inspect the [`peer_active_conn_id_limit`] value.
6755    ///
6756    /// [`peer_active_conn_id_limit`]: struct.Stats.html#structfield.peer_active_conn_id_limit
6757    #[inline]
6758    pub fn scids_left(&self) -> usize {
6759        let max_active_source_cids = cmp::min(
6760            self.peer_transport_params.active_conn_id_limit,
6761            self.local_transport_params.active_conn_id_limit,
6762        ) as usize;
6763
6764        max_active_source_cids - self.active_scids()
6765    }
6766
6767    /// Requests the retirement of the destination Connection ID used by the
6768    /// host to reach its peer.
6769    ///
6770    /// This triggers sending RETIRE_CONNECTION_ID frames.
6771    ///
6772    /// If the application tries to retire a non-existing Destination Connection
6773    /// ID sequence number, or if it uses zero-length Destination Connection ID,
6774    /// this method returns an [`InvalidState`].
6775    ///
6776    /// At any time, the host must have at least one Destination ID. If the
6777    /// application tries to retire the last one, or if the caller tries to
6778    /// retire the destination Connection ID used by the current active path
6779    /// while having neither spare Destination Connection IDs nor validated
6780    /// network paths, this method returns an [`OutOfIdentifiers`]. This
6781    /// behavior prevents the caller from stalling the connection due to the
6782    /// lack of validated path to send non-probing packets.
6783    ///
6784    /// [`InvalidState`]: enum.Error.html#InvalidState
6785    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
6786    pub fn retire_dcid(&mut self, dcid_seq: u64) -> Result<()> {
6787        if self.ids.zero_length_dcid() {
6788            return Err(Error::InvalidState);
6789        }
6790
6791        let active_path_dcid_seq = self
6792            .paths
6793            .get_active()?
6794            .active_dcid_seq
6795            .ok_or(Error::InvalidState)?;
6796
6797        let active_path_id = self.paths.get_active_path_id()?;
6798
6799        if active_path_dcid_seq == dcid_seq &&
6800            self.ids.lowest_available_dcid_seq().is_none() &&
6801            !self
6802                .paths
6803                .iter()
6804                .any(|(pid, p)| pid != active_path_id && p.usable())
6805        {
6806            return Err(Error::OutOfIdentifiers);
6807        }
6808
6809        if let Some(pid) = self.ids.retire_dcid(dcid_seq)? {
6810            // The retired Destination CID was associated to a given path. Let's
6811            // find an available DCID to associate to that path.
6812            let path = self.paths.get_mut(pid)?;
6813            let dcid_seq = self.ids.lowest_available_dcid_seq();
6814
6815            if let Some(dcid_seq) = dcid_seq {
6816                self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
6817            }
6818
6819            path.active_dcid_seq = dcid_seq;
6820        }
6821
6822        Ok(())
6823    }
6824
6825    /// Processes path-specific events.
6826    ///
6827    /// On success it returns a [`PathEvent`], or `None` when there are no
6828    /// events to report. Please refer to [`PathEvent`] for the exhaustive event
6829    /// list.
6830    ///
6831    /// Note that all events are edge-triggered, meaning that once reported they
6832    /// will not be reported again by calling this method again, until the event
6833    /// is re-armed.
6834    ///
6835    /// [`PathEvent`]: enum.PathEvent.html
6836    pub fn path_event_next(&mut self) -> Option<PathEvent> {
6837        self.paths.pop_event()
6838    }
6839
6840    /// Returns the number of source Connection IDs that are retired.
6841    pub fn retired_scids(&self) -> usize {
6842        self.ids.retired_source_cids()
6843    }
6844
6845    /// Returns a source `ConnectionId` that has been retired.
6846    ///
6847    /// On success it returns a [`ConnectionId`], or `None` when there are no
6848    /// more retired connection IDs.
6849    ///
6850    /// [`ConnectionId`]: struct.ConnectionId.html
6851    pub fn retired_scid_next(&mut self) -> Option<ConnectionId<'static>> {
6852        self.ids.pop_retired_scid()
6853    }
6854
6855    /// Returns the number of spare Destination Connection IDs, i.e.,
6856    /// Destination Connection IDs that are still unused.
6857    ///
6858    /// Note that this function returns 0 if the host uses zero length
6859    /// Destination Connection IDs.
6860    pub fn available_dcids(&self) -> usize {
6861        self.ids.available_dcids()
6862    }
6863
6864    /// Returns an iterator over destination `SockAddr`s whose association
6865    /// with `from` forms a known QUIC path on which packets can be sent to.
6866    ///
6867    /// This function is typically used in combination with [`send_on_path()`].
6868    ///
6869    /// Note that the iterator includes all the possible combination of
6870    /// destination `SockAddr`s, even those whose sending is not required now.
6871    /// In other words, this is another way for the application to recall from
6872    /// past [`PathEvent::New`] events.
6873    ///
6874    /// [`PathEvent::New`]: enum.PathEvent.html#variant.New
6875    /// [`send_on_path()`]: struct.Connection.html#method.send_on_path
6876    ///
6877    /// ## Examples:
6878    ///
6879    /// ```no_run
6880    /// # let mut out = [0; 512];
6881    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6882    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6883    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6884    /// # let local = socket.local_addr().unwrap();
6885    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6886    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6887    /// // Iterate over possible destinations for the given local `SockAddr`.
6888    /// for dest in conn.paths_iter(local) {
6889    ///     loop {
6890    ///         let (write, send_info) =
6891    ///             match conn.send_on_path(&mut out, Some(local), Some(dest)) {
6892    ///                 Ok(v) => v,
6893    ///
6894    ///                 Err(quiche::Error::Done) => {
6895    ///                     // Done writing for this destination.
6896    ///                     break;
6897    ///                 },
6898    ///
6899    ///                 Err(e) => {
6900    ///                     // An error occurred, handle it.
6901    ///                     break;
6902    ///                 },
6903    ///             };
6904    ///
6905    ///         socket.send_to(&out[..write], &send_info.to).unwrap();
6906    ///     }
6907    /// }
6908    /// # Ok::<(), quiche::Error>(())
6909    /// ```
6910    #[inline]
6911    pub fn paths_iter(&self, from: SocketAddr) -> SocketAddrIter {
6912        // Instead of trying to identify whether packets will be sent on the
6913        // given 4-tuple, simply filter paths that cannot be used.
6914        SocketAddrIter {
6915            sockaddrs: self
6916                .paths
6917                .iter()
6918                .filter(|(_, p)| p.active_dcid_seq.is_some())
6919                .filter(|(_, p)| p.usable() || p.probing_required())
6920                .filter(|(_, p)| p.local_addr() == from)
6921                .map(|(_, p)| p.peer_addr())
6922                .collect(),
6923
6924            index: 0,
6925        }
6926    }
6927
6928    /// Closes the connection with the given error and reason.
6929    ///
6930    /// The `app` parameter specifies whether an application close should be
6931    /// sent to the peer. Otherwise a normal connection close is sent.
6932    ///
6933    /// If `app` is true but the connection is not in a state that is safe to
6934    /// send an application error (not established nor in early data), in
6935    /// accordance with [RFC
6936    /// 9000](https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.3-3), the
6937    /// error code is changed to APPLICATION_ERROR and the reason phrase is
6938    /// cleared.
6939    ///
6940    /// Returns [`Done`] if the connection had already been closed.
6941    ///
6942    /// Note that the connection will not be closed immediately. An application
6943    /// should continue calling the [`recv()`], [`send()`], [`timeout()`] and
6944    /// [`on_timeout()`] methods as normal, until the [`is_closed()`] method
6945    /// returns `true`.
6946    ///
6947    /// [`Done`]: enum.Error.html#variant.Done
6948    /// [`recv()`]: struct.Connection.html#method.recv
6949    /// [`send()`]: struct.Connection.html#method.send
6950    /// [`timeout()`]: struct.Connection.html#method.timeout
6951    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
6952    /// [`is_closed()`]: struct.Connection.html#method.is_closed
6953    pub fn close(&mut self, app: bool, err: u64, reason: &[u8]) -> Result<()> {
6954        if self.is_closed() || self.is_draining() {
6955            return Err(Error::Done);
6956        }
6957
6958        if self.local_error.is_some() {
6959            return Err(Error::Done);
6960        }
6961
6962        let is_safe_to_send_app_data =
6963            self.is_established() || self.is_in_early_data();
6964
6965        if app && !is_safe_to_send_app_data {
6966            // Clear error information.
6967            self.local_error = Some(ConnectionError {
6968                is_app: false,
6969                error_code: 0x0c,
6970                reason: vec![],
6971            });
6972        } else {
6973            self.local_error = Some(ConnectionError {
6974                is_app: app,
6975                error_code: err,
6976                reason: reason.to_vec(),
6977            });
6978        }
6979
6980        // When no packet was successfully processed close connection immediately.
6981        if self.recv_count == 0 {
6982            self.mark_closed();
6983        }
6984
6985        Ok(())
6986    }
6987
6988    /// Returns a string uniquely representing the connection.
6989    ///
6990    /// This can be used for logging purposes to differentiate between multiple
6991    /// connections.
6992    #[inline]
6993    pub fn trace_id(&self) -> &str {
6994        &self.trace_id
6995    }
6996
6997    /// Returns the negotiated ALPN protocol.
6998    ///
6999    /// If no protocol has been negotiated, the returned value is empty.
7000    #[inline]
7001    pub fn application_proto(&self) -> &[u8] {
7002        self.alpn.as_ref()
7003    }
7004
7005    /// Returns the server name requested by the client.
7006    #[inline]
7007    pub fn server_name(&self) -> Option<&str> {
7008        self.handshake.server_name()
7009    }
7010
7011    /// Returns the peer's leaf certificate (if any) as a DER-encoded buffer.
7012    #[inline]
7013    pub fn peer_cert(&self) -> Option<&[u8]> {
7014        self.handshake.peer_cert()
7015    }
7016
7017    /// Returns the peer's certificate chain (if any) as a vector of DER-encoded
7018    /// buffers.
7019    ///
7020    /// The certificate at index 0 is the peer's leaf certificate, the other
7021    /// certificates (if any) are the chain certificate authorities used to
7022    /// sign the leaf certificate.
7023    #[inline]
7024    pub fn peer_cert_chain(&self) -> Option<Vec<&[u8]>> {
7025        self.handshake.peer_cert_chain()
7026    }
7027
7028    /// Returns the serialized cryptographic session for the connection.
7029    ///
7030    /// This can be used by a client to cache a connection's session, and resume
7031    /// it later using the [`set_session()`] method.
7032    ///
7033    /// [`set_session()`]: struct.Connection.html#method.set_session
7034    #[inline]
7035    pub fn session(&self) -> Option<&[u8]> {
7036        self.session.as_deref()
7037    }
7038
7039    /// Returns the source connection ID.
7040    ///
7041    /// When there are multiple IDs, and if there is an active path, the ID used
7042    /// on that path is returned. Otherwise the oldest ID is returned.
7043    ///
7044    /// Note that the value returned can change throughout the connection's
7045    /// lifetime.
7046    #[inline]
7047    pub fn source_id(&self) -> ConnectionId<'_> {
7048        if let Ok(path) = self.paths.get_active() {
7049            if let Some(active_scid_seq) = path.active_scid_seq {
7050                if let Ok(e) = self.ids.get_scid(active_scid_seq) {
7051                    return ConnectionId::from_ref(e.cid.as_ref());
7052                }
7053            }
7054        }
7055
7056        let e = self.ids.oldest_scid();
7057        ConnectionId::from_ref(e.cid.as_ref())
7058    }
7059
7060    /// Returns all active source connection IDs.
7061    ///
7062    /// An iterator is returned for all active IDs (i.e. ones that have not
7063    /// been explicitly retired yet).
7064    #[inline]
7065    pub fn source_ids(&self) -> impl Iterator<Item = &ConnectionId<'_>> {
7066        self.ids.scids_iter()
7067    }
7068
7069    /// Returns the destination connection ID.
7070    ///
7071    /// Note that the value returned can change throughout the connection's
7072    /// lifetime.
7073    #[inline]
7074    pub fn destination_id(&self) -> ConnectionId<'_> {
7075        if let Ok(path) = self.paths.get_active() {
7076            if let Some(active_dcid_seq) = path.active_dcid_seq {
7077                if let Ok(e) = self.ids.get_dcid(active_dcid_seq) {
7078                    return ConnectionId::from_ref(e.cid.as_ref());
7079                }
7080            }
7081        }
7082
7083        let e = self.ids.oldest_dcid();
7084        ConnectionId::from_ref(e.cid.as_ref())
7085    }
7086
7087    /// Returns the PMTU for the active path if it exists. This requires no
7088    /// additonal packets to be sent but simply checks if PMTUD has completed
7089    /// and has found a valid PMTU.
7090    #[inline]
7091    pub fn pmtu(&self) -> Option<usize> {
7092        if let Ok(path) = self.paths.get_active() {
7093            path.pmtud.as_ref().and_then(|pmtud| pmtud.get_pmtu())
7094        } else {
7095            None
7096        }
7097    }
7098
7099    /// Revalidates the PMTU for the active path by sending a new probe packet
7100    /// of PMTU size. If the probe is dropped PMTUD will restart and find a new
7101    /// valid PMTU.
7102    #[inline]
7103    pub fn revalidate_pmtu(&mut self) {
7104        if let Ok(active_path) = self.paths.get_active_mut() {
7105            if let Some(pmtud) = active_path.pmtud.as_mut() {
7106                pmtud.revalidate_pmtu();
7107            }
7108        }
7109    }
7110
7111    /// Returns true if the connection handshake is complete.
7112    #[inline]
7113    pub fn is_established(&self) -> bool {
7114        self.handshake_completed
7115    }
7116
7117    /// Returns true if the connection is resumed.
7118    #[inline]
7119    pub fn is_resumed(&self) -> bool {
7120        self.handshake.is_resumed()
7121    }
7122
7123    /// Returns true if the connection has a pending handshake that has
7124    /// progressed enough to send or receive early data.
7125    #[inline]
7126    pub fn is_in_early_data(&self) -> bool {
7127        self.handshake.is_in_early_data()
7128    }
7129
7130    /// Returns whether there is stream or DATAGRAM data available to read.
7131    #[inline]
7132    pub fn is_readable(&self) -> bool {
7133        self.streams.has_readable() || self.dgram_recv_front_len().is_some()
7134    }
7135
7136    /// Returns whether the network path with local address `from` and remote
7137    /// address `peer` has been validated.
7138    ///
7139    /// If the 4-tuple does not exist over the connection, returns an
7140    /// [`InvalidState`].
7141    ///
7142    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
7143    pub fn is_path_validated(
7144        &self, from: SocketAddr, to: SocketAddr,
7145    ) -> Result<bool> {
7146        let pid = self
7147            .paths
7148            .path_id_from_addrs(&(from, to))
7149            .ok_or(Error::InvalidState)?;
7150
7151        Ok(self.paths.get(pid)?.validated())
7152    }
7153
7154    /// Returns true if the connection is draining.
7155    ///
7156    /// If this returns `true`, the connection object cannot yet be dropped, but
7157    /// no new application data can be sent or received. An application should
7158    /// continue calling the [`recv()`], [`timeout()`], and [`on_timeout()`]
7159    /// methods as normal, until the [`is_closed()`] method returns `true`.
7160    ///
7161    /// In contrast, once `is_draining()` returns `true`, calling [`send()`]
7162    /// is not required because no new outgoing packets will be generated.
7163    ///
7164    /// [`recv()`]: struct.Connection.html#method.recv
7165    /// [`send()`]: struct.Connection.html#method.send
7166    /// [`timeout()`]: struct.Connection.html#method.timeout
7167    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
7168    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7169    #[inline]
7170    pub fn is_draining(&self) -> bool {
7171        self.draining_timer.is_some()
7172    }
7173
7174    /// Returns true if the connection is closed.
7175    ///
7176    /// If this returns true, the connection object can be dropped.
7177    #[inline]
7178    pub fn is_closed(&self) -> bool {
7179        self.closed
7180    }
7181
7182    /// Returns true if the connection was closed due to the idle timeout.
7183    #[inline]
7184    pub fn is_timed_out(&self) -> bool {
7185        self.timed_out
7186    }
7187
7188    /// Returns the error received from the peer, if any.
7189    ///
7190    /// Note that a `Some` return value does not necessarily imply
7191    /// [`is_closed()`] or any other connection state.
7192    ///
7193    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7194    #[inline]
7195    pub fn peer_error(&self) -> Option<&ConnectionError> {
7196        self.peer_error.as_ref()
7197    }
7198
7199    /// Returns the error [`close()`] was called with, or internally
7200    /// created quiche errors, if any.
7201    ///
7202    /// Note that a `Some` return value does not necessarily imply
7203    /// [`is_closed()`] or any other connection state.
7204    /// `Some` also does not guarantee that the error has been sent to
7205    /// or received by the peer.
7206    ///
7207    /// [`close()`]: struct.Connection.html#method.close
7208    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7209    #[inline]
7210    pub fn local_error(&self) -> Option<&ConnectionError> {
7211        self.local_error.as_ref()
7212    }
7213
7214    /// Collects and returns statistics about the connection.
7215    #[inline]
7216    pub fn stats(&self) -> Stats {
7217        Stats {
7218            recv: self.recv_count,
7219            sent: self.sent_count,
7220            lost: self.lost_count,
7221            spurious_lost: self.spurious_lost_count,
7222            retrans: self.retrans_count,
7223            sent_bytes: self.sent_bytes,
7224            recv_bytes: self.recv_bytes,
7225            acked_bytes: self.acked_bytes,
7226            lost_bytes: self.lost_bytes,
7227            stream_retrans_bytes: self.stream_retrans_bytes,
7228            dgram_recv: self.dgram_recv_count,
7229            dgram_sent: self.dgram_sent_count,
7230            paths_count: self.paths.len(),
7231            reset_stream_count_local: self.reset_stream_local_count,
7232            stopped_stream_count_local: self.stopped_stream_local_count,
7233            reset_stream_count_remote: self.reset_stream_remote_count,
7234            stopped_stream_count_remote: self.stopped_stream_remote_count,
7235            path_challenge_rx_count: self.path_challenge_rx_count,
7236            bytes_in_flight_duration: self.bytes_in_flight_duration(),
7237        }
7238    }
7239
7240    /// Returns the sum of the durations when each path in the
7241    /// connection was actively sending bytes or waiting for acks.
7242    /// Note that this could result in a duration that is longer than
7243    /// the actual connection duration in cases where multiple paths
7244    /// are active for extended periods of time.  In practice only 1
7245    /// path is typically active at a time.
7246    /// TODO revisit computation if in the future multiple paths are
7247    /// often active at the same time.
7248    fn bytes_in_flight_duration(&self) -> Duration {
7249        self.paths.iter().fold(Duration::ZERO, |acc, (_, path)| {
7250            acc + path.bytes_in_flight_duration()
7251        })
7252    }
7253
7254    /// Returns reference to peer's transport parameters. Returns `None` if we
7255    /// have not yet processed the peer's transport parameters.
7256    pub fn peer_transport_params(&self) -> Option<&TransportParams> {
7257        if !self.parsed_peer_transport_params {
7258            return None;
7259        }
7260
7261        Some(&self.peer_transport_params)
7262    }
7263
7264    /// Collects and returns statistics about each known path for the
7265    /// connection.
7266    pub fn path_stats(&self) -> impl Iterator<Item = PathStats> + '_ {
7267        self.paths.iter().map(|(_, p)| p.stats())
7268    }
7269
7270    /// Returns whether or not this is a server-side connection.
7271    pub fn is_server(&self) -> bool {
7272        self.is_server
7273    }
7274
7275    fn encode_transport_params(&mut self) -> Result<()> {
7276        self.handshake.set_quic_transport_params(
7277            &self.local_transport_params,
7278            self.is_server,
7279        )
7280    }
7281
7282    fn parse_peer_transport_params(
7283        &mut self, peer_params: TransportParams,
7284    ) -> Result<()> {
7285        // Validate initial_source_connection_id.
7286        match &peer_params.initial_source_connection_id {
7287            Some(v) if v != &self.destination_id() =>
7288                return Err(Error::InvalidTransportParam),
7289
7290            Some(_) => (),
7291
7292            // initial_source_connection_id must be sent by
7293            // both endpoints.
7294            None => return Err(Error::InvalidTransportParam),
7295        }
7296
7297        // Validate original_destination_connection_id.
7298        if let Some(odcid) = &self.odcid {
7299            match &peer_params.original_destination_connection_id {
7300                Some(v) if v != odcid =>
7301                    return Err(Error::InvalidTransportParam),
7302
7303                Some(_) => (),
7304
7305                // original_destination_connection_id must be
7306                // sent by the server.
7307                None if !self.is_server =>
7308                    return Err(Error::InvalidTransportParam),
7309
7310                None => (),
7311            }
7312        }
7313
7314        // Validate retry_source_connection_id.
7315        if let Some(rscid) = &self.rscid {
7316            match &peer_params.retry_source_connection_id {
7317                Some(v) if v != rscid =>
7318                    return Err(Error::InvalidTransportParam),
7319
7320                Some(_) => (),
7321
7322                // retry_source_connection_id must be sent by
7323                // the server.
7324                None => return Err(Error::InvalidTransportParam),
7325            }
7326        }
7327
7328        self.process_peer_transport_params(peer_params)?;
7329
7330        self.parsed_peer_transport_params = true;
7331
7332        Ok(())
7333    }
7334
7335    fn process_peer_transport_params(
7336        &mut self, peer_params: TransportParams,
7337    ) -> Result<()> {
7338        self.max_tx_data = peer_params.initial_max_data;
7339
7340        // Update send capacity.
7341        self.update_tx_cap();
7342
7343        self.streams
7344            .update_peer_max_streams_bidi(peer_params.initial_max_streams_bidi);
7345        self.streams
7346            .update_peer_max_streams_uni(peer_params.initial_max_streams_uni);
7347
7348        let max_ack_delay = Duration::from_millis(peer_params.max_ack_delay);
7349
7350        self.recovery_config.max_ack_delay = max_ack_delay;
7351
7352        let active_path = self.paths.get_active_mut()?;
7353
7354        active_path.recovery.update_max_ack_delay(max_ack_delay);
7355
7356        if active_path
7357            .pmtud
7358            .as_ref()
7359            .map(|pmtud| pmtud.should_probe())
7360            .unwrap_or(false)
7361        {
7362            active_path.recovery.pmtud_update_max_datagram_size(
7363                active_path
7364                    .pmtud
7365                    .as_mut()
7366                    .expect("PMTUD existence verified above")
7367                    .get_probe_size()
7368                    .min(peer_params.max_udp_payload_size as usize),
7369            );
7370        } else {
7371            active_path.recovery.update_max_datagram_size(
7372                peer_params.max_udp_payload_size as usize,
7373            );
7374        }
7375
7376        // Record the max_active_conn_id parameter advertised by the peer.
7377        self.ids
7378            .set_source_conn_id_limit(peer_params.active_conn_id_limit);
7379
7380        self.peer_transport_params = peer_params;
7381
7382        Ok(())
7383    }
7384
7385    /// Continues the handshake.
7386    ///
7387    /// If the connection is already established, it does nothing.
7388    fn do_handshake(&mut self, now: Instant) -> Result<()> {
7389        let mut ex_data = tls::ExData {
7390            application_protos: &self.application_protos,
7391
7392            crypto_ctx: &mut self.crypto_ctx,
7393
7394            session: &mut self.session,
7395
7396            local_error: &mut self.local_error,
7397
7398            keylog: self.keylog.as_mut(),
7399
7400            trace_id: &self.trace_id,
7401
7402            local_transport_params: self.local_transport_params.clone(),
7403
7404            recovery_config: self.recovery_config,
7405
7406            tx_cap_factor: self.tx_cap_factor,
7407
7408            pmtud: None,
7409
7410            is_server: self.is_server,
7411        };
7412
7413        if self.handshake_completed {
7414            return self.handshake.process_post_handshake(&mut ex_data);
7415        }
7416
7417        match self.handshake.do_handshake(&mut ex_data) {
7418            Ok(_) => (),
7419
7420            Err(Error::Done) => {
7421                // Apply in-handshake configuration from callbacks before any
7422                // packet has been sent.
7423                if self.sent_count == 0 {
7424                    if ex_data.recovery_config != self.recovery_config {
7425                        if let Ok(path) = self.paths.get_active_mut() {
7426                            self.recovery_config = ex_data.recovery_config;
7427                            path.reinit_recovery(&self.recovery_config);
7428                        }
7429                    }
7430
7431                    if ex_data.tx_cap_factor != self.tx_cap_factor {
7432                        self.tx_cap_factor = ex_data.tx_cap_factor;
7433                    }
7434
7435                    if let Some(discover) = ex_data.pmtud {
7436                        self.paths.set_discover_pmtu_on_existing_paths(
7437                            discover,
7438                            self.recovery_config.max_send_udp_payload_size,
7439                        );
7440                    }
7441
7442                    if ex_data.local_transport_params !=
7443                        self.local_transport_params
7444                    {
7445                        self.streams.set_max_streams_bidi(
7446                            ex_data
7447                                .local_transport_params
7448                                .initial_max_streams_bidi,
7449                        );
7450
7451                        self.local_transport_params =
7452                            ex_data.local_transport_params;
7453                    }
7454                }
7455
7456                // Try to parse transport parameters as soon as the first flight
7457                // of handshake data is processed.
7458                //
7459                // This is potentially dangerous as the handshake hasn't been
7460                // completed yet, though it's required to be able to send data
7461                // in 0.5 RTT.
7462                let raw_params = self.handshake.quic_transport_params();
7463
7464                if !self.parsed_peer_transport_params && !raw_params.is_empty() {
7465                    let peer_params = TransportParams::decode(
7466                        raw_params,
7467                        self.is_server,
7468                        self.peer_transport_params_track_unknown,
7469                    )?;
7470
7471                    self.parse_peer_transport_params(peer_params)?;
7472                }
7473
7474                return Ok(());
7475            },
7476
7477            Err(e) => return Err(e),
7478        };
7479
7480        self.handshake_completed = self.handshake.is_completed();
7481
7482        self.alpn = self.handshake.alpn_protocol().to_vec();
7483
7484        let raw_params = self.handshake.quic_transport_params();
7485
7486        if !self.parsed_peer_transport_params && !raw_params.is_empty() {
7487            let peer_params = TransportParams::decode(
7488                raw_params,
7489                self.is_server,
7490                self.peer_transport_params_track_unknown,
7491            )?;
7492
7493            self.parse_peer_transport_params(peer_params)?;
7494        }
7495
7496        if self.handshake_completed {
7497            // The handshake is considered confirmed at the server when the
7498            // handshake completes, at which point we can also drop the
7499            // handshake epoch.
7500            if self.is_server {
7501                self.handshake_confirmed = true;
7502
7503                self.drop_epoch_state(packet::Epoch::Handshake, now);
7504            }
7505
7506            // Once the handshake is completed there's no point in processing
7507            // 0-RTT packets anymore, so clear the buffer now.
7508            self.undecryptable_pkts.clear();
7509
7510            trace!("{} connection established: proto={:?} cipher={:?} curve={:?} sigalg={:?} resumed={} {:?}",
7511                   &self.trace_id,
7512                   std::str::from_utf8(self.application_proto()),
7513                   self.handshake.cipher(),
7514                   self.handshake.curve(),
7515                   self.handshake.sigalg(),
7516                   self.handshake.is_resumed(),
7517                   self.peer_transport_params);
7518        }
7519
7520        Ok(())
7521    }
7522
7523    /// Selects the packet type for the next outgoing packet.
7524    fn write_pkt_type(&self, send_pid: usize) -> Result<Type> {
7525        // On error send packet in the latest epoch available, but only send
7526        // 1-RTT ones when the handshake is completed.
7527        if self
7528            .local_error
7529            .as_ref()
7530            .is_some_and(|conn_err| !conn_err.is_app)
7531        {
7532            let epoch = match self.handshake.write_level() {
7533                crypto::Level::Initial => packet::Epoch::Initial,
7534                crypto::Level::ZeroRTT => unreachable!(),
7535                crypto::Level::Handshake => packet::Epoch::Handshake,
7536                crypto::Level::OneRTT => packet::Epoch::Application,
7537            };
7538
7539            if !self.handshake_confirmed {
7540                match epoch {
7541                    // Downgrade the epoch to Handshake as the handshake is not
7542                    // completed yet.
7543                    packet::Epoch::Application => return Ok(Type::Handshake),
7544
7545                    // Downgrade the epoch to Initial as the remote peer might
7546                    // not be able to decrypt handshake packets yet.
7547                    packet::Epoch::Handshake
7548                        if self.crypto_ctx[packet::Epoch::Initial].has_keys() =>
7549                        return Ok(Type::Initial),
7550
7551                    _ => (),
7552                };
7553            }
7554
7555            return Ok(Type::from_epoch(epoch));
7556        }
7557
7558        for &epoch in packet::Epoch::epochs(
7559            packet::Epoch::Initial..=packet::Epoch::Application,
7560        ) {
7561            let crypto_ctx = &self.crypto_ctx[epoch];
7562            let pkt_space = &self.pkt_num_spaces[epoch];
7563
7564            // Only send packets in a space when we have the send keys for it.
7565            if crypto_ctx.crypto_seal.is_none() {
7566                continue;
7567            }
7568
7569            // We are ready to send data for this packet number space.
7570            if crypto_ctx.data_available() || pkt_space.ready() {
7571                return Ok(Type::from_epoch(epoch));
7572            }
7573
7574            // There are lost frames in this packet number space.
7575            for (_, p) in self.paths.iter() {
7576                if p.recovery.has_lost_frames(epoch) {
7577                    return Ok(Type::from_epoch(epoch));
7578                }
7579
7580                // We need to send PTO probe packets.
7581                if p.recovery.loss_probes(epoch) > 0 {
7582                    return Ok(Type::from_epoch(epoch));
7583                }
7584            }
7585        }
7586
7587        // If there are flushable, almost full or blocked streams, use the
7588        // Application epoch.
7589        let send_path = self.paths.get(send_pid)?;
7590        if (self.is_established() || self.is_in_early_data()) &&
7591            (self.should_send_handshake_done() ||
7592                self.almost_full ||
7593                self.blocked_limit.is_some() ||
7594                self.dgram_send_queue.has_pending() ||
7595                self.local_error
7596                    .as_ref()
7597                    .is_some_and(|conn_err| conn_err.is_app) ||
7598                self.streams.should_update_max_streams_bidi() ||
7599                self.streams.should_update_max_streams_uni() ||
7600                self.streams.has_flushable() ||
7601                self.streams.has_almost_full() ||
7602                self.streams.has_blocked() ||
7603                self.streams.has_reset() ||
7604                self.streams.has_stopped() ||
7605                self.ids.has_new_scids() ||
7606                self.ids.has_retire_dcids() ||
7607                send_path
7608                    .pmtud
7609                    .as_ref()
7610                    .is_some_and(|pmtud| pmtud.should_probe()) ||
7611                send_path.needs_ack_eliciting ||
7612                send_path.probing_required())
7613        {
7614            // Only clients can send 0-RTT packets.
7615            if !self.is_server && self.is_in_early_data() {
7616                return Ok(Type::ZeroRTT);
7617            }
7618
7619            return Ok(Type::Short);
7620        }
7621
7622        Err(Error::Done)
7623    }
7624
7625    /// Returns the mutable stream with the given ID if it exists, or creates
7626    /// a new one otherwise.
7627    fn get_or_create_stream(
7628        &mut self, id: u64, local: bool,
7629    ) -> Result<&mut stream::Stream<F>> {
7630        self.streams.get_or_create(
7631            id,
7632            &self.local_transport_params,
7633            &self.peer_transport_params,
7634            local,
7635            self.is_server,
7636        )
7637    }
7638
7639    /// Processes an incoming frame.
7640    fn process_frame(
7641        &mut self, frame: frame::Frame, hdr: &Header, recv_path_id: usize,
7642        epoch: packet::Epoch, now: Instant,
7643    ) -> Result<()> {
7644        trace!("{} rx frm {:?}", self.trace_id, frame);
7645
7646        match frame {
7647            frame::Frame::Padding { .. } => (),
7648
7649            frame::Frame::Ping { .. } => (),
7650
7651            frame::Frame::ACK {
7652                ranges, ack_delay, ..
7653            } => {
7654                let ack_delay = ack_delay
7655                    .checked_mul(2_u64.pow(
7656                        self.peer_transport_params.ack_delay_exponent as u32,
7657                    ))
7658                    .ok_or(Error::InvalidFrame)?;
7659
7660                if epoch == packet::Epoch::Handshake ||
7661                    (epoch == packet::Epoch::Application &&
7662                        self.is_established())
7663                {
7664                    self.peer_verified_initial_address = true;
7665                }
7666
7667                let handshake_status = self.handshake_status();
7668
7669                let is_app_limited = self.delivery_rate_check_if_app_limited();
7670
7671                let largest_acked = ranges.last().expect(
7672                    "ACK frames should always have at least one ack range",
7673                );
7674
7675                for (_, p) in self.paths.iter_mut() {
7676                    if self.pkt_num_spaces[epoch]
7677                        .largest_tx_pkt_num
7678                        .is_some_and(|largest_sent| largest_sent < largest_acked)
7679                    {
7680                        // https://www.rfc-editor.org/rfc/rfc9000#section-13.1
7681                        // An endpoint SHOULD treat receipt of an acknowledgment
7682                        // for a packet it did not send as
7683                        // a connection error of type PROTOCOL_VIOLATION
7684                        return Err(Error::InvalidAckRange);
7685                    }
7686
7687                    if is_app_limited {
7688                        p.recovery.delivery_rate_update_app_limited(true);
7689                    }
7690
7691                    let OnAckReceivedOutcome {
7692                        lost_packets,
7693                        lost_bytes,
7694                        acked_bytes,
7695                        spurious_losses,
7696                    } = p.recovery.on_ack_received(
7697                        &ranges,
7698                        ack_delay,
7699                        epoch,
7700                        handshake_status,
7701                        now,
7702                        self.pkt_num_manager.skip_pn(),
7703                        &self.trace_id,
7704                    )?;
7705
7706                    let skip_pn = self.pkt_num_manager.skip_pn();
7707                    let largest_acked =
7708                        p.recovery.get_largest_acked_on_epoch(epoch);
7709
7710                    // Consider the skip_pn validated if the peer has sent an ack
7711                    // for a larger pkt number.
7712                    if let Some((largest_acked, skip_pn)) =
7713                        largest_acked.zip(skip_pn)
7714                    {
7715                        if largest_acked > skip_pn {
7716                            self.pkt_num_manager.set_skip_pn(None);
7717                        }
7718                    }
7719
7720                    self.lost_count += lost_packets;
7721                    self.lost_bytes += lost_bytes as u64;
7722                    self.acked_bytes += acked_bytes as u64;
7723                    self.spurious_lost_count += spurious_losses;
7724                }
7725            },
7726
7727            frame::Frame::ResetStream {
7728                stream_id,
7729                error_code,
7730                final_size,
7731            } => {
7732                // Peer can't send on our unidirectional streams.
7733                if !stream::is_bidi(stream_id) &&
7734                    stream::is_local(stream_id, self.is_server)
7735                {
7736                    return Err(Error::InvalidStreamState(stream_id));
7737                }
7738
7739                let max_rx_data_left = self.max_rx_data() - self.rx_data;
7740
7741                // Get existing stream or create a new one, but if the stream
7742                // has already been closed and collected, ignore the frame.
7743                //
7744                // This can happen if e.g. an ACK frame is lost, and the peer
7745                // retransmits another frame before it realizes that the stream
7746                // is gone.
7747                //
7748                // Note that it makes it impossible to check if the frame is
7749                // illegal, since we have no state, but since we ignore the
7750                // frame, it should be fine.
7751                let stream = match self.get_or_create_stream(stream_id, false) {
7752                    Ok(v) => v,
7753
7754                    Err(Error::Done) => return Ok(()),
7755
7756                    Err(e) => return Err(e),
7757                };
7758
7759                let was_readable = stream.is_readable();
7760                let priority_key = Arc::clone(&stream.priority_key);
7761
7762                let max_off_delta =
7763                    stream.recv.reset(error_code, final_size)? as u64;
7764
7765                if max_off_delta > max_rx_data_left {
7766                    return Err(Error::FlowControl);
7767                }
7768
7769                if !was_readable && stream.is_readable() {
7770                    self.streams.insert_readable(&priority_key);
7771                }
7772
7773                self.rx_data += max_off_delta;
7774
7775                self.reset_stream_remote_count =
7776                    self.reset_stream_remote_count.saturating_add(1);
7777            },
7778
7779            frame::Frame::StopSending {
7780                stream_id,
7781                error_code,
7782            } => {
7783                // STOP_SENDING on a receive-only stream is a fatal error.
7784                if !stream::is_local(stream_id, self.is_server) &&
7785                    !stream::is_bidi(stream_id)
7786                {
7787                    return Err(Error::InvalidStreamState(stream_id));
7788                }
7789
7790                // Get existing stream or create a new one, but if the stream
7791                // has already been closed and collected, ignore the frame.
7792                //
7793                // This can happen if e.g. an ACK frame is lost, and the peer
7794                // retransmits another frame before it realizes that the stream
7795                // is gone.
7796                //
7797                // Note that it makes it impossible to check if the frame is
7798                // illegal, since we have no state, but since we ignore the
7799                // frame, it should be fine.
7800                let stream = match self.get_or_create_stream(stream_id, false) {
7801                    Ok(v) => v,
7802
7803                    Err(Error::Done) => return Ok(()),
7804
7805                    Err(e) => return Err(e),
7806                };
7807
7808                let was_writable = stream.is_writable();
7809
7810                let priority_key = Arc::clone(&stream.priority_key);
7811
7812                // Try stopping the stream.
7813                if let Ok((final_size, unsent)) = stream.send.stop(error_code) {
7814                    // Claw back some flow control allowance from data that was
7815                    // buffered but not actually sent before the stream was
7816                    // reset.
7817                    //
7818                    // Note that `tx_cap` will be updated later on, so no need
7819                    // to touch it here.
7820                    self.tx_data = self.tx_data.saturating_sub(unsent);
7821
7822                    self.tx_buffered =
7823                        self.tx_buffered.saturating_sub(unsent as usize);
7824
7825                    self.streams.insert_reset(stream_id, error_code, final_size);
7826
7827                    if !was_writable {
7828                        self.streams.insert_writable(&priority_key);
7829                    }
7830
7831                    self.stopped_stream_remote_count =
7832                        self.stopped_stream_remote_count.saturating_add(1);
7833                    self.reset_stream_local_count =
7834                        self.reset_stream_local_count.saturating_add(1);
7835                }
7836            },
7837
7838            frame::Frame::Crypto { data } => {
7839                if data.max_off() >= MAX_CRYPTO_STREAM_OFFSET {
7840                    return Err(Error::CryptoBufferExceeded);
7841                }
7842
7843                // Push the data to the stream so it can be re-ordered.
7844                self.crypto_ctx[epoch].crypto_stream.recv.write(data)?;
7845
7846                // Feed crypto data to the TLS state, if there's data
7847                // available at the expected offset.
7848                let mut crypto_buf = [0; 512];
7849
7850                let level = crypto::Level::from_epoch(epoch);
7851
7852                let stream = &mut self.crypto_ctx[epoch].crypto_stream;
7853
7854                while let Ok((read, _)) = stream.recv.emit(&mut crypto_buf) {
7855                    let recv_buf = &crypto_buf[..read];
7856                    self.handshake.provide_data(level, recv_buf)?;
7857                }
7858
7859                self.do_handshake(now)?;
7860            },
7861
7862            frame::Frame::CryptoHeader { .. } => unreachable!(),
7863
7864            // TODO: implement stateless retry
7865            frame::Frame::NewToken { .. } =>
7866                if self.is_server {
7867                    return Err(Error::InvalidPacket);
7868                },
7869
7870            frame::Frame::Stream { stream_id, data } => {
7871                // Peer can't send on our unidirectional streams.
7872                if !stream::is_bidi(stream_id) &&
7873                    stream::is_local(stream_id, self.is_server)
7874                {
7875                    return Err(Error::InvalidStreamState(stream_id));
7876                }
7877
7878                let max_rx_data_left = self.max_rx_data() - self.rx_data;
7879
7880                // Get existing stream or create a new one, but if the stream
7881                // has already been closed and collected, ignore the frame.
7882                //
7883                // This can happen if e.g. an ACK frame is lost, and the peer
7884                // retransmits another frame before it realizes that the stream
7885                // is gone.
7886                //
7887                // Note that it makes it impossible to check if the frame is
7888                // illegal, since we have no state, but since we ignore the
7889                // frame, it should be fine.
7890                let stream = match self.get_or_create_stream(stream_id, false) {
7891                    Ok(v) => v,
7892
7893                    Err(Error::Done) => return Ok(()),
7894
7895                    Err(e) => return Err(e),
7896                };
7897
7898                // Check for the connection-level flow control limit.
7899                let max_off_delta =
7900                    data.max_off().saturating_sub(stream.recv.max_off());
7901
7902                if max_off_delta > max_rx_data_left {
7903                    return Err(Error::FlowControl);
7904                }
7905
7906                let was_readable = stream.is_readable();
7907                let priority_key = Arc::clone(&stream.priority_key);
7908
7909                let was_draining = stream.recv.is_draining();
7910
7911                stream.recv.write(data)?;
7912
7913                if !was_readable && stream.is_readable() {
7914                    self.streams.insert_readable(&priority_key);
7915                }
7916
7917                self.rx_data += max_off_delta;
7918
7919                if was_draining {
7920                    // When a stream is in draining state it will not queue
7921                    // incoming data for the application to read, so consider
7922                    // the received data as consumed, which might trigger a flow
7923                    // control update.
7924                    self.flow_control.add_consumed(max_off_delta);
7925
7926                    if self.should_update_max_data() {
7927                        self.almost_full = true;
7928                    }
7929                }
7930            },
7931
7932            frame::Frame::StreamHeader { .. } => unreachable!(),
7933
7934            frame::Frame::MaxData { max } => {
7935                self.max_tx_data = cmp::max(self.max_tx_data, max);
7936            },
7937
7938            frame::Frame::MaxStreamData { stream_id, max } => {
7939                // Peer can't receive on its own unidirectional streams.
7940                if !stream::is_bidi(stream_id) &&
7941                    !stream::is_local(stream_id, self.is_server)
7942                {
7943                    return Err(Error::InvalidStreamState(stream_id));
7944                }
7945
7946                // Get existing stream or create a new one, but if the stream
7947                // has already been closed and collected, ignore the frame.
7948                //
7949                // This can happen if e.g. an ACK frame is lost, and the peer
7950                // retransmits another frame before it realizes that the stream
7951                // is gone.
7952                //
7953                // Note that it makes it impossible to check if the frame is
7954                // illegal, since we have no state, but since we ignore the
7955                // frame, it should be fine.
7956                let stream = match self.get_or_create_stream(stream_id, false) {
7957                    Ok(v) => v,
7958
7959                    Err(Error::Done) => return Ok(()),
7960
7961                    Err(e) => return Err(e),
7962                };
7963
7964                let was_flushable = stream.is_flushable();
7965
7966                stream.send.update_max_data(max);
7967
7968                let writable = stream.is_writable();
7969
7970                let priority_key = Arc::clone(&stream.priority_key);
7971
7972                // If the stream is now flushable push it to the flushable queue,
7973                // but only if it wasn't already queued.
7974                if stream.is_flushable() && !was_flushable {
7975                    let priority_key = Arc::clone(&stream.priority_key);
7976                    self.streams.insert_flushable(&priority_key);
7977                }
7978
7979                if writable {
7980                    self.streams.insert_writable(&priority_key);
7981                }
7982            },
7983
7984            frame::Frame::MaxStreamsBidi { max } => {
7985                if max > MAX_STREAM_ID {
7986                    return Err(Error::InvalidFrame);
7987                }
7988
7989                self.streams.update_peer_max_streams_bidi(max);
7990            },
7991
7992            frame::Frame::MaxStreamsUni { max } => {
7993                if max > MAX_STREAM_ID {
7994                    return Err(Error::InvalidFrame);
7995                }
7996
7997                self.streams.update_peer_max_streams_uni(max);
7998            },
7999
8000            frame::Frame::DataBlocked { .. } => (),
8001
8002            frame::Frame::StreamDataBlocked { .. } => (),
8003
8004            frame::Frame::StreamsBlockedBidi { limit } => {
8005                if limit > MAX_STREAM_ID {
8006                    return Err(Error::InvalidFrame);
8007                }
8008            },
8009
8010            frame::Frame::StreamsBlockedUni { limit } => {
8011                if limit > MAX_STREAM_ID {
8012                    return Err(Error::InvalidFrame);
8013                }
8014            },
8015
8016            frame::Frame::NewConnectionId {
8017                seq_num,
8018                retire_prior_to,
8019                conn_id,
8020                reset_token,
8021            } => {
8022                if self.ids.zero_length_dcid() {
8023                    return Err(Error::InvalidState);
8024                }
8025
8026                let mut retired_path_ids = SmallVec::new();
8027
8028                // Retire pending path IDs before propagating the error code to
8029                // make sure retired connection IDs are not in use anymore.
8030                let new_dcid_res = self.ids.new_dcid(
8031                    conn_id.into(),
8032                    seq_num,
8033                    u128::from_be_bytes(reset_token),
8034                    retire_prior_to,
8035                    &mut retired_path_ids,
8036                );
8037
8038                for (dcid_seq, pid) in retired_path_ids {
8039                    let path = self.paths.get_mut(pid)?;
8040
8041                    // Maybe the path already switched to another DCID.
8042                    if path.active_dcid_seq != Some(dcid_seq) {
8043                        continue;
8044                    }
8045
8046                    if let Some(new_dcid_seq) =
8047                        self.ids.lowest_available_dcid_seq()
8048                    {
8049                        path.active_dcid_seq = Some(new_dcid_seq);
8050
8051                        self.ids.link_dcid_to_path_id(new_dcid_seq, pid)?;
8052
8053                        trace!(
8054                            "{} path ID {} changed DCID: old seq num {} new seq num {}",
8055                            self.trace_id, pid, dcid_seq, new_dcid_seq,
8056                        );
8057                    } else {
8058                        // We cannot use this path anymore for now.
8059                        path.active_dcid_seq = None;
8060
8061                        trace!(
8062                            "{} path ID {} cannot be used; DCID seq num {} has been retired",
8063                            self.trace_id, pid, dcid_seq,
8064                        );
8065                    }
8066                }
8067
8068                // Propagate error (if any) now...
8069                new_dcid_res?;
8070            },
8071
8072            frame::Frame::RetireConnectionId { seq_num } => {
8073                if self.ids.zero_length_scid() {
8074                    return Err(Error::InvalidState);
8075                }
8076
8077                if let Some(pid) = self.ids.retire_scid(seq_num, &hdr.dcid)? {
8078                    let path = self.paths.get_mut(pid)?;
8079
8080                    // Maybe we already linked a new SCID to that path.
8081                    if path.active_scid_seq == Some(seq_num) {
8082                        // XXX: We do not remove unused paths now, we instead
8083                        // wait until we need to maintain more paths than the
8084                        // host is willing to.
8085                        path.active_scid_seq = None;
8086                    }
8087                }
8088            },
8089
8090            frame::Frame::PathChallenge { data } => {
8091                self.path_challenge_rx_count += 1;
8092
8093                self.paths
8094                    .get_mut(recv_path_id)?
8095                    .on_challenge_received(data);
8096            },
8097
8098            frame::Frame::PathResponse { data } => {
8099                self.paths.on_response_received(data)?;
8100            },
8101
8102            frame::Frame::ConnectionClose {
8103                error_code, reason, ..
8104            } => {
8105                self.peer_error = Some(ConnectionError {
8106                    is_app: false,
8107                    error_code,
8108                    reason,
8109                });
8110
8111                let path = self.paths.get_active()?;
8112                self.draining_timer = Some(now + (path.recovery.pto() * 3));
8113            },
8114
8115            frame::Frame::ApplicationClose { error_code, reason } => {
8116                self.peer_error = Some(ConnectionError {
8117                    is_app: true,
8118                    error_code,
8119                    reason,
8120                });
8121
8122                let path = self.paths.get_active()?;
8123                self.draining_timer = Some(now + (path.recovery.pto() * 3));
8124            },
8125
8126            frame::Frame::HandshakeDone => {
8127                if self.is_server {
8128                    return Err(Error::InvalidPacket);
8129                }
8130
8131                self.peer_verified_initial_address = true;
8132
8133                self.handshake_confirmed = true;
8134
8135                // Once the handshake is confirmed, we can drop Handshake keys.
8136                self.drop_epoch_state(packet::Epoch::Handshake, now);
8137            },
8138
8139            frame::Frame::Datagram { data } => {
8140                // Close the connection if DATAGRAMs are not enabled.
8141                // quiche always advertises support for 64K sized DATAGRAM
8142                // frames, as recommended by the standard, so we don't need a
8143                // size check.
8144                if !self.dgram_enabled() {
8145                    return Err(Error::InvalidState);
8146                }
8147
8148                // If recv queue is full, discard oldest
8149                if self.dgram_recv_queue.is_full() {
8150                    self.dgram_recv_queue.pop();
8151                }
8152
8153                self.dgram_recv_queue.push(data)?;
8154
8155                let _ = self.dgram_recv_count.saturating_add(1);
8156                let _ = self
8157                    .paths
8158                    .get_mut(recv_path_id)?
8159                    .dgram_recv_count
8160                    .saturating_add(1);
8161            },
8162
8163            frame::Frame::DatagramHeader { .. } => unreachable!(),
8164        }
8165
8166        Ok(())
8167    }
8168
8169    /// Drops the keys and recovery state for the given epoch.
8170    fn drop_epoch_state(&mut self, epoch: packet::Epoch, now: Instant) {
8171        let crypto_ctx = &mut self.crypto_ctx[epoch];
8172        if crypto_ctx.crypto_open.is_none() {
8173            return;
8174        }
8175        crypto_ctx.clear();
8176        self.pkt_num_spaces[epoch].clear();
8177
8178        let handshake_status = self.handshake_status();
8179        for (_, p) in self.paths.iter_mut() {
8180            p.recovery
8181                .on_pkt_num_space_discarded(epoch, handshake_status, now);
8182        }
8183
8184        trace!("{} dropped epoch {} state", self.trace_id, epoch);
8185    }
8186
8187    /// Returns true if the connection-level flow control needs to be updated.
8188    ///
8189    /// This happens when the new max data limit is at least double the amount
8190    /// of data that can be received before blocking.
8191    fn should_update_max_data(&self) -> bool {
8192        self.flow_control.should_update_max_data()
8193    }
8194
8195    /// Returns the connection level flow control limit.
8196    fn max_rx_data(&self) -> u64 {
8197        self.flow_control.max_data()
8198    }
8199
8200    /// Returns true if the HANDSHAKE_DONE frame needs to be sent.
8201    fn should_send_handshake_done(&self) -> bool {
8202        self.is_established() && !self.handshake_done_sent && self.is_server
8203    }
8204
8205    /// Returns the idle timeout value.
8206    ///
8207    /// `None` is returned if both end-points disabled the idle timeout.
8208    fn idle_timeout(&self) -> Option<Duration> {
8209        // If the transport parameter is set to 0, then the respective endpoint
8210        // decided to disable the idle timeout. If both are disabled we should
8211        // not set any timeout.
8212        if self.local_transport_params.max_idle_timeout == 0 &&
8213            self.peer_transport_params.max_idle_timeout == 0
8214        {
8215            return None;
8216        }
8217
8218        // If the local endpoint or the peer disabled the idle timeout, use the
8219        // other peer's value, otherwise use the minimum of the two values.
8220        let idle_timeout = if self.local_transport_params.max_idle_timeout == 0 {
8221            self.peer_transport_params.max_idle_timeout
8222        } else if self.peer_transport_params.max_idle_timeout == 0 {
8223            self.local_transport_params.max_idle_timeout
8224        } else {
8225            cmp::min(
8226                self.local_transport_params.max_idle_timeout,
8227                self.peer_transport_params.max_idle_timeout,
8228            )
8229        };
8230
8231        let path_pto = match self.paths.get_active() {
8232            Ok(p) => p.recovery.pto(),
8233            Err(_) => Duration::ZERO,
8234        };
8235
8236        let idle_timeout = Duration::from_millis(idle_timeout);
8237        let idle_timeout = cmp::max(idle_timeout, 3 * path_pto);
8238
8239        Some(idle_timeout)
8240    }
8241
8242    /// Returns the connection's handshake status for use in loss recovery.
8243    fn handshake_status(&self) -> recovery::HandshakeStatus {
8244        recovery::HandshakeStatus {
8245            has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
8246                .has_keys(),
8247
8248            peer_verified_address: self.peer_verified_initial_address,
8249
8250            completed: self.is_established(),
8251        }
8252    }
8253
8254    /// Updates send capacity.
8255    fn update_tx_cap(&mut self) {
8256        let cwin_available = match self.paths.get_active() {
8257            Ok(p) => p.recovery.cwnd_available() as u64,
8258            Err(_) => 0,
8259        };
8260
8261        let cap =
8262            cmp::min(cwin_available, self.max_tx_data - self.tx_data) as usize;
8263        self.tx_cap = (cap as f64 * self.tx_cap_factor).ceil() as usize;
8264    }
8265
8266    fn delivery_rate_check_if_app_limited(&self) -> bool {
8267        // Enter the app-limited phase of delivery rate when these conditions
8268        // are met:
8269        //
8270        // - The remaining capacity is higher than available bytes in cwnd (there
8271        //   is more room to send).
8272        // - New data since the last send() is smaller than available bytes in
8273        //   cwnd (we queued less than what we can send).
8274        // - There is room to send more data in cwnd.
8275        //
8276        // In application-limited phases the transmission rate is limited by the
8277        // application rather than the congestion control algorithm.
8278        //
8279        // Note that this is equivalent to CheckIfApplicationLimited() from the
8280        // delivery rate draft. This is also separate from `recovery.app_limited`
8281        // and only applies to delivery rate calculation.
8282        let cwin_available = self
8283            .paths
8284            .iter()
8285            .filter(|&(_, p)| p.active())
8286            .map(|(_, p)| p.recovery.cwnd_available())
8287            .sum();
8288
8289        ((self.tx_buffered + self.dgram_send_queue_byte_size()) < cwin_available) &&
8290            (self.tx_data.saturating_sub(self.last_tx_data)) <
8291                cwin_available as u64 &&
8292            cwin_available > 0
8293    }
8294
8295    fn set_initial_dcid(
8296        &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
8297        path_id: usize,
8298    ) -> Result<()> {
8299        self.ids.set_initial_dcid(cid, reset_token, Some(path_id));
8300        self.paths.get_mut(path_id)?.active_dcid_seq = Some(0);
8301
8302        Ok(())
8303    }
8304
8305    /// Selects the path that the incoming packet belongs to, or creates a new
8306    /// one if no existing path matches.
8307    fn get_or_create_recv_path_id(
8308        &mut self, recv_pid: Option<usize>, dcid: &ConnectionId, buf_len: usize,
8309        info: &RecvInfo,
8310    ) -> Result<usize> {
8311        let ids = &mut self.ids;
8312
8313        let (in_scid_seq, mut in_scid_pid) =
8314            ids.find_scid_seq(dcid).ok_or(Error::InvalidState)?;
8315
8316        if let Some(recv_pid) = recv_pid {
8317            // If the path observes a change of SCID used, note it.
8318            let recv_path = self.paths.get_mut(recv_pid)?;
8319
8320            let cid_entry =
8321                recv_path.active_scid_seq.and_then(|v| ids.get_scid(v).ok());
8322
8323            if cid_entry.map(|e| &e.cid) != Some(dcid) {
8324                let incoming_cid_entry = ids.get_scid(in_scid_seq)?;
8325
8326                let prev_recv_pid =
8327                    incoming_cid_entry.path_id.unwrap_or(recv_pid);
8328
8329                if prev_recv_pid != recv_pid {
8330                    trace!(
8331                        "{} peer reused CID {:?} from path {} on path {}",
8332                        self.trace_id,
8333                        dcid,
8334                        prev_recv_pid,
8335                        recv_pid
8336                    );
8337
8338                    // TODO: reset congestion control.
8339                }
8340
8341                trace!(
8342                    "{} path ID {} now see SCID with seq num {}",
8343                    self.trace_id,
8344                    recv_pid,
8345                    in_scid_seq
8346                );
8347
8348                recv_path.active_scid_seq = Some(in_scid_seq);
8349                ids.link_scid_to_path_id(in_scid_seq, recv_pid)?;
8350            }
8351
8352            return Ok(recv_pid);
8353        }
8354
8355        // This is a new 4-tuple. See if the CID has not been assigned on
8356        // another path.
8357
8358        // Ignore this step if are using zero-length SCID.
8359        if ids.zero_length_scid() {
8360            in_scid_pid = None;
8361        }
8362
8363        if let Some(in_scid_pid) = in_scid_pid {
8364            // This CID has been used by another path. If we have the
8365            // room to do so, create a new `Path` structure holding this
8366            // new 4-tuple. Otherwise, drop the packet.
8367            let old_path = self.paths.get_mut(in_scid_pid)?;
8368            let old_local_addr = old_path.local_addr();
8369            let old_peer_addr = old_path.peer_addr();
8370
8371            trace!(
8372                "{} reused CID seq {} of ({},{}) (path {}) on ({},{})",
8373                self.trace_id,
8374                in_scid_seq,
8375                old_local_addr,
8376                old_peer_addr,
8377                in_scid_pid,
8378                info.to,
8379                info.from
8380            );
8381
8382            // Notify the application.
8383            self.paths.notify_event(PathEvent::ReusedSourceConnectionId(
8384                in_scid_seq,
8385                (old_local_addr, old_peer_addr),
8386                (info.to, info.from),
8387            ));
8388        }
8389
8390        // This is a new path using an unassigned CID; create it!
8391        let mut path = path::Path::new(
8392            info.to,
8393            info.from,
8394            &self.recovery_config,
8395            self.path_challenge_recv_max_queue_len,
8396            false,
8397            None,
8398        );
8399
8400        path.max_send_bytes = buf_len * self.max_amplification_factor;
8401        path.active_scid_seq = Some(in_scid_seq);
8402
8403        // Automatically probes the new path.
8404        path.request_validation();
8405
8406        let pid = self.paths.insert_path(path, self.is_server)?;
8407
8408        // Do not record path reuse.
8409        if in_scid_pid.is_none() {
8410            ids.link_scid_to_path_id(in_scid_seq, pid)?;
8411        }
8412
8413        Ok(pid)
8414    }
8415
8416    /// Selects the path on which the next packet must be sent.
8417    fn get_send_path_id(
8418        &self, from: Option<SocketAddr>, to: Option<SocketAddr>,
8419    ) -> Result<usize> {
8420        // A probing packet must be sent, but only if the connection is fully
8421        // established.
8422        if self.is_established() {
8423            let mut probing = self
8424                .paths
8425                .iter()
8426                .filter(|(_, p)| from.is_none() || Some(p.local_addr()) == from)
8427                .filter(|(_, p)| to.is_none() || Some(p.peer_addr()) == to)
8428                .filter(|(_, p)| p.active_dcid_seq.is_some())
8429                .filter(|(_, p)| p.probing_required())
8430                .map(|(pid, _)| pid);
8431
8432            if let Some(pid) = probing.next() {
8433                return Ok(pid);
8434            }
8435        }
8436
8437        if let Some((pid, p)) = self.paths.get_active_with_pid() {
8438            if from.is_some() && Some(p.local_addr()) != from {
8439                return Err(Error::Done);
8440            }
8441
8442            if to.is_some() && Some(p.peer_addr()) != to {
8443                return Err(Error::Done);
8444            }
8445
8446            return Ok(pid);
8447        };
8448
8449        Err(Error::InvalidState)
8450    }
8451
8452    /// Sets the path with identifier 'path_id' to be active.
8453    fn set_active_path(&mut self, path_id: usize, now: Instant) -> Result<()> {
8454        if let Ok(old_active_path) = self.paths.get_active_mut() {
8455            for &e in packet::Epoch::epochs(
8456                packet::Epoch::Initial..=packet::Epoch::Application,
8457            ) {
8458                let (lost_packets, lost_bytes) = old_active_path
8459                    .recovery
8460                    .on_path_change(e, now, &self.trace_id);
8461
8462                self.lost_count += lost_packets;
8463                self.lost_bytes += lost_bytes as u64;
8464            }
8465        }
8466
8467        self.paths.set_active_path(path_id)
8468    }
8469
8470    /// Handles potential connection migration.
8471    fn on_peer_migrated(
8472        &mut self, new_pid: usize, disable_dcid_reuse: bool, now: Instant,
8473    ) -> Result<()> {
8474        let active_path_id = self.paths.get_active_path_id()?;
8475
8476        if active_path_id == new_pid {
8477            return Ok(());
8478        }
8479
8480        self.set_active_path(new_pid, now)?;
8481
8482        let no_spare_dcid =
8483            self.paths.get_mut(new_pid)?.active_dcid_seq.is_none();
8484
8485        if no_spare_dcid && !disable_dcid_reuse {
8486            self.paths.get_mut(new_pid)?.active_dcid_seq =
8487                self.paths.get_mut(active_path_id)?.active_dcid_seq;
8488        }
8489
8490        Ok(())
8491    }
8492
8493    /// Creates a new client-side path.
8494    fn create_path_on_client(
8495        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
8496    ) -> Result<usize> {
8497        if self.is_server {
8498            return Err(Error::InvalidState);
8499        }
8500
8501        // If we use zero-length SCID and go over our local active CID limit,
8502        // the `insert_path()` call will raise an error.
8503        if !self.ids.zero_length_scid() && self.ids.available_scids() == 0 {
8504            return Err(Error::OutOfIdentifiers);
8505        }
8506
8507        // Do we have a spare DCID? If we are using zero-length DCID, just use
8508        // the default having sequence 0 (note that if we exceed our local CID
8509        // limit, the `insert_path()` call will raise an error.
8510        let dcid_seq = if self.ids.zero_length_dcid() {
8511            0
8512        } else {
8513            self.ids
8514                .lowest_available_dcid_seq()
8515                .ok_or(Error::OutOfIdentifiers)?
8516        };
8517
8518        let mut path = path::Path::new(
8519            local_addr,
8520            peer_addr,
8521            &self.recovery_config,
8522            self.path_challenge_recv_max_queue_len,
8523            false,
8524            None,
8525        );
8526        path.active_dcid_seq = Some(dcid_seq);
8527
8528        let pid = self
8529            .paths
8530            .insert_path(path, false)
8531            .map_err(|_| Error::OutOfIdentifiers)?;
8532        self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
8533
8534        Ok(pid)
8535    }
8536
8537    // Marks the connection as closed and does any related tidyup.
8538    fn mark_closed(&mut self) {
8539        #[cfg(feature = "qlog")]
8540        {
8541            let cc = match (self.is_established(), self.timed_out, &self.peer_error, &self.local_error) {
8542                (false, _, _, _) => qlog::events::connectivity::ConnectionClosed {
8543                    owner: Some(TransportOwner::Local),
8544                    connection_code: None,
8545                    application_code: None,
8546                    internal_code: None,
8547                    reason: Some("Failed to establish connection".to_string()),
8548                    trigger: Some(qlog::events::connectivity::ConnectionClosedTrigger::HandshakeTimeout)
8549                },
8550
8551                (true, true, _, _) => qlog::events::connectivity::ConnectionClosed {
8552                    owner: Some(TransportOwner::Local),
8553                    connection_code: None,
8554                    application_code: None,
8555                    internal_code: None,
8556                    reason: Some("Idle timeout".to_string()),
8557                    trigger: Some(qlog::events::connectivity::ConnectionClosedTrigger::IdleTimeout)
8558                },
8559
8560                (true, false, Some(peer_error), None) => {
8561                    let (connection_code, application_code, trigger) = if peer_error.is_app {
8562                        (None, Some(qlog::events::ApplicationErrorCode::Value(peer_error.error_code)), None)
8563                    } else {
8564                        let trigger = if peer_error.error_code == WireErrorCode::NoError as u64 {
8565                            Some(qlog::events::connectivity::ConnectionClosedTrigger::Clean)
8566                        } else {
8567                            Some(qlog::events::connectivity::ConnectionClosedTrigger::Error)
8568                        };
8569
8570                        (Some(qlog::events::ConnectionErrorCode::Value(peer_error.error_code)), None, trigger)
8571                    };
8572
8573                    qlog::events::connectivity::ConnectionClosed {
8574                        owner: Some(TransportOwner::Remote),
8575                        connection_code,
8576                        application_code,
8577                        internal_code: None,
8578                        reason: Some(String::from_utf8_lossy(&peer_error.reason).to_string()),
8579                        trigger,
8580                    }
8581                },
8582
8583                (true, false, None, Some(local_error)) => {
8584                    let (connection_code, application_code, trigger) = if local_error.is_app {
8585                        (None, Some(qlog::events::ApplicationErrorCode::Value(local_error.error_code)), None)
8586                    } else {
8587                        let trigger = if local_error.error_code == WireErrorCode::NoError as u64 {
8588                            Some(qlog::events::connectivity::ConnectionClosedTrigger::Clean)
8589                        } else {
8590                            Some(qlog::events::connectivity::ConnectionClosedTrigger::Error)
8591                        };
8592
8593                        (Some(qlog::events::ConnectionErrorCode::Value(local_error.error_code)), None, trigger)
8594                    };
8595
8596                    qlog::events::connectivity::ConnectionClosed {
8597                        owner: Some(TransportOwner::Local),
8598                        connection_code,
8599                        application_code,
8600                        internal_code: None,
8601                        reason: Some(String::from_utf8_lossy(&local_error.reason).to_string()),
8602                        trigger,
8603                    }
8604                },
8605
8606                _ => qlog::events::connectivity::ConnectionClosed {
8607                    owner: None,
8608                    connection_code: None,
8609                    application_code: None,
8610                    internal_code: None,
8611                    reason: None,
8612                    trigger: None,
8613                },
8614            };
8615
8616            qlog_with_type!(QLOG_CONNECTION_CLOSED, self.qlog, q, {
8617                let ev_data = EventData::ConnectionClosed(cc);
8618
8619                q.add_event_data_now(ev_data).ok();
8620            });
8621            self.qlog.streamer = None;
8622        }
8623        self.closed = true;
8624    }
8625}
8626
8627#[cfg(feature = "boringssl-boring-crate")]
8628impl<F: BufFactory> AsMut<boring::ssl::SslRef> for Connection<F> {
8629    fn as_mut(&mut self) -> &mut boring::ssl::SslRef {
8630        self.handshake.ssl_mut()
8631    }
8632}
8633
8634/// Maps an `Error` to `Error::Done`, or itself.
8635///
8636/// When a received packet that hasn't yet been authenticated triggers a failure
8637/// it should, in most cases, be ignored, instead of raising a connection error,
8638/// to avoid potential man-in-the-middle and man-on-the-side attacks.
8639///
8640/// However, if no other packet was previously received, the connection should
8641/// indeed be closed as the received packet might just be network background
8642/// noise, and it shouldn't keep resources occupied indefinitely.
8643///
8644/// This function maps an error to `Error::Done` to ignore a packet failure
8645/// without aborting the connection, except when no other packet was previously
8646/// received, in which case the error itself is returned, but only on the
8647/// server-side as the client will already have armed the idle timer.
8648///
8649/// This must only be used for errors preceding packet authentication. Failures
8650/// happening after a packet has been authenticated should still cause the
8651/// connection to be aborted.
8652fn drop_pkt_on_err(
8653    e: Error, recv_count: usize, is_server: bool, trace_id: &str,
8654) -> Error {
8655    // On the server, if no other packet has been successfully processed, abort
8656    // the connection to avoid keeping the connection open when only junk is
8657    // received.
8658    if is_server && recv_count == 0 {
8659        return e;
8660    }
8661
8662    trace!("{trace_id} dropped invalid packet");
8663
8664    // Ignore other invalid packets that haven't been authenticated to prevent
8665    // man-in-the-middle and man-on-the-side attacks.
8666    Error::Done
8667}
8668
8669struct AddrTupleFmt(SocketAddr, SocketAddr);
8670
8671impl std::fmt::Display for AddrTupleFmt {
8672    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
8673        let AddrTupleFmt(src, dst) = &self;
8674
8675        if src.ip().is_unspecified() || dst.ip().is_unspecified() {
8676            return Ok(());
8677        }
8678
8679        f.write_fmt(format_args!("src:{src} dst:{dst}"))
8680    }
8681}
8682
8683/// Statistics about the connection.
8684///
8685/// A connection's statistics can be collected using the [`stats()`] method.
8686///
8687/// [`stats()`]: struct.Connection.html#method.stats
8688#[derive(Clone, Default)]
8689pub struct Stats {
8690    /// The number of QUIC packets received.
8691    pub recv: usize,
8692
8693    /// The number of QUIC packets sent.
8694    pub sent: usize,
8695
8696    /// The number of QUIC packets that were lost.
8697    pub lost: usize,
8698
8699    /// The number of QUIC packets that were marked as lost but later acked.
8700    pub spurious_lost: usize,
8701
8702    /// The number of sent QUIC packets with retransmitted data.
8703    pub retrans: usize,
8704
8705    /// The number of sent bytes.
8706    pub sent_bytes: u64,
8707
8708    /// The number of received bytes.
8709    pub recv_bytes: u64,
8710
8711    /// The number of bytes sent acked.
8712    pub acked_bytes: u64,
8713
8714    /// The number of bytes sent lost.
8715    pub lost_bytes: u64,
8716
8717    /// The number of stream bytes retransmitted.
8718    pub stream_retrans_bytes: u64,
8719
8720    /// The number of DATAGRAM frames received.
8721    pub dgram_recv: usize,
8722
8723    /// The number of DATAGRAM frames sent.
8724    pub dgram_sent: usize,
8725
8726    /// The number of known paths for the connection.
8727    pub paths_count: usize,
8728
8729    /// The number of streams reset by local.
8730    pub reset_stream_count_local: u64,
8731
8732    /// The number of streams stopped by local.
8733    pub stopped_stream_count_local: u64,
8734
8735    /// The number of streams reset by remote.
8736    pub reset_stream_count_remote: u64,
8737
8738    /// The number of streams stopped by remote.
8739    pub stopped_stream_count_remote: u64,
8740
8741    /// The total number of PATH_CHALLENGE frames that were received.
8742    pub path_challenge_rx_count: u64,
8743
8744    /// Total duration during which this side of the connection was
8745    /// actively sending bytes or waiting for those bytes to be acked.
8746    pub bytes_in_flight_duration: Duration,
8747}
8748
8749impl std::fmt::Debug for Stats {
8750    #[inline]
8751    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
8752        write!(
8753            f,
8754            "recv={} sent={} lost={} retrans={}",
8755            self.recv, self.sent, self.lost, self.retrans,
8756        )?;
8757
8758        write!(
8759            f,
8760            " sent_bytes={} recv_bytes={} lost_bytes={}",
8761            self.sent_bytes, self.recv_bytes, self.lost_bytes,
8762        )?;
8763
8764        Ok(())
8765    }
8766}
8767
8768/// QUIC Unknown Transport Parameter.
8769///
8770/// A QUIC transport parameter that is not specifically recognized
8771/// by this implementation.
8772#[derive(Clone, Debug, PartialEq)]
8773pub struct UnknownTransportParameter<T> {
8774    /// The ID of the unknown transport parameter.
8775    pub id: u64,
8776
8777    /// Original data representing the value of the unknown transport parameter.
8778    pub value: T,
8779}
8780
8781impl<T> UnknownTransportParameter<T> {
8782    /// Checks whether an unknown Transport Parameter's ID is in the reserved
8783    /// space.
8784    ///
8785    /// See Section 18.1 in [RFC9000](https://datatracker.ietf.org/doc/html/rfc9000#name-reserved-transport-paramete).
8786    pub fn is_reserved(&self) -> bool {
8787        let n = (self.id - 27) / 31;
8788        self.id == 31 * n + 27
8789    }
8790}
8791
8792#[cfg(feature = "qlog")]
8793impl From<UnknownTransportParameter<Vec<u8>>>
8794    for qlog::events::quic::UnknownTransportParameter
8795{
8796    fn from(value: UnknownTransportParameter<Vec<u8>>) -> Self {
8797        Self {
8798            id: value.id,
8799            value: qlog::HexSlice::maybe_string(Some(value.value.as_slice()))
8800                .unwrap_or_default(),
8801        }
8802    }
8803}
8804
8805impl From<UnknownTransportParameter<&[u8]>>
8806    for UnknownTransportParameter<Vec<u8>>
8807{
8808    // When an instance of an UnknownTransportParameter is actually
8809    // stored in UnknownTransportParameters, then we make a copy
8810    // of the bytes if the source is an instance of an UnknownTransportParameter
8811    // whose value is not owned.
8812    fn from(value: UnknownTransportParameter<&[u8]>) -> Self {
8813        Self {
8814            id: value.id,
8815            value: value.value.to_vec(),
8816        }
8817    }
8818}
8819
8820/// Track unknown transport parameters, up to a limit.
8821#[derive(Clone, Debug, PartialEq, Default)]
8822pub struct UnknownTransportParameters {
8823    /// The space remaining for storing unknown transport parameters.
8824    pub capacity: usize,
8825    /// The unknown transport parameters.
8826    pub parameters: Vec<UnknownTransportParameter<Vec<u8>>>,
8827}
8828
8829impl UnknownTransportParameters {
8830    /// Pushes an unknown transport parameter into storage if there is space
8831    /// remaining.
8832    pub fn push(&mut self, new: UnknownTransportParameter<&[u8]>) -> Result<()> {
8833        let new_unknown_tp_size = new.value.len() + size_of::<u64>();
8834        if new_unknown_tp_size < self.capacity {
8835            self.capacity -= new_unknown_tp_size;
8836            self.parameters.push(new.into());
8837            Ok(())
8838        } else {
8839            Err(octets::BufferTooShortError.into())
8840        }
8841    }
8842}
8843
8844/// An Iterator over unknown transport parameters.
8845pub struct UnknownTransportParameterIterator<'a> {
8846    index: usize,
8847    parameters: &'a Vec<UnknownTransportParameter<Vec<u8>>>,
8848}
8849
8850impl<'a> IntoIterator for &'a UnknownTransportParameters {
8851    type IntoIter = UnknownTransportParameterIterator<'a>;
8852    type Item = &'a UnknownTransportParameter<Vec<u8>>;
8853
8854    fn into_iter(self) -> Self::IntoIter {
8855        UnknownTransportParameterIterator {
8856            index: 0,
8857            parameters: &self.parameters,
8858        }
8859    }
8860}
8861
8862impl<'a> Iterator for UnknownTransportParameterIterator<'a> {
8863    type Item = &'a UnknownTransportParameter<Vec<u8>>;
8864
8865    fn next(&mut self) -> Option<Self::Item> {
8866        let result = self.parameters.get(self.index);
8867        self.index += 1;
8868        result
8869    }
8870}
8871
8872/// QUIC Transport Parameters
8873#[derive(Clone, Debug, PartialEq)]
8874pub struct TransportParams {
8875    /// Value of Destination CID field from first Initial packet sent by client
8876    pub original_destination_connection_id: Option<ConnectionId<'static>>,
8877    /// The maximum idle timeout.
8878    pub max_idle_timeout: u64,
8879    /// Token used for verifying stateless resets
8880    pub stateless_reset_token: Option<u128>,
8881    /// The maximum UDP payload size.
8882    pub max_udp_payload_size: u64,
8883    /// The initial flow control maximum data for the connection.
8884    pub initial_max_data: u64,
8885    /// The initial flow control maximum data for local bidirectional streams.
8886    pub initial_max_stream_data_bidi_local: u64,
8887    /// The initial flow control maximum data for remote bidirectional streams.
8888    pub initial_max_stream_data_bidi_remote: u64,
8889    /// The initial flow control maximum data for unidirectional streams.
8890    pub initial_max_stream_data_uni: u64,
8891    /// The initial maximum bidirectional streams.
8892    pub initial_max_streams_bidi: u64,
8893    /// The initial maximum unidirectional streams.
8894    pub initial_max_streams_uni: u64,
8895    /// The ACK delay exponent.
8896    pub ack_delay_exponent: u64,
8897    /// The max ACK delay.
8898    pub max_ack_delay: u64,
8899    /// Whether active migration is disabled.
8900    pub disable_active_migration: bool,
8901    /// The active connection ID limit.
8902    pub active_conn_id_limit: u64,
8903    /// The value that the endpoint included in the Source CID field of a Retry
8904    /// Packet.
8905    pub initial_source_connection_id: Option<ConnectionId<'static>>,
8906    /// The value that the server included in the Source CID field of a Retry
8907    /// Packet.
8908    pub retry_source_connection_id: Option<ConnectionId<'static>>,
8909    /// DATAGRAM frame extension parameter, if any.
8910    pub max_datagram_frame_size: Option<u64>,
8911    /// Unknown peer transport parameters and values, if any.
8912    pub unknown_params: Option<UnknownTransportParameters>,
8913    // pub preferred_address: ...,
8914}
8915
8916impl Default for TransportParams {
8917    fn default() -> TransportParams {
8918        TransportParams {
8919            original_destination_connection_id: None,
8920            max_idle_timeout: 0,
8921            stateless_reset_token: None,
8922            max_udp_payload_size: 65527,
8923            initial_max_data: 0,
8924            initial_max_stream_data_bidi_local: 0,
8925            initial_max_stream_data_bidi_remote: 0,
8926            initial_max_stream_data_uni: 0,
8927            initial_max_streams_bidi: 0,
8928            initial_max_streams_uni: 0,
8929            ack_delay_exponent: 3,
8930            max_ack_delay: 25,
8931            disable_active_migration: false,
8932            active_conn_id_limit: 2,
8933            initial_source_connection_id: None,
8934            retry_source_connection_id: None,
8935            max_datagram_frame_size: None,
8936            unknown_params: Default::default(),
8937        }
8938    }
8939}
8940
8941impl TransportParams {
8942    fn decode(
8943        buf: &[u8], is_server: bool, unknown_size: Option<usize>,
8944    ) -> Result<TransportParams> {
8945        let mut params = octets::Octets::with_slice(buf);
8946        let mut seen_params = HashSet::new();
8947
8948        let mut tp = TransportParams::default();
8949
8950        if let Some(unknown_transport_param_tracking_size) = unknown_size {
8951            tp.unknown_params = Some(UnknownTransportParameters {
8952                capacity: unknown_transport_param_tracking_size,
8953                parameters: vec![],
8954            });
8955        }
8956
8957        while params.cap() > 0 {
8958            let id = params.get_varint()?;
8959
8960            if seen_params.contains(&id) {
8961                return Err(Error::InvalidTransportParam);
8962            }
8963            seen_params.insert(id);
8964
8965            let mut val = params.get_bytes_with_varint_length()?;
8966
8967            match id {
8968                0x0000 => {
8969                    if is_server {
8970                        return Err(Error::InvalidTransportParam);
8971                    }
8972
8973                    tp.original_destination_connection_id =
8974                        Some(val.to_vec().into());
8975                },
8976
8977                0x0001 => {
8978                    tp.max_idle_timeout = val.get_varint()?;
8979                },
8980
8981                0x0002 => {
8982                    if is_server {
8983                        return Err(Error::InvalidTransportParam);
8984                    }
8985
8986                    tp.stateless_reset_token = Some(u128::from_be_bytes(
8987                        val.get_bytes(16)?
8988                            .to_vec()
8989                            .try_into()
8990                            .map_err(|_| Error::BufferTooShort)?,
8991                    ));
8992                },
8993
8994                0x0003 => {
8995                    tp.max_udp_payload_size = val.get_varint()?;
8996
8997                    if tp.max_udp_payload_size < 1200 {
8998                        return Err(Error::InvalidTransportParam);
8999                    }
9000                },
9001
9002                0x0004 => {
9003                    tp.initial_max_data = val.get_varint()?;
9004                },
9005
9006                0x0005 => {
9007                    tp.initial_max_stream_data_bidi_local = val.get_varint()?;
9008                },
9009
9010                0x0006 => {
9011                    tp.initial_max_stream_data_bidi_remote = val.get_varint()?;
9012                },
9013
9014                0x0007 => {
9015                    tp.initial_max_stream_data_uni = val.get_varint()?;
9016                },
9017
9018                0x0008 => {
9019                    let max = val.get_varint()?;
9020
9021                    if max > MAX_STREAM_ID {
9022                        return Err(Error::InvalidTransportParam);
9023                    }
9024
9025                    tp.initial_max_streams_bidi = max;
9026                },
9027
9028                0x0009 => {
9029                    let max = val.get_varint()?;
9030
9031                    if max > MAX_STREAM_ID {
9032                        return Err(Error::InvalidTransportParam);
9033                    }
9034
9035                    tp.initial_max_streams_uni = max;
9036                },
9037
9038                0x000a => {
9039                    let ack_delay_exponent = val.get_varint()?;
9040
9041                    if ack_delay_exponent > 20 {
9042                        return Err(Error::InvalidTransportParam);
9043                    }
9044
9045                    tp.ack_delay_exponent = ack_delay_exponent;
9046                },
9047
9048                0x000b => {
9049                    let max_ack_delay = val.get_varint()?;
9050
9051                    if max_ack_delay >= 2_u64.pow(14) {
9052                        return Err(Error::InvalidTransportParam);
9053                    }
9054
9055                    tp.max_ack_delay = max_ack_delay;
9056                },
9057
9058                0x000c => {
9059                    tp.disable_active_migration = true;
9060                },
9061
9062                0x000d => {
9063                    if is_server {
9064                        return Err(Error::InvalidTransportParam);
9065                    }
9066
9067                    // TODO: decode preferred_address
9068                },
9069
9070                0x000e => {
9071                    let limit = val.get_varint()?;
9072
9073                    if limit < 2 {
9074                        return Err(Error::InvalidTransportParam);
9075                    }
9076
9077                    tp.active_conn_id_limit = limit;
9078                },
9079
9080                0x000f => {
9081                    tp.initial_source_connection_id = Some(val.to_vec().into());
9082                },
9083
9084                0x00010 => {
9085                    if is_server {
9086                        return Err(Error::InvalidTransportParam);
9087                    }
9088
9089                    tp.retry_source_connection_id = Some(val.to_vec().into());
9090                },
9091
9092                0x0020 => {
9093                    tp.max_datagram_frame_size = Some(val.get_varint()?);
9094                },
9095
9096                // Track unknown transport parameters specially.
9097                unknown_tp_id => {
9098                    if let Some(unknown_params) = &mut tp.unknown_params {
9099                        // It is _not_ an error not to have space enough to track
9100                        // an unknown parameter.
9101                        let _ = unknown_params.push(UnknownTransportParameter {
9102                            id: unknown_tp_id,
9103                            value: val.buf(),
9104                        });
9105                    }
9106                },
9107            }
9108        }
9109
9110        Ok(tp)
9111    }
9112
9113    fn encode_param(
9114        b: &mut octets::OctetsMut, ty: u64, len: usize,
9115    ) -> Result<()> {
9116        b.put_varint(ty)?;
9117        b.put_varint(len as u64)?;
9118
9119        Ok(())
9120    }
9121
9122    fn encode<'a>(
9123        tp: &TransportParams, is_server: bool, out: &'a mut [u8],
9124    ) -> Result<&'a mut [u8]> {
9125        let mut b = octets::OctetsMut::with_slice(out);
9126
9127        if is_server {
9128            if let Some(ref odcid) = tp.original_destination_connection_id {
9129                TransportParams::encode_param(&mut b, 0x0000, odcid.len())?;
9130                b.put_bytes(odcid)?;
9131            }
9132        };
9133
9134        if tp.max_idle_timeout != 0 {
9135            assert!(tp.max_idle_timeout <= octets::MAX_VAR_INT);
9136            TransportParams::encode_param(
9137                &mut b,
9138                0x0001,
9139                octets::varint_len(tp.max_idle_timeout),
9140            )?;
9141            b.put_varint(tp.max_idle_timeout)?;
9142        }
9143
9144        if is_server {
9145            if let Some(ref token) = tp.stateless_reset_token {
9146                TransportParams::encode_param(&mut b, 0x0002, 16)?;
9147                b.put_bytes(&token.to_be_bytes())?;
9148            }
9149        }
9150
9151        if tp.max_udp_payload_size != 0 {
9152            assert!(tp.max_udp_payload_size <= octets::MAX_VAR_INT);
9153            TransportParams::encode_param(
9154                &mut b,
9155                0x0003,
9156                octets::varint_len(tp.max_udp_payload_size),
9157            )?;
9158            b.put_varint(tp.max_udp_payload_size)?;
9159        }
9160
9161        if tp.initial_max_data != 0 {
9162            assert!(tp.initial_max_data <= octets::MAX_VAR_INT);
9163            TransportParams::encode_param(
9164                &mut b,
9165                0x0004,
9166                octets::varint_len(tp.initial_max_data),
9167            )?;
9168            b.put_varint(tp.initial_max_data)?;
9169        }
9170
9171        if tp.initial_max_stream_data_bidi_local != 0 {
9172            assert!(tp.initial_max_stream_data_bidi_local <= octets::MAX_VAR_INT);
9173            TransportParams::encode_param(
9174                &mut b,
9175                0x0005,
9176                octets::varint_len(tp.initial_max_stream_data_bidi_local),
9177            )?;
9178            b.put_varint(tp.initial_max_stream_data_bidi_local)?;
9179        }
9180
9181        if tp.initial_max_stream_data_bidi_remote != 0 {
9182            assert!(
9183                tp.initial_max_stream_data_bidi_remote <= octets::MAX_VAR_INT
9184            );
9185            TransportParams::encode_param(
9186                &mut b,
9187                0x0006,
9188                octets::varint_len(tp.initial_max_stream_data_bidi_remote),
9189            )?;
9190            b.put_varint(tp.initial_max_stream_data_bidi_remote)?;
9191        }
9192
9193        if tp.initial_max_stream_data_uni != 0 {
9194            assert!(tp.initial_max_stream_data_uni <= octets::MAX_VAR_INT);
9195            TransportParams::encode_param(
9196                &mut b,
9197                0x0007,
9198                octets::varint_len(tp.initial_max_stream_data_uni),
9199            )?;
9200            b.put_varint(tp.initial_max_stream_data_uni)?;
9201        }
9202
9203        if tp.initial_max_streams_bidi != 0 {
9204            assert!(tp.initial_max_streams_bidi <= octets::MAX_VAR_INT);
9205            TransportParams::encode_param(
9206                &mut b,
9207                0x0008,
9208                octets::varint_len(tp.initial_max_streams_bidi),
9209            )?;
9210            b.put_varint(tp.initial_max_streams_bidi)?;
9211        }
9212
9213        if tp.initial_max_streams_uni != 0 {
9214            assert!(tp.initial_max_streams_uni <= octets::MAX_VAR_INT);
9215            TransportParams::encode_param(
9216                &mut b,
9217                0x0009,
9218                octets::varint_len(tp.initial_max_streams_uni),
9219            )?;
9220            b.put_varint(tp.initial_max_streams_uni)?;
9221        }
9222
9223        if tp.ack_delay_exponent != 0 {
9224            assert!(tp.ack_delay_exponent <= octets::MAX_VAR_INT);
9225            TransportParams::encode_param(
9226                &mut b,
9227                0x000a,
9228                octets::varint_len(tp.ack_delay_exponent),
9229            )?;
9230            b.put_varint(tp.ack_delay_exponent)?;
9231        }
9232
9233        if tp.max_ack_delay != 0 {
9234            assert!(tp.max_ack_delay <= octets::MAX_VAR_INT);
9235            TransportParams::encode_param(
9236                &mut b,
9237                0x000b,
9238                octets::varint_len(tp.max_ack_delay),
9239            )?;
9240            b.put_varint(tp.max_ack_delay)?;
9241        }
9242
9243        if tp.disable_active_migration {
9244            TransportParams::encode_param(&mut b, 0x000c, 0)?;
9245        }
9246
9247        // TODO: encode preferred_address
9248
9249        if tp.active_conn_id_limit != 2 {
9250            assert!(tp.active_conn_id_limit <= octets::MAX_VAR_INT);
9251            TransportParams::encode_param(
9252                &mut b,
9253                0x000e,
9254                octets::varint_len(tp.active_conn_id_limit),
9255            )?;
9256            b.put_varint(tp.active_conn_id_limit)?;
9257        }
9258
9259        if let Some(scid) = &tp.initial_source_connection_id {
9260            TransportParams::encode_param(&mut b, 0x000f, scid.len())?;
9261            b.put_bytes(scid)?;
9262        }
9263
9264        if is_server {
9265            if let Some(scid) = &tp.retry_source_connection_id {
9266                TransportParams::encode_param(&mut b, 0x0010, scid.len())?;
9267                b.put_bytes(scid)?;
9268            }
9269        }
9270
9271        if let Some(max_datagram_frame_size) = tp.max_datagram_frame_size {
9272            assert!(max_datagram_frame_size <= octets::MAX_VAR_INT);
9273            TransportParams::encode_param(
9274                &mut b,
9275                0x0020,
9276                octets::varint_len(max_datagram_frame_size),
9277            )?;
9278            b.put_varint(max_datagram_frame_size)?;
9279        }
9280
9281        let out_len = b.off();
9282
9283        Ok(&mut out[..out_len])
9284    }
9285
9286    /// Creates a qlog event for connection transport parameters and TLS fields
9287    #[cfg(feature = "qlog")]
9288    pub fn to_qlog(
9289        &self, owner: TransportOwner, cipher: Option<crypto::Algorithm>,
9290    ) -> EventData {
9291        let original_destination_connection_id = qlog::HexSlice::maybe_string(
9292            self.original_destination_connection_id.as_ref(),
9293        );
9294
9295        let stateless_reset_token = qlog::HexSlice::maybe_string(
9296            self.stateless_reset_token.map(|s| s.to_be_bytes()).as_ref(),
9297        );
9298
9299        let tls_cipher: Option<String> = cipher.map(|f| format!("{f:?}"));
9300
9301        EventData::TransportParametersSet(
9302            qlog::events::quic::TransportParametersSet {
9303                owner: Some(owner),
9304                tls_cipher,
9305                original_destination_connection_id,
9306                stateless_reset_token,
9307                disable_active_migration: Some(self.disable_active_migration),
9308                max_idle_timeout: Some(self.max_idle_timeout),
9309                max_udp_payload_size: Some(self.max_udp_payload_size as u32),
9310                ack_delay_exponent: Some(self.ack_delay_exponent as u16),
9311                max_ack_delay: Some(self.max_ack_delay as u16),
9312                active_connection_id_limit: Some(
9313                    self.active_conn_id_limit as u32,
9314                ),
9315
9316                initial_max_data: Some(self.initial_max_data),
9317                initial_max_stream_data_bidi_local: Some(
9318                    self.initial_max_stream_data_bidi_local,
9319                ),
9320                initial_max_stream_data_bidi_remote: Some(
9321                    self.initial_max_stream_data_bidi_remote,
9322                ),
9323                initial_max_stream_data_uni: Some(
9324                    self.initial_max_stream_data_uni,
9325                ),
9326                initial_max_streams_bidi: Some(self.initial_max_streams_bidi),
9327                initial_max_streams_uni: Some(self.initial_max_streams_uni),
9328
9329                unknown_parameters: self
9330                    .unknown_params
9331                    .as_ref()
9332                    .map(|unknown_params| {
9333                        unknown_params
9334                            .into_iter()
9335                            .cloned()
9336                            .map(
9337                                Into::<
9338                                    qlog::events::quic::UnknownTransportParameter,
9339                                >::into,
9340                            )
9341                            .collect()
9342                    })
9343                    .unwrap_or_default(),
9344
9345                ..Default::default()
9346            },
9347        )
9348    }
9349}
9350
9351#[doc(hidden)]
9352pub mod test_utils;
9353
9354#[cfg(test)]
9355mod tests;
9356
9357pub use crate::packet::ConnectionId;
9358pub use crate::packet::Header;
9359pub use crate::packet::Type;
9360
9361pub use crate::path::PathEvent;
9362pub use crate::path::PathStats;
9363pub use crate::path::SocketAddrIter;
9364
9365pub use crate::recovery::BbrBwLoReductionStrategy;
9366pub use crate::recovery::BbrParams;
9367pub use crate::recovery::CongestionControlAlgorithm;
9368pub use crate::recovery::StartupExit;
9369pub use crate::recovery::StartupExitReason;
9370
9371pub use crate::stream::StreamIter;
9372
9373pub use crate::range_buf::BufFactory;
9374pub use crate::range_buf::BufSplit;
9375
9376mod cid;
9377mod crypto;
9378mod dgram;
9379#[cfg(feature = "ffi")]
9380mod ffi;
9381mod flowcontrol;
9382mod frame;
9383pub mod h3;
9384mod minmax;
9385mod packet;
9386mod path;
9387mod pmtud;
9388mod rand;
9389mod range_buf;
9390mod ranges;
9391mod recovery;
9392mod stream;
9393mod tls;