Skip to main content

quiche/
lib.rs

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