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