Skip to main content

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