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