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