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