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