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 retransmitted =
4285                            stream.send.retransmit(offset, length);
4286
4287                        if fin {
4288                            stream.send.retransmit_fin();
4289                        }
4290
4291                        // If the stream is now flushable push it to the
4292                        // flushable queue, but only if it wasn't already
4293                        // queued.
4294                        if stream.is_flushable() && !was_flushable {
4295                            let priority_key = Arc::clone(&stream.priority_key);
4296                            self.streams.insert_flushable(&priority_key);
4297                        }
4298
4299                        // Update tx_buffered when data is marked for
4300                        // retransmission (it was decremented when emitted).
4301                        // Only increment by the actual amount retransmitted,
4302                        // which may be less than `length` if some data was
4303                        // already acked.
4304                        self.streams.add_tx_buffered(retransmitted);
4305
4306                        self.stream_retrans_bytes += length as u64;
4307                        p.stream_retrans_bytes += length as u64;
4308
4309                        self.retrans_count += 1;
4310                        p.retrans_count += 1;
4311                    },
4312
4313                    frame::Frame::ACK { .. } => {
4314                        pkt_space.ack_elicited = true;
4315                    },
4316
4317                    frame::Frame::ResetStream {
4318                        stream_id,
4319                        error_code,
4320                        final_size,
4321                    } => {
4322                        self.streams
4323                            .insert_reset(stream_id, error_code, final_size);
4324                    },
4325
4326                    frame::Frame::StopSending {
4327                        stream_id,
4328                        error_code,
4329                    } =>
4330                    // We only need to retransmit the STOP_SENDING frame if
4331                    // the stream is still active and not FIN'd. Even if the
4332                    // packet was lost, if the application has the final
4333                    // size at this point there is no need to retransmit.
4334                        if let Some(stream) = self.streams.get(stream_id) {
4335                            if !stream.recv.is_fin() {
4336                                self.streams
4337                                    .insert_stopped(stream_id, error_code);
4338                            }
4339                        },
4340
4341                    // Retransmit HANDSHAKE_DONE only if it hasn't been acked at
4342                    // least once already.
4343                    frame::Frame::HandshakeDone =>
4344                        if !self.handshake_done_acked {
4345                            self.handshake_done_sent = false;
4346                        },
4347
4348                    frame::Frame::MaxStreamData { stream_id, .. } => {
4349                        if self.streams.get(stream_id).is_some() {
4350                            self.streams.insert_almost_full(stream_id);
4351                        }
4352                    },
4353
4354                    frame::Frame::MaxData { .. } => {
4355                        self.should_send_max_data = true;
4356                    },
4357
4358                    frame::Frame::MaxStreamsUni { .. } => {
4359                        self.should_send_max_streams_uni = true;
4360                    },
4361
4362                    frame::Frame::MaxStreamsBidi { .. } => {
4363                        self.should_send_max_streams_bidi = true;
4364                    },
4365
4366                    // Retransmit STREAMS_BLOCKED frames if the frame with the
4367                    // most recent limit is lost.  These are informational
4368                    // signals to the peer, reliably sending them
4369                    // ensures the signal is used consistently and helps
4370                    // debugging.
4371                    frame::Frame::StreamsBlockedBidi { limit } => {
4372                        self.streams_blocked_bidi_state
4373                            .force_retransmit_sent_limit_eq(limit);
4374                    },
4375
4376                    frame::Frame::StreamsBlockedUni { limit } => {
4377                        self.streams_blocked_uni_state
4378                            .force_retransmit_sent_limit_eq(limit);
4379                    },
4380
4381                    frame::Frame::NewConnectionId { seq_num, .. } => {
4382                        self.ids.mark_advertise_new_scid_seq(seq_num, true);
4383                    },
4384
4385                    frame::Frame::RetireConnectionId { seq_num } => {
4386                        self.ids.mark_retire_dcid_seq(seq_num, true)?;
4387                    },
4388
4389                    frame::Frame::Ping { mtu_probe } => {
4390                        // Ping frames are not retransmitted.
4391                        if let Some(failed_probe) = mtu_probe {
4392                            trace!("pmtud probe dropped: {failed_probe}");
4393
4394                            let local = p.local_addr();
4395                            let peer = p.peer_addr();
4396                            if let Some(pmtud) = p.pmtud.as_mut() {
4397                                let old_pmtu = pmtud.get_current_mtu();
4398                                pmtud.failed_probe(failed_probe);
4399                                let new_pmtu = pmtud.get_current_mtu();
4400
4401                                if let Some(event) = path::pmtu_event(
4402                                    local, peer, old_pmtu, new_pmtu,
4403                                ) {
4404                                    p.recovery
4405                                        .pmtud_update_max_datagram_size(new_pmtu);
4406                                    path_events.push_back(event);
4407                                }
4408                            }
4409                        }
4410                    },
4411
4412                    // Sent as StreamHeader frames. Stream frames are never
4413                    // generated by quiche.
4414                    frame::Frame::Stream { .. } => {
4415                        debug_panic!(
4416                            "Unexpected frame lost: Stream. quiche should \
4417                             have tracked retransmittable stream data as \
4418                             StreamHeader frames."
4419                        );
4420                    },
4421
4422                    // Sent as CryptoHeader frames. Crypto frames are never
4423                    // generated by quiche.
4424                    frame::Frame::Crypto { .. } => {
4425                        debug_panic!(
4426                            "Unexpected frame lost: Crypto. quiche should \
4427                             have tracked retransmittable crypto data as \
4428                             CryptoHeader frames."
4429                        );
4430                    },
4431
4432                    // NewToken frames are never sent by quiche; they are not
4433                    // implemented.
4434                    frame::Frame::NewToken { .. } => {
4435                        debug_panic!(
4436                            "Unexpected frame lost: NewToken. quiche used to \
4437                             not implement NewToken frames, retransmission of \
4438                             these frames is not implemented."
4439                        );
4440                    },
4441
4442                    // Data blocked frames are an optional advisory
4443                    // signal. We choose to not retransmit them to
4444                    // avoid unnecessary network usage.
4445                    frame::Frame::DataBlocked { .. } |
4446                    frame::Frame::StreamDataBlocked { .. } => (),
4447
4448                    // Path challenge and response have their own
4449                    // retry logic. They should not be retransmitted
4450                    // normally since according to RFC 9000 Section
4451                    // 8.2.2: "An endpoint MUST NOT send more than one
4452                    // PATH_RESPONSE frame in response to one
4453                    // PATH_CHALLENGE frame".
4454                    frame::Frame::PathChallenge { .. } |
4455                    frame::Frame::PathResponse { .. } => (),
4456
4457                    // From RFC 9000 Section 13.3: CONNECTION_CLOSE
4458                    // frames, are not sent again when packet loss is
4459                    // detected. Resending these signals is described
4460                    // in Section 10.
4461                    frame::Frame::ConnectionClose { .. } |
4462                    frame::Frame::ApplicationClose { .. } => (),
4463
4464                    // Padding doesn't require retransmission.
4465                    frame::Frame::Padding { .. } => (),
4466
4467                    frame::Frame::DatagramHeader { .. } |
4468                    frame::Frame::Datagram { .. } => {
4469                        // Datagrams do not require retransmission.  Just update
4470                        // stats.
4471                        p.dgram_lost_count = p.dgram_lost_count.saturating_add(1);
4472                    },
4473                    // IMPORTANT: Do not add an exhaustive catch
4474                    // all. We want to add explicit handling for frame
4475                    // types that can be safely ignored when lost.
4476                }
4477            }
4478        }
4479
4480        #[cfg(debug_assertions)]
4481        self.streams.debug_check_tx_buffered_consistency();
4482
4483        let is_app_limited = self.delivery_rate_check_if_app_limited();
4484        let n_paths = self.paths.len();
4485        let path = self.paths.get_mut(send_pid)?;
4486        let flow_control = &mut self.flow_control;
4487        let pkt_space = &mut self.pkt_num_spaces[epoch];
4488        let crypto_ctx = &mut self.crypto_ctx[epoch];
4489        let pkt_num_manager = &mut self.pkt_num_manager;
4490
4491        let mut left = if let Some(pmtud) = path.pmtud.as_mut() {
4492            // Limit output buffer size by estimated path MTU.
4493            cmp::min(pmtud.get_current_mtu(), b.cap())
4494        } else {
4495            b.cap()
4496        };
4497
4498        if pkt_num_manager.should_skip_pn(self.handshake_completed) {
4499            pkt_num_manager.set_skip_pn(Some(self.next_pkt_num));
4500            self.next_pkt_num += 1;
4501        };
4502        let pn = self.next_pkt_num;
4503
4504        let largest_acked_pkt =
4505            path.recovery.get_largest_acked_on_epoch(epoch).unwrap_or(0);
4506        let pn_len = packet::pkt_num_len(pn, largest_acked_pkt);
4507
4508        // The AEAD overhead at the current encryption level.
4509        let crypto_overhead = crypto_ctx.crypto_overhead().ok_or(Error::Done)?;
4510
4511        let dcid_seq = path.active_dcid_seq.ok_or(Error::OutOfIdentifiers)?;
4512
4513        let dcid =
4514            ConnectionId::from_ref(self.ids.get_dcid(dcid_seq)?.cid.as_ref());
4515
4516        let scid = if let Some(scid_seq) = path.active_scid_seq {
4517            ConnectionId::from_ref(self.ids.get_scid(scid_seq)?.cid.as_ref())
4518        } else if pkt_type == Type::Short {
4519            ConnectionId::default()
4520        } else {
4521            return Err(Error::InvalidState);
4522        };
4523
4524        let hdr = Header {
4525            ty: pkt_type,
4526
4527            version: self.version,
4528
4529            dcid,
4530            scid,
4531
4532            pkt_num: 0,
4533            pkt_num_len: pn_len,
4534
4535            // Only clone token for Initial packets, as other packets don't have
4536            // this field (Retry doesn't count, as it's not encoded as part of
4537            // this code path).
4538            token: if pkt_type == Type::Initial {
4539                self.token.clone()
4540            } else {
4541                None
4542            },
4543
4544            versions: None,
4545            key_phase: self.key_phase,
4546        };
4547
4548        hdr.to_bytes(&mut b)?;
4549
4550        let hdr_trace = if log::max_level() == log::LevelFilter::Trace {
4551            Some(format!("{hdr:?}"))
4552        } else {
4553            None
4554        };
4555
4556        let hdr_ty = hdr.ty;
4557
4558        #[cfg(feature = "qlog")]
4559        let qlog_pkt_hdr = self.qlog.streamer.as_ref().map(|_q| {
4560            qlog::events::quic::PacketHeader::with_type(
4561                hdr.ty.to_qlog(),
4562                Some(pn),
4563                Some(hdr.version),
4564                Some(&hdr.scid),
4565                Some(&hdr.dcid),
4566            )
4567        });
4568
4569        // Calculate the space required for the packet, including the header
4570        // the payload length, the packet number and the AEAD overhead.
4571        let mut overhead = b.off() + pn_len + crypto_overhead;
4572
4573        // We assume that the payload length, which is only present in long
4574        // header packets, can always be encoded with a 2-byte varint.
4575        if pkt_type != Type::Short {
4576            overhead += PAYLOAD_LENGTH_LEN;
4577        }
4578
4579        // Make sure we have enough space left for the packet overhead.
4580        match left.checked_sub(overhead) {
4581            Some(v) => left = v,
4582
4583            None => {
4584                // We can't send more because there isn't enough space available
4585                // in the output buffer.
4586                //
4587                // This usually happens when we try to send a new packet but
4588                // failed because cwnd is almost full. In such case app_limited
4589                // is set to false here to make cwnd grow when ACK is received.
4590                path.recovery.update_app_limited(false);
4591                return Err(Error::Done);
4592            },
4593        }
4594
4595        // Make sure there is enough space for the minimum payload length.
4596        if left < PAYLOAD_MIN_LEN {
4597            path.recovery.update_app_limited(false);
4598            return Err(Error::Done);
4599        }
4600
4601        let mut frames: SmallVec<[frame::Frame; 1]> = SmallVec::new();
4602
4603        let mut ack_eliciting = false;
4604        let mut in_flight = false;
4605        let mut is_pmtud_probe = false;
4606        let mut has_data = false;
4607        let mut stream_data_skipped = false;
4608
4609        // Whether a PING frame must explicitly elicit an ACK when no other
4610        // frame does so implicitly.
4611        let ack_elicit_required =
4612            !is_closing && path.recovery.should_elicit_ack(epoch);
4613
4614        let header_offset = b.off();
4615
4616        // Reserve space for payload length in advance. Since we don't yet know
4617        // what the final length will be, we reserve 2 bytes in all cases.
4618        //
4619        // Only long header packets have an explicit length field.
4620        if pkt_type != Type::Short {
4621            b.skip(PAYLOAD_LENGTH_LEN)?;
4622        }
4623
4624        packet::encode_pkt_num(pn, pn_len, &mut b)?;
4625
4626        let payload_offset = b.off();
4627
4628        // `usize::MAX` bypasses cwnd when authorized by packet selection;
4629        // `left` still bounds the packet. Keep this local so other cwnd users
4630        // see the actual window.
4631        let send_limit_from_cwnd = if bypass_cwnd {
4632            usize::MAX
4633        } else {
4634            path.recovery.cwnd_available()
4635        }
4636        .saturating_sub(overhead);
4637
4638        let left_before_packing_ack_frame = left;
4639
4640        // Create ACK frame.
4641        //
4642        // When we need to explicitly elicit an ACK via PING later, go ahead and
4643        // generate an ACK (if there's anything to ACK) since we're going to
4644        // send a packet with PING anyways, even if we haven't received anything
4645        // ACK eliciting.
4646        //
4647        // While closing, PING frames are suppressed, so ACK elicitation must
4648        // not generate ACK-only packets.
4649        if pkt_space.recv_pkt_need_ack.len() > 0 &&
4650            (pkt_space.ack_elicited || ack_elicit_required) &&
4651            (!is_closing ||
4652                (pkt_type == Type::Handshake &&
4653                    self.local_error
4654                        .as_ref()
4655                        .is_some_and(|le| le.is_app))) &&
4656            path.active()
4657        {
4658            #[cfg(not(feature = "fuzzing"))]
4659            let ack_delay = pkt_space.largest_rx_pkt_time.elapsed();
4660
4661            #[cfg(not(feature = "fuzzing"))]
4662            let ack_delay = ack_delay.as_micros() as u64 /
4663                2_u64
4664                    .pow(self.local_transport_params.ack_delay_exponent as u32);
4665
4666            // pseudo-random reproducible ack delays when fuzzing
4667            #[cfg(feature = "fuzzing")]
4668            let ack_delay = rand::rand_u8() as u64 + 1;
4669
4670            let frame = frame::Frame::ACK {
4671                ack_delay,
4672                ranges: pkt_space.recv_pkt_need_ack.clone(),
4673                ecn_counts: None, // sending ECN is not supported at this time
4674            };
4675
4676            // When a PING frame needs to be sent, avoid sending the ACK if
4677            // there is not enough cwnd available for both (note that PING
4678            // frames are always 1 byte, so we just need to check that the
4679            // ACK's length is lower than cwnd).
4680            if pkt_space.ack_elicited || frame.wire_len() < send_limit_from_cwnd {
4681                // ACK-only packets are not congestion controlled so ACKs must
4682                // be bundled considering the buffer capacity only, and not the
4683                // available cwnd.
4684                if push_frame_to_pkt!(b, frames, frame, left) {
4685                    pkt_space.ack_elicited = false;
4686                }
4687            }
4688        }
4689
4690        // Limit output packet size by congestion window size.
4691        left = cmp::min(
4692            left,
4693            // Bytes consumed by ACK frames.
4694            send_limit_from_cwnd
4695                .saturating_sub(left_before_packing_ack_frame - left),
4696        );
4697
4698        let mut challenge_data = None;
4699
4700        if pkt_type == Type::Short {
4701            // Create PMTUD probe.
4702            //
4703            // A PMTUD probe must ignore `left`, which is already limited by the
4704            // current PMTU. The probe remains limited by the output buffer and
4705            // congestion window.
4706            //
4707            // Generate PMTUD probes only after handshake confirmation to avoid
4708            // interference from anti-amplification limits.
4709            if let Ok(active_path) = self.paths.get_active_mut() {
4710                let should_probe_pmtu = active_path.should_send_pmtu_probe(
4711                    self.handshake_confirmed,
4712                    self.handshake_completed,
4713                    out_len,
4714                    is_closing,
4715                    frames.is_empty(),
4716                );
4717
4718                if should_probe_pmtu {
4719                    if let Some(pmtud) = active_path.pmtud.as_mut() {
4720                        let probe_size = pmtud.get_probe_size();
4721                        trace!(
4722                        "{} sending pmtud probe pmtu_probe={} estimated_pmtu={}",
4723                        self.trace_id,
4724                        probe_size,
4725                        pmtud.get_current_mtu(),
4726                    );
4727
4728                        left = probe_size;
4729
4730                        match left.checked_sub(overhead) {
4731                            Some(v) => left = v,
4732
4733                            None => {
4734                                // We can't send more because there isn't enough
4735                                // space available in the output buffer.
4736                                //
4737                                // The congestion window is nearly full. A new
4738                                // packet does not fit.
4739                                //
4740                                // Clear the app-limited state so ACKs can grow
4741                                // the congestion window.
4742                                active_path.recovery.update_app_limited(false);
4743                                return Err(Error::Done);
4744                            },
4745                        }
4746
4747                        let frame = frame::Frame::Padding {
4748                            len: probe_size - overhead - 1,
4749                        };
4750
4751                        if push_frame_to_pkt!(b, frames, frame, left) {
4752                            let frame = frame::Frame::Ping {
4753                                mtu_probe: Some(probe_size),
4754                            };
4755
4756                            if push_frame_to_pkt!(b, frames, frame, left) {
4757                                ack_eliciting = true;
4758                                in_flight = true;
4759                            }
4760                        }
4761
4762                        // Reset probe flag after sending to prevent duplicate
4763                        // probes in a single flight.
4764                        pmtud.set_in_flight(true);
4765                        is_pmtud_probe = true;
4766                    }
4767                }
4768            }
4769
4770            let path = self.paths.get_mut(send_pid)?;
4771            // Create PATH_RESPONSE frame if needed.
4772            // We do not try to ensure that these are really sent.
4773            while let Some(challenge) = path.pop_received_challenge() {
4774                let frame = frame::Frame::PathResponse { data: challenge };
4775
4776                if push_frame_to_pkt!(b, frames, frame, left) {
4777                    ack_eliciting = true;
4778                    in_flight = true;
4779                } else {
4780                    // If there are other pending PATH_RESPONSE, don't lose them
4781                    // now.
4782                    break;
4783                }
4784            }
4785
4786            // Create PATH_CHALLENGE frame if needed.
4787            if path.validation_requested() {
4788                // TODO: ensure that data is unique over paths.
4789                let data = rand::rand_u64().to_be_bytes();
4790
4791                let frame = frame::Frame::PathChallenge { data };
4792
4793                if push_frame_to_pkt!(b, frames, frame, left) {
4794                    // Let's notify the path once we know the packet size.
4795                    challenge_data = Some(data);
4796
4797                    ack_eliciting = true;
4798                    in_flight = true;
4799                }
4800            }
4801
4802            if let Some(key_update) = crypto_ctx.key_update.as_mut() {
4803                key_update.update_acked = true;
4804            }
4805        }
4806
4807        let path = self.paths.get_mut(send_pid)?;
4808
4809        if pkt_type == Type::Short && !is_closing {
4810            // Create NEW_CONNECTION_ID frames as needed.
4811            while let Some(seq_num) = self.ids.next_advertise_new_scid_seq() {
4812                let frame = self.ids.get_new_connection_id_frame_for(seq_num)?;
4813
4814                if push_frame_to_pkt!(b, frames, frame, left) {
4815                    self.ids.mark_advertise_new_scid_seq(seq_num, false);
4816
4817                    ack_eliciting = true;
4818                    in_flight = true;
4819                } else {
4820                    break;
4821                }
4822            }
4823        }
4824
4825        if pkt_type == Type::Short && !is_closing && path.active() {
4826            // Create HANDSHAKE_DONE frame.
4827            // self.should_send_handshake_done() but without the need to borrow
4828            if self.handshake_completed &&
4829                !self.handshake_done_sent &&
4830                self.is_server
4831            {
4832                let frame = frame::Frame::HandshakeDone;
4833
4834                if push_frame_to_pkt!(b, frames, frame, left) {
4835                    self.handshake_done_sent = true;
4836
4837                    ack_eliciting = true;
4838                    in_flight = true;
4839                }
4840            }
4841
4842            // Create MAX_STREAMS_BIDI frame.
4843            if self.streams.should_update_max_streams_bidi() ||
4844                self.should_send_max_streams_bidi
4845            {
4846                let frame = frame::Frame::MaxStreamsBidi {
4847                    max: self.streams.max_streams_bidi_next(),
4848                };
4849
4850                if push_frame_to_pkt!(b, frames, frame, left) {
4851                    self.streams.update_max_streams_bidi();
4852                    self.should_send_max_streams_bidi = false;
4853
4854                    ack_eliciting = true;
4855                    in_flight = true;
4856                }
4857            }
4858
4859            // Create MAX_STREAMS_UNI frame.
4860            if self.streams.should_update_max_streams_uni() ||
4861                self.should_send_max_streams_uni
4862            {
4863                let frame = frame::Frame::MaxStreamsUni {
4864                    max: self.streams.max_streams_uni_next(),
4865                };
4866
4867                if push_frame_to_pkt!(b, frames, frame, left) {
4868                    self.streams.update_max_streams_uni();
4869                    self.should_send_max_streams_uni = false;
4870
4871                    ack_eliciting = true;
4872                    in_flight = true;
4873                }
4874            }
4875
4876            // Create DATA_BLOCKED frame.
4877            if let Some(limit) = self.blocked_limit {
4878                let frame = frame::Frame::DataBlocked { limit };
4879
4880                if push_frame_to_pkt!(b, frames, frame, left) {
4881                    self.blocked_limit = None;
4882                    self.data_blocked_sent_count =
4883                        self.data_blocked_sent_count.saturating_add(1);
4884
4885                    ack_eliciting = true;
4886                    in_flight = true;
4887                }
4888            }
4889
4890            // Create STREAMS_BLOCKED (bidi) frame when the local endpoint has
4891            // exhausted the peer's bidirectional stream count limit.
4892            if self
4893                .streams_blocked_bidi_state
4894                .has_pending_stream_blocked_frame()
4895            {
4896                if let Some(limit) = self.streams_blocked_bidi_state.blocked_at {
4897                    let frame = frame::Frame::StreamsBlockedBidi { limit };
4898
4899                    if push_frame_to_pkt!(b, frames, frame, left) {
4900                        // Record the limit we just notified the peer about so
4901                        // that redundant frames for the same limit are
4902                        // suppressed.
4903                        self.streams_blocked_bidi_state.blocked_sent =
4904                            Some(limit);
4905
4906                        ack_eliciting = true;
4907                        in_flight = true;
4908                    }
4909                }
4910            }
4911
4912            // Create STREAMS_BLOCKED (uni) frame when the local endpoint has
4913            // exhausted the peer's unidirectional stream count limit.
4914            if self
4915                .streams_blocked_uni_state
4916                .has_pending_stream_blocked_frame()
4917            {
4918                if let Some(limit) = self.streams_blocked_uni_state.blocked_at {
4919                    let frame = frame::Frame::StreamsBlockedUni { limit };
4920
4921                    if push_frame_to_pkt!(b, frames, frame, left) {
4922                        // Record the limit we just notified the peer about so
4923                        // that redundant frames for the same limit are
4924                        // suppressed.
4925                        self.streams_blocked_uni_state.blocked_sent = Some(limit);
4926
4927                        ack_eliciting = true;
4928                        in_flight = true;
4929                    }
4930                }
4931            }
4932
4933            // Create MAX_STREAM_DATA frames as needed.
4934            for stream_id in self.streams.almost_full() {
4935                let stream = match self.streams.get_mut(stream_id) {
4936                    Some(v) => v,
4937
4938                    None => {
4939                        // The stream doesn't exist anymore, so remove it from
4940                        // the almost full set.
4941                        self.streams.remove_almost_full(stream_id);
4942                        continue;
4943                    },
4944                };
4945
4946                // Autotune the stream window size, but only if this is not a
4947                // retransmission (on a retransmit the stream will be in
4948                // `self.streams.almost_full()` but it's `almost_full()`
4949                // method returns false.
4950                if stream.recv.almost_full() {
4951                    stream.recv.autotune_window(now, path.recovery.rtt());
4952                }
4953
4954                let frame = frame::Frame::MaxStreamData {
4955                    stream_id,
4956                    max: stream.recv.max_data_next(),
4957                };
4958
4959                if push_frame_to_pkt!(b, frames, frame, left) {
4960                    let recv_win = stream.recv.window();
4961
4962                    stream.recv.update_max_data(now);
4963
4964                    self.streams.remove_almost_full(stream_id);
4965
4966                    ack_eliciting = true;
4967                    in_flight = true;
4968
4969                    // Make sure the connection window always has some
4970                    // room compared to the stream window.
4971                    flow_control.ensure_window_lower_bound(
4972                        (recv_win as f64 * CONNECTION_WINDOW_FACTOR) as u64,
4973                    );
4974                }
4975            }
4976
4977            // Create MAX_DATA frame as needed.
4978            if flow_control.should_update_max_data() &&
4979                flow_control.max_data() < flow_control.max_data_next()
4980            {
4981                // Autotune the connection window size. We only tune the window
4982                // if we are sending an "organic" update, not on retransmits.
4983                flow_control.autotune_window(now, path.recovery.rtt());
4984                self.should_send_max_data = true;
4985            }
4986
4987            if self.should_send_max_data {
4988                let frame = frame::Frame::MaxData {
4989                    max: flow_control.max_data_next(),
4990                };
4991
4992                if push_frame_to_pkt!(b, frames, frame, left) {
4993                    self.should_send_max_data = false;
4994
4995                    // Commits the new max_rx_data limit.
4996                    flow_control.update_max_data(now);
4997
4998                    ack_eliciting = true;
4999                    in_flight = true;
5000                }
5001            }
5002
5003            // Create STOP_SENDING frames as needed.
5004            for (stream_id, error_code) in self
5005                .streams
5006                .stopped()
5007                .map(|(&k, &v)| (k, v))
5008                .collect::<Vec<(u64, u64)>>()
5009            {
5010                let frame = frame::Frame::StopSending {
5011                    stream_id,
5012                    error_code,
5013                };
5014
5015                if push_frame_to_pkt!(b, frames, frame, left) {
5016                    self.streams.remove_stopped(stream_id);
5017
5018                    ack_eliciting = true;
5019                    in_flight = true;
5020                }
5021            }
5022
5023            // Create RESET_STREAM frames as needed.
5024            for (stream_id, (error_code, final_size)) in self
5025                .streams
5026                .reset()
5027                .map(|(&k, &v)| (k, v))
5028                .collect::<Vec<(u64, (u64, u64))>>()
5029            {
5030                let frame = frame::Frame::ResetStream {
5031                    stream_id,
5032                    error_code,
5033                    final_size,
5034                };
5035
5036                if push_frame_to_pkt!(b, frames, frame, left) {
5037                    self.streams.remove_reset(stream_id);
5038
5039                    ack_eliciting = true;
5040                    in_flight = true;
5041                }
5042            }
5043
5044            // Create STREAM_DATA_BLOCKED frames as needed.
5045            for (stream_id, limit) in self
5046                .streams
5047                .blocked()
5048                .map(|(&k, &v)| (k, v))
5049                .collect::<Vec<(u64, u64)>>()
5050            {
5051                let frame = frame::Frame::StreamDataBlocked { stream_id, limit };
5052
5053                if push_frame_to_pkt!(b, frames, frame, left) {
5054                    self.streams.remove_blocked(stream_id);
5055                    self.stream_data_blocked_sent_count =
5056                        self.stream_data_blocked_sent_count.saturating_add(1);
5057
5058                    ack_eliciting = true;
5059                    in_flight = true;
5060                }
5061            }
5062
5063            // Create RETIRE_CONNECTION_ID frames as needed.
5064            let retire_dcid_seqs = self.ids.retire_dcid_seqs();
5065
5066            for seq_num in retire_dcid_seqs {
5067                // The sequence number specified in a RETIRE_CONNECTION_ID frame
5068                // MUST NOT refer to the Destination Connection ID field of the
5069                // packet in which the frame is contained.
5070                let dcid_seq = path.active_dcid_seq.ok_or(Error::InvalidState)?;
5071
5072                if seq_num == dcid_seq {
5073                    continue;
5074                }
5075
5076                let frame = frame::Frame::RetireConnectionId { seq_num };
5077
5078                if push_frame_to_pkt!(b, frames, frame, left) {
5079                    self.ids.mark_retire_dcid_seq(seq_num, false)?;
5080
5081                    ack_eliciting = true;
5082                    in_flight = true;
5083                } else {
5084                    break;
5085                }
5086            }
5087        }
5088
5089        // Create CONNECTION_CLOSE frame. Try to send this only on the active
5090        // path, unless it is the last one available.
5091        if path.active() || n_paths == 1 {
5092            if let Some(conn_err) = self.local_error.as_ref() {
5093                if conn_err.is_app {
5094                    // Create ApplicationClose frame.
5095                    if pkt_type == Type::Short {
5096                        let frame = frame::Frame::ApplicationClose {
5097                            error_code: conn_err.error_code,
5098                            reason: conn_err.reason.clone(),
5099                        };
5100
5101                        if push_frame_to_pkt!(b, frames, frame, left) {
5102                            let pto = path.recovery.pto();
5103                            self.draining_timer = Some(now + (pto * 3));
5104
5105                            ack_eliciting = true;
5106                            in_flight = true;
5107                        }
5108                    }
5109                } else {
5110                    // Create ConnectionClose frame.
5111                    let frame = frame::Frame::ConnectionClose {
5112                        error_code: conn_err.error_code,
5113                        frame_type: 0,
5114                        reason: conn_err.reason.clone(),
5115                    };
5116
5117                    if push_frame_to_pkt!(b, frames, frame, left) {
5118                        let pto = path.recovery.pto();
5119                        self.draining_timer = Some(now + (pto * 3));
5120
5121                        ack_eliciting = true;
5122                        in_flight = true;
5123                    }
5124                }
5125            }
5126        }
5127
5128        // Create CRYPTO frame.
5129        if crypto_ctx.crypto_stream.is_flushable() &&
5130            left > frame::MAX_CRYPTO_OVERHEAD &&
5131            !is_closing &&
5132            path.active()
5133        {
5134            let crypto_off = crypto_ctx.crypto_stream.send.off_front();
5135
5136            // Encode the frame.
5137            //
5138            // Instead of creating a `frame::Frame` object, encode the frame
5139            // directly into the packet buffer.
5140            //
5141            // First we reserve some space in the output buffer for writing the
5142            // frame header (we assume the length field is always a 2-byte
5143            // varint as we don't know the value yet).
5144            //
5145            // Then we emit the data from the crypto stream's send buffer.
5146            //
5147            // Finally we go back and encode the frame header with the now
5148            // available information.
5149            let hdr_off = b.off();
5150            let hdr_len = 1 + // frame type
5151                octets::varint_len(crypto_off) + // offset
5152                2; // length, always encode as 2-byte varint
5153
5154            if let Some(max_len) = left.checked_sub(hdr_len) {
5155                let (mut crypto_hdr, mut crypto_payload) =
5156                    b.split_at(hdr_off + hdr_len)?;
5157
5158                // Write stream data into the packet buffer.
5159                let (len, _) = crypto_ctx
5160                    .crypto_stream
5161                    .send
5162                    .emit(&mut crypto_payload.as_mut()[..max_len])?;
5163
5164                // Encode the frame's header.
5165                //
5166                // Due to how `OctetsMut::split_at()` works, `crypto_hdr` starts
5167                // from the initial offset of `b` (rather than the current
5168                // offset), so it needs to be advanced to the
5169                // initial frame offset.
5170                crypto_hdr.skip(hdr_off)?;
5171
5172                frame::encode_crypto_header(
5173                    crypto_off,
5174                    len as u64,
5175                    &mut crypto_hdr,
5176                )?;
5177
5178                // Advance the packet buffer's offset.
5179                b.skip(hdr_len + len)?;
5180
5181                let frame = frame::Frame::CryptoHeader {
5182                    offset: crypto_off,
5183                    length: len,
5184                };
5185
5186                if push_frame_to_pkt!(b, frames, frame, left) {
5187                    ack_eliciting = true;
5188                    in_flight = true;
5189                    has_data = true;
5190                }
5191            }
5192        }
5193
5194        // The preference of data-bearing frame to include in a packet
5195        // is managed by `self.emit_dgram`. However, whether any frames
5196        // can be sent depends on the state of their buffers. In the case
5197        // where one type is preferred but its buffer is empty, fall back
5198        // to the other type in order not to waste this function call.
5199        let mut dgram_emitted = false;
5200        let dgrams_to_emit = max_dgram_len.is_some();
5201        let stream_to_emit = self.streams.has_flushable();
5202
5203        let mut do_dgram = self.emit_dgram && dgrams_to_emit;
5204        let do_stream = !self.emit_dgram && stream_to_emit;
5205
5206        if !do_stream && dgrams_to_emit {
5207            do_dgram = true;
5208        }
5209
5210        // Create DATAGRAM frame.
5211        if (pkt_type == Type::Short || pkt_type == Type::ZeroRTT) &&
5212            left > frame::MAX_DGRAM_OVERHEAD &&
5213            !is_closing &&
5214            path.active() &&
5215            do_dgram
5216        {
5217            if let Some(max_dgram_payload) = max_dgram_len {
5218                while let Some(len) = self.dgram_send_queue.peek_front_len() {
5219                    let hdr_off = b.off();
5220                    let hdr_len = 1 + // frame type
5221                        2; // length, always encode as 2-byte varint
5222
5223                    if (hdr_len + len) <= left {
5224                        // Front of the queue fits this packet, send it.
5225                        match self.dgram_send_queue.pop() {
5226                            Some(data) => {
5227                                // Encode the frame.
5228                                //
5229                                // Instead of creating a `frame::Frame` object,
5230                                // encode the frame directly into the packet
5231                                // buffer.
5232                                //
5233                                // First we reserve some space in the output
5234                                // buffer for writing the frame header (we
5235                                // assume the length field is always a 2-byte
5236                                // varint as we don't know the value yet).
5237                                //
5238                                // Then we emit the data from the DATAGRAM's
5239                                // buffer.
5240                                //
5241                                // Finally we go back and encode the frame
5242                                // header with the now available information.
5243                                let (mut dgram_hdr, mut dgram_payload) =
5244                                    b.split_at(hdr_off + hdr_len)?;
5245
5246                                dgram_payload.as_mut()[..len]
5247                                    .copy_from_slice(data.as_ref());
5248
5249                                // Encode the frame's header.
5250                                //
5251                                // Due to how `OctetsMut::split_at()` works,
5252                                // `dgram_hdr` starts from the initial offset
5253                                // of `b` (rather than the current offset), so
5254                                // it needs to be advanced to the initial frame
5255                                // offset.
5256                                dgram_hdr.skip(hdr_off)?;
5257
5258                                frame::encode_dgram_header(
5259                                    len as u64,
5260                                    &mut dgram_hdr,
5261                                )?;
5262
5263                                // Advance the packet buffer's offset.
5264                                b.skip(hdr_len + len)?;
5265
5266                                let frame =
5267                                    frame::Frame::DatagramHeader { length: len };
5268
5269                                if push_frame_to_pkt!(b, frames, frame, left) {
5270                                    ack_eliciting = true;
5271                                    in_flight = true;
5272                                    dgram_emitted = true;
5273                                    self.dgram_sent_count =
5274                                        self.dgram_sent_count.saturating_add(1);
5275                                    path.dgram_sent_count =
5276                                        path.dgram_sent_count.saturating_add(1);
5277                                }
5278                            },
5279
5280                            None => continue,
5281                        };
5282                    } else if len > max_dgram_payload {
5283                        // This dgram frame will never fit. Let's purge it.
5284                        self.dgram_send_queue.pop();
5285                    } else {
5286                        break;
5287                    }
5288                }
5289            }
5290        }
5291
5292        // Create a single STREAM frame for the first stream that is flushable.
5293        if (pkt_type == Type::Short || pkt_type == Type::ZeroRTT) &&
5294            !is_closing &&
5295            path.active() &&
5296            !dgram_emitted
5297        {
5298            while let Some(priority_key) = self.streams.peek_flushable() {
5299                let stream_id = priority_key.id;
5300                let stream = match self.streams.get_mut(stream_id) {
5301                    // A reset can abandon queued data or FINs while the stream
5302                    // remains alive waiting for the reset to be acknowledged.
5303                    Some(stream) if !stream.send.is_reset() => stream,
5304                    _ => {
5305                        self.streams.remove_flushable(&priority_key);
5306                        continue;
5307                    },
5308                };
5309
5310                let stream_off = stream.send.off_front();
5311
5312                // Encode the frame.
5313                //
5314                // Instead of creating a `frame::Frame` object, encode the frame
5315                // directly into the packet buffer.
5316                //
5317                // First we reserve some space in the output buffer for writing
5318                // the frame header (we assume the length field is always a
5319                // 2-byte varint as we don't know the value yet).
5320                //
5321                // Then we emit the data from the stream's send buffer.
5322                //
5323                // Finally we go back and encode the frame header with the now
5324                // available information.
5325                let hdr_off = b.off();
5326                let hdr_len = 1 + // frame type
5327                    octets::varint_len(stream_id) + // stream_id
5328                    octets::varint_len(stream_off) + // offset
5329                    2; // length, always encode as 2-byte varint
5330
5331                // A non-FIN STREAM frame must carry at least one byte. If the
5332                // header and payload don't fit, leave the stream flushable for
5333                // a later packet. Empty FIN frames only need the header.
5334                let max_len = match left.checked_sub(hdr_len) {
5335                    Some(v) if v > 0 || stream.send.empty_fin_next() => v,
5336                    _ => {
5337                        stream_data_skipped = true;
5338
5339                        if stream.incremental {
5340                            let priority_key = Arc::clone(&stream.priority_key);
5341                            self.streams.remove_flushable(&priority_key);
5342                            self.streams.insert_flushable(&priority_key);
5343                        }
5344
5345                        break;
5346                    },
5347                };
5348
5349                let (mut stream_hdr, mut stream_payload) =
5350                    b.split_at(hdr_off + hdr_len)?;
5351
5352                // Write stream data into the packet buffer.
5353                let (len, fin) =
5354                    stream.send.emit(&mut stream_payload.as_mut()[..max_len])?;
5355
5356                // ACK processing can leave a stream in the flushable queue
5357                // after removing all of its retransmission data. Unlink the
5358                // stale entry and continue with the next stream;
5359                // future retransmits or writedata will queue the stream again.
5360                if len == 0 && !fin {
5361                    let priority_key = Arc::clone(&stream.priority_key);
5362                    self.streams.remove_flushable(&priority_key);
5363                    continue;
5364                }
5365
5366                // Encode the frame's header.
5367                //
5368                // Due to how `OctetsMut::split_at()` works, `stream_hdr` starts
5369                // from the initial offset of `b` (rather than the current
5370                // offset), so it needs to be advanced to the initial frame
5371                // offset.
5372                stream_hdr.skip(hdr_off)?;
5373
5374                frame::encode_stream_header(
5375                    stream_id,
5376                    stream_off,
5377                    len as u64,
5378                    fin,
5379                    &mut stream_hdr,
5380                )?;
5381
5382                // Advance the packet buffer's offset.
5383                b.skip(hdr_len + len)?;
5384
5385                let frame = frame::Frame::StreamHeader {
5386                    stream_id,
5387                    offset: stream_off,
5388                    length: len,
5389                    fin,
5390                };
5391
5392                if push_frame_to_pkt!(b, frames, frame, left) {
5393                    ack_eliciting = true;
5394                    in_flight = true;
5395                    has_data = true;
5396                }
5397
5398                let priority_key = Arc::clone(&stream.priority_key);
5399                // Remove the stream when it is no longer flushable.
5400                if !stream.is_flushable() {
5401                    self.streams.remove_flushable(&priority_key);
5402                } else if stream.incremental {
5403                    // Shuffle the incremental stream to the back of the
5404                    // queue.
5405                    self.streams.remove_flushable(&priority_key);
5406                    self.streams.insert_flushable(&priority_key);
5407                }
5408
5409                // Update tx_buffered when data is emitted.
5410                self.streams.sub_tx_buffered(len);
5411
5412                #[cfg(feature = "fuzzing")]
5413                // Coalesce STREAM frames when fuzzing.
5414                continue;
5415
5416                #[cfg(not(feature = "fuzzing"))]
5417                break;
5418            }
5419        }
5420
5421        // Alternate trying to send DATAGRAMs next time.
5422        self.emit_dgram = !dgram_emitted;
5423
5424        // If no other ack-eliciting frame is sent, include a PING frame
5425        // - if PTO probe needed; OR
5426        // - if we've sent too many non ack-eliciting packets without having
5427        // sent an ACK eliciting one; OR
5428        // - the application requested an ack-eliciting frame be sent.
5429        if (ack_elicit_required || path.needs_ack_eliciting) &&
5430            !ack_eliciting &&
5431            left >= 1 &&
5432            !is_closing
5433        {
5434            let frame = frame::Frame::Ping { mtu_probe: None };
5435
5436            if push_frame_to_pkt!(b, frames, frame, left) {
5437                ack_eliciting = true;
5438                in_flight = true;
5439            }
5440        }
5441
5442        if ack_eliciting && !is_pmtud_probe {
5443            path.needs_ack_eliciting = false;
5444            path.recovery.ping_sent(epoch);
5445        }
5446
5447        // Pending stream data means the sender is size-, not app-limited.
5448        if !has_data &&
5449            !stream_data_skipped &&
5450            !dgram_emitted &&
5451            send_limit_from_cwnd > LEGACY_APP_LIMITED_BYTE_THRESHOLD
5452        {
5453            path.recovery.on_app_limited();
5454        }
5455
5456        if frames.is_empty() {
5457            // When we reach this point we are not able to write more, so set
5458            // app_limited to false.
5459            path.recovery.update_app_limited(false);
5460            return Err(Error::Done);
5461        }
5462
5463        // When coalescing a 1-RTT packet, we can't add padding in the UDP
5464        // datagram, so use PADDING frames instead.
5465        //
5466        // This is only needed if
5467        // 1) an Initial packet has already been written to the UDP datagram,
5468        // as Initial always requires padding.
5469        //
5470        // 2) this is a probing packet towards an unvalidated peer address.
5471        if (has_initial || !path.validated()) &&
5472            pkt_type == Type::Short &&
5473            left >= 1
5474        {
5475            let frame = frame::Frame::Padding { len: left };
5476
5477            if push_frame_to_pkt!(b, frames, frame, left) {
5478                in_flight = true;
5479            }
5480        }
5481
5482        // Pad payload so that it's always at least 4 bytes.
5483        if b.off() - payload_offset < PAYLOAD_MIN_LEN {
5484            let payload_len = b.off() - payload_offset;
5485
5486            let frame = frame::Frame::Padding {
5487                len: PAYLOAD_MIN_LEN - payload_len,
5488            };
5489
5490            #[allow(unused_assignments)]
5491            if push_frame_to_pkt!(b, frames, frame, left) {
5492                in_flight = true;
5493            }
5494        }
5495
5496        let payload_len = b.off() - payload_offset;
5497
5498        // Fill in payload length.
5499        if pkt_type != Type::Short {
5500            let len = pn_len + payload_len + crypto_overhead;
5501
5502            let (_, mut payload_with_len) = b.split_at(header_offset)?;
5503            payload_with_len
5504                .put_varint_with_len(len as u64, PAYLOAD_LENGTH_LEN)?;
5505        }
5506
5507        trace!(
5508            "{} tx pkt {} len={} pn={} {}",
5509            self.trace_id,
5510            hdr_trace.unwrap_or_default(),
5511            payload_len,
5512            pn,
5513            AddrTupleFmt(path.local_addr(), path.peer_addr())
5514        );
5515
5516        #[cfg(feature = "qlog")]
5517        let mut qlog_frames: Vec<qlog::events::quic::QuicFrame> =
5518            Vec::with_capacity(frames.len());
5519
5520        for frame in &mut frames {
5521            trace!("{} tx frm {:?}", self.trace_id, frame);
5522
5523            qlog_with_type!(QLOG_PACKET_TX, self.qlog, _q, {
5524                qlog_frames.push(frame.to_qlog());
5525            });
5526        }
5527
5528        qlog_with_type!(QLOG_PACKET_TX, self.qlog, q, {
5529            if let Some(header) = qlog_pkt_hdr {
5530                // Qlog packet raw info described at
5531                // https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema-00#section-5.1
5532                //
5533                // `length` includes packet headers and trailers (AEAD tag).
5534                let length = payload_len + payload_offset + crypto_overhead;
5535                let qlog_raw_info = RawInfo {
5536                    length: Some(length as u64),
5537                    payload_length: Some(payload_len as u64),
5538                    data: None,
5539                };
5540
5541                let send_at_time =
5542                    now.duration_since(q.start_time()).as_secs_f64() * 1000.0;
5543
5544                let ev_data =
5545                    EventData::QuicPacketSent(qlog::events::quic::PacketSent {
5546                        header,
5547                        frames: Some(qlog_frames),
5548                        raw: Some(qlog_raw_info),
5549                        send_at_time: Some(send_at_time),
5550                        ..Default::default()
5551                    });
5552
5553                q.add_event_data_with_instant(ev_data, now).ok();
5554            }
5555        });
5556
5557        let aead = match crypto_ctx.crypto_seal {
5558            Some(ref mut v) => v,
5559            None => return Err(Error::InvalidState),
5560        };
5561
5562        let written = packet::encrypt_pkt(
5563            &mut b,
5564            pn,
5565            pn_len,
5566            payload_len,
5567            payload_offset,
5568            None,
5569            aead,
5570        )?;
5571
5572        let sent_pkt_has_data = if path.recovery.gcongestion_enabled() {
5573            has_data || dgram_emitted
5574        } else {
5575            has_data
5576        };
5577
5578        let sent_pkt = recovery::Sent {
5579            pkt_num: pn,
5580            frames,
5581            time_sent: now,
5582            time_acked: None,
5583            time_lost: None,
5584            size: if ack_eliciting { written } else { 0 },
5585            ack_eliciting,
5586            in_flight,
5587            delivered: 0,
5588            delivered_time: now,
5589            first_sent_time: now,
5590            is_app_limited: false,
5591            tx_in_flight: 0,
5592            lost: 0,
5593            has_data: sent_pkt_has_data,
5594            is_pmtud_probe,
5595        };
5596
5597        if in_flight && is_app_limited {
5598            path.recovery.delivery_rate_update_app_limited(true);
5599        }
5600
5601        self.next_pkt_num += 1;
5602
5603        let handshake_status = recovery::HandshakeStatus {
5604            has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
5605                .has_keys(),
5606            peer_verified_address: self.peer_verified_initial_address,
5607            completed: self.handshake_completed,
5608        };
5609
5610        self.on_packet_sent(send_pid, sent_pkt, epoch, handshake_status, now)?;
5611
5612        let path = self.paths.get_mut(send_pid)?;
5613        qlog_with_type!(QLOG_METRICS, self.qlog, q, {
5614            path.recovery.maybe_qlog(q, now);
5615        });
5616
5617        // Record sent packet size if we probe the path.
5618        if let Some(data) = challenge_data {
5619            path.add_challenge_sent(data, written, now);
5620        }
5621
5622        self.sent_count += 1;
5623        self.sent_bytes += written as u64;
5624        path.sent_count += 1;
5625        path.sent_bytes += written as u64;
5626
5627        if self.dgram_send_queue.byte_size() > path.recovery.cwnd_available() {
5628            path.recovery.update_app_limited(false);
5629        }
5630
5631        let had_send_budget = path.max_send_bytes > 0;
5632        path.max_send_bytes = path.max_send_bytes.saturating_sub(written);
5633        if self.is_server &&
5634            !path.verified_peer_address &&
5635            had_send_budget &&
5636            path.max_send_bytes == 0
5637        {
5638            self.amplification_limited_count =
5639                self.amplification_limited_count.saturating_add(1);
5640        }
5641
5642        // On the client, drop initial state after sending an Handshake packet.
5643        if !self.is_server && hdr_ty == Type::Handshake {
5644            self.drop_epoch_state(packet::Epoch::Initial, now);
5645        }
5646
5647        // (Re)start the idle timer if we are sending the first ack-eliciting
5648        // packet since last receiving a packet.
5649        if ack_eliciting && !self.ack_eliciting_sent {
5650            if let Some(idle_timeout) = self.idle_timeout() {
5651                self.idle_timer = Some(now + idle_timeout);
5652            }
5653        }
5654
5655        if ack_eliciting {
5656            self.ack_eliciting_sent = true;
5657        }
5658
5659        Ok((pkt_type, written))
5660    }
5661
5662    fn on_packet_sent(
5663        &mut self, send_pid: usize, sent_pkt: recovery::Sent,
5664        epoch: packet::Epoch, handshake_status: recovery::HandshakeStatus,
5665        now: Instant,
5666    ) -> Result<()> {
5667        let path = self.paths.get_mut(send_pid)?;
5668
5669        // The skip counter may use values from an inactive path.
5670        let cwnd = path.recovery.cwnd();
5671        let max_datagram_size = path.recovery.max_datagram_size();
5672        self.pkt_num_spaces[epoch].on_packet_sent(&sent_pkt);
5673        self.pkt_num_manager.on_packet_sent(
5674            cwnd,
5675            max_datagram_size,
5676            self.handshake_completed,
5677        );
5678
5679        path.recovery.on_packet_sent(
5680            sent_pkt,
5681            epoch,
5682            handshake_status,
5683            now,
5684            &self.trace_id,
5685        );
5686
5687        // Bound recovery metadata when sent packet records accumulate.
5688        if self.local_error.is_none() {
5689            if let Some(max_outstanding_sent_packets) =
5690                self.max_outstanding_sent_packets
5691            {
5692                let tracked_sent_packets: usize = self
5693                    .paths
5694                    .iter()
5695                    .flat_map(|(_, p)| {
5696                        packet::Epoch::epochs(
5697                            packet::Epoch::Initial..=packet::Epoch::Application,
5698                        )
5699                        .iter()
5700                        .map(|&e| p.recovery.sent_packets_len(e))
5701                    })
5702                    .sum();
5703
5704                if tracked_sent_packets > max_outstanding_sent_packets.get() {
5705                    trace!(
5706                        "{} too many outstanding sent packets: {}",
5707                        self.trace_id,
5708                        tracked_sent_packets
5709                    );
5710
5711                    self.close(
5712                        false,
5713                        WireErrorCode::ProtocolViolation as u64,
5714                        b"too many outstanding sent packets",
5715                    )
5716                    .ok();
5717                }
5718            }
5719        }
5720
5721        Ok(())
5722    }
5723
5724    /// Returns the desired send time for the next packet.
5725    #[inline]
5726    pub fn get_next_release_time(&self) -> Option<ReleaseDecision> {
5727        Some(
5728            self.paths
5729                .get_active()
5730                .ok()?
5731                .recovery
5732                .get_next_release_time(),
5733        )
5734    }
5735
5736    /// Returns whether gcongestion is enabled.
5737    #[inline]
5738    pub fn gcongestion_enabled(&self) -> Option<bool> {
5739        Some(self.paths.get_active().ok()?.recovery.gcongestion_enabled())
5740    }
5741
5742    /// Returns the maximum pacing into the future.
5743    ///
5744    /// Equals 1/8 of the smoothed RTT, but at least 1ms and not greater than
5745    /// 5ms.
5746    pub fn max_release_into_future(&self) -> Duration {
5747        self.paths
5748            .get_active()
5749            .map(|p| p.recovery.rtt().mul_f64(0.125))
5750            .unwrap_or(Duration::from_millis(1))
5751            .max(Duration::from_millis(1))
5752            .min(Duration::from_millis(5))
5753    }
5754
5755    /// Returns whether pacing is enabled.
5756    #[inline]
5757    pub fn pacing_enabled(&self) -> bool {
5758        self.recovery_config.pacing
5759    }
5760
5761    /// Returns the size of the send quantum, in bytes.
5762    ///
5763    /// This represents the maximum size of a packet burst as determined by the
5764    /// congestion control algorithm in use.
5765    ///
5766    /// Applications can, for example, use it in conjunction with segmentation
5767    /// offloading mechanisms as the maximum limit for outgoing aggregates of
5768    /// multiple packets.
5769    #[inline]
5770    pub fn send_quantum(&self) -> usize {
5771        match self.paths.get_active() {
5772            Ok(p) => p.recovery.send_quantum(),
5773            _ => 0,
5774        }
5775    }
5776
5777    /// Returns the size of the send quantum over the given 4-tuple, in bytes.
5778    ///
5779    /// This represents the maximum size of a packet burst as determined by the
5780    /// congestion control algorithm in use.
5781    ///
5782    /// Applications can, for example, use it in conjunction with segmentation
5783    /// offloading mechanisms as the maximum limit for outgoing aggregates of
5784    /// multiple packets.
5785    ///
5786    /// If the (`local_addr`, peer_addr`) 4-tuple relates to a non-existing
5787    /// path, this method returns 0.
5788    pub fn send_quantum_on_path(
5789        &self, local_addr: SocketAddr, peer_addr: SocketAddr,
5790    ) -> usize {
5791        self.paths
5792            .path_id_from_addrs(&(local_addr, peer_addr))
5793            .and_then(|pid| self.paths.get(pid).ok())
5794            .map(|path| path.recovery.send_quantum())
5795            .unwrap_or(0)
5796    }
5797
5798    /// Reads contiguous data from a stream into the provided slice.
5799    ///
5800    /// The slice must be sized by the caller and will be populated up to its
5801    /// capacity.
5802    ///
5803    /// On success the amount of bytes read and a flag indicating the fin state
5804    /// is returned as a tuple, or [`Done`] if there is no data to read.
5805    ///
5806    /// Reading data from a stream may trigger queueing of control messages
5807    /// (e.g. MAX_STREAM_DATA). [`send()`] should be called afterwards.
5808    ///
5809    /// [`Done`]: enum.Error.html#variant.Done
5810    /// [`send()`]: struct.Connection.html#method.send
5811    ///
5812    /// ## Examples:
5813    ///
5814    /// ```no_run
5815    /// # let mut buf = [0; 512];
5816    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5817    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5818    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5819    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5820    /// # let local = socket.local_addr().unwrap();
5821    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5822    /// # let stream_id = 0;
5823    /// while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
5824    ///     println!("Got {} bytes on stream {}", read, stream_id);
5825    /// }
5826    /// # Ok::<(), quiche::Error>(())
5827    /// ```
5828    #[inline]
5829    pub fn stream_recv(
5830        &mut self, stream_id: u64, out: &mut [u8],
5831    ) -> Result<(usize, bool)> {
5832        self.stream_recv_buf(stream_id, out)
5833    }
5834
5835    /// Reads contiguous data from a stream into the provided [`bytes::BufMut`].
5836    ///
5837    /// **NOTE**:
5838    /// The BufMut will be populated with all available data up to its capacity.
5839    /// Since some BufMut implementations, e.g., [`Vec<u8>`], dynamically
5840    /// allocate additional memory, the caller may use [`BufMut::limit()`]
5841    /// to limit the maximum amount of data that can be written.
5842    ///
5843    /// On success the amount of bytes read and a flag indicating the fin state
5844    /// is returned as a tuple, or [`Done`] if there is no data to read.
5845    /// [`BufMut::advance_mut()`] will have been called with the same number of
5846    /// total bytes.
5847    ///
5848    /// Reading data from a stream may trigger queueing of control messages
5849    /// (e.g. MAX_STREAM_DATA). [`send()`] should be called afterwards.
5850    ///
5851    /// [`BufMut::limit()`]: bytes::BufMut::limit
5852    /// [`BufMut::advance_mut()`]: bytes::BufMut::advance_mut
5853    /// [`Done`]: enum.Error.html#variant.Done
5854    /// [`send()`]: struct.Connection.html#method.send
5855    ///
5856    /// ## Examples:
5857    ///
5858    /// ```no_run
5859    /// # use bytes::BufMut as _;
5860    /// # let mut buf = Vec::new().limit(1024);  // Read at most 1024 bytes
5861    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5862    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5863    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5864    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5865    /// # let local = socket.local_addr().unwrap();
5866    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5867    /// # let stream_id = 0;
5868    /// # let mut total_read = 0;
5869    /// while let Ok((read, fin)) = conn.stream_recv_buf(stream_id, &mut buf) {
5870    ///     println!("Got {} bytes on stream {}", read, stream_id);
5871    ///     total_read += read;
5872    ///     assert_eq!(buf.get_ref().len(), total_read);
5873    /// }
5874    /// # Ok::<(), quiche::Error>(())
5875    /// ```
5876    pub fn stream_recv_buf<B: bytes::BufMut>(
5877        &mut self, stream_id: u64, out: B,
5878    ) -> Result<(usize, bool)> {
5879        self.do_stream_recv(stream_id, RecvAction::Emit { out })
5880    }
5881
5882    /// Discard contiguous data from a stream without copying.
5883    ///
5884    /// On success the amount of bytes discarded and a flag indicating the fin
5885    /// state is returned as a tuple, or [`Done`] if there is no data to
5886    /// discard.
5887    ///
5888    /// Discarding data from a stream may trigger queueing of control messages
5889    /// (e.g. MAX_STREAM_DATA). [`send()`] should be called afterwards.
5890    ///
5891    /// [`Done`]: enum.Error.html#variant.Done
5892    /// [`send()`]: struct.Connection.html#method.send
5893    ///
5894    /// ## Examples:
5895    ///
5896    /// ```no_run
5897    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
5898    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
5899    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
5900    /// # let peer = "127.0.0.1:1234".parse().unwrap();
5901    /// # let local = socket.local_addr().unwrap();
5902    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
5903    /// # let stream_id = 0;
5904    /// while let Ok((read, fin)) = conn.stream_discard(stream_id, 1) {
5905    ///     println!("Discarded {} byte(s) on stream {}", read, stream_id);
5906    /// }
5907    /// # Ok::<(), quiche::Error>(())
5908    /// ```
5909    pub fn stream_discard(
5910        &mut self, stream_id: u64, len: usize,
5911    ) -> Result<(usize, bool)> {
5912        // `do_stream_recv()` is generic on the kind of `BufMut` in RecvAction.
5913        // Since we are discarding, it doesn't matter, but the compiler still
5914        // wants to know, so we say `&mut [u8]`.
5915        self.do_stream_recv::<&mut [u8]>(stream_id, RecvAction::Discard { len })
5916    }
5917
5918    // Reads or discards contiguous data from a stream.
5919    //
5920    // Passing an `action` of `StreamRecvAction::Emit` results in a read into
5921    // the provided slice. It must be sized by the caller and will be populated
5922    // up to its capacity.
5923    //
5924    // Passing an `action` of `StreamRecvAction::Discard` results in discard up
5925    // to the indicated length.
5926    //
5927    // On success the amount of bytes read or discarded, and a flag indicating
5928    // the fin state, is returned as a tuple, or [`Done`] if there is no data to
5929    // read or discard.
5930    //
5931    // Reading or discarding data from a stream may trigger queueing of control
5932    // messages (e.g. MAX_STREAM_DATA). [`send()`] should be called afterwards.
5933    //
5934    // [`Done`]: enum.Error.html#variant.Done
5935    // [`send()`]: struct.Connection.html#method.send
5936    fn do_stream_recv<B: bytes::BufMut>(
5937        &mut self, stream_id: u64, action: RecvAction<B>,
5938    ) -> Result<(usize, bool)> {
5939        // We can't read on our own unidirectional streams.
5940        if !stream::is_bidi(stream_id) &&
5941            stream::is_local(stream_id, self.is_server)
5942        {
5943            return Err(Error::InvalidStreamState(stream_id));
5944        }
5945
5946        let stream = self
5947            .streams
5948            .get_mut(stream_id)
5949            .ok_or(Error::InvalidStreamState(stream_id))?;
5950
5951        if !stream.is_readable() {
5952            return Err(Error::Done);
5953        }
5954
5955        let local = stream.local;
5956        let priority_key = Arc::clone(&stream.priority_key);
5957
5958        #[cfg(feature = "qlog")]
5959        let offset = stream.recv.off_front();
5960
5961        #[cfg(feature = "qlog")]
5962        let to = match action {
5963            RecvAction::Emit { .. } => Some(DataRecipient::Application),
5964
5965            RecvAction::Discard { .. } => Some(DataRecipient::Dropped),
5966        };
5967
5968        let (read, fin) = match stream.recv.emit_or_discard(action) {
5969            Ok(v) => v,
5970
5971            Err(e) => {
5972                // A StreamReset read completes the receive side, but an
5973                // unreported STOP error still needs the send-side state.
5974                if stream.state() == stream::StreamState::Collectable {
5975                    self.streams.collect(stream_id, local);
5976                }
5977
5978                self.streams.remove_readable(&priority_key);
5979                return Err(e);
5980            },
5981        };
5982
5983        self.flow_control.add_consumed(read as u64);
5984
5985        let readable = stream.is_readable();
5986
5987        let state = stream.state();
5988
5989        if stream.recv.almost_full() {
5990            self.streams.insert_almost_full(stream_id);
5991        }
5992
5993        if !readable {
5994            self.streams.remove_readable(&priority_key);
5995        }
5996
5997        if state == stream::StreamState::Collectable {
5998            self.streams.collect(stream_id, local);
5999        }
6000
6001        qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
6002            let ev_data = EventData::QuicStreamDataMoved(
6003                qlog::events::quic::StreamDataMoved {
6004                    stream_id: Some(stream_id),
6005                    offset: Some(offset),
6006                    raw: Some(RawInfo {
6007                        length: Some(read as u64),
6008                        ..Default::default()
6009                    }),
6010                    from: Some(DataRecipient::Transport),
6011                    to,
6012                    additional_info: fin
6013                        .then_some(DataMovedAdditionalInfo::FinSet),
6014                },
6015            );
6016
6017            let now = Instant::now();
6018            q.add_event_data_with_instant(ev_data, now).ok();
6019        });
6020
6021        if priority_key.incremental && readable {
6022            // Shuffle the incremental stream to the back of the queue.
6023            self.streams.remove_readable(&priority_key);
6024            self.streams.insert_readable(&priority_key);
6025        }
6026
6027        Ok((read, fin))
6028    }
6029
6030    /// Writes data to a stream.
6031    ///
6032    /// On success the number of bytes written is returned, or [`Done`] if no
6033    /// data was written (e.g. because the stream has no capacity).
6034    ///
6035    /// Applications can provide a 0-length buffer with the fin flag set to
6036    /// true. This will lead to a 0-length FIN STREAM frame being sent at the
6037    /// latest offset. The `Ok(0)` value is only returned when the application
6038    /// provided a 0-length buffer.
6039    ///
6040    /// In addition, if the peer has signalled that it doesn't want to receive
6041    /// any more data from this stream by sending the `STOP_SENDING` frame, the
6042    /// [`StreamStopped`] error will be returned instead of any data.
6043    ///
6044    /// Note that in order to avoid buffering an infinite amount of data in the
6045    /// stream's send buffer, streams are only allowed to buffer outgoing data
6046    /// up to the amount that the peer allows it to send (that is, up to the
6047    /// stream's outgoing flow control capacity).
6048    ///
6049    /// This means that the number of written bytes returned can be lower than
6050    /// the length of the input buffer when the stream doesn't have enough
6051    /// capacity for the operation to complete. The application should retry the
6052    /// operation once the stream is reported as writable again.
6053    ///
6054    /// Applications should call this method only after the handshake is
6055    /// completed (whenever [`is_established()`] returns `true`) or during
6056    /// early data if enabled (whenever [`is_in_early_data()`] returns `true`).
6057    ///
6058    /// [`Done`]: enum.Error.html#variant.Done
6059    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
6060    /// [`is_established()`]: struct.Connection.html#method.is_established
6061    /// [`is_in_early_data()`]: struct.Connection.html#method.is_in_early_data
6062    ///
6063    /// ## Examples:
6064    ///
6065    /// ```no_run
6066    /// # let mut buf = [0; 512];
6067    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6068    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6069    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6070    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6071    /// # let local = "127.0.0.1:4321".parse().unwrap();
6072    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6073    /// # let stream_id = 0;
6074    /// conn.stream_send(stream_id, b"hello", true)?;
6075    /// # Ok::<(), quiche::Error>(())
6076    /// ```
6077    pub fn stream_send(
6078        &mut self, stream_id: u64, buf: &[u8], fin: bool,
6079    ) -> Result<usize> {
6080        self.stream_do_send(
6081            stream_id,
6082            buf,
6083            fin,
6084            |stream: &mut stream::Stream<F>,
6085             buf: &[u8],
6086             cap: usize,
6087             fin: bool| {
6088                stream.send.write(&buf[..cap], fin).map(|v| (v, v))
6089            },
6090        )
6091    }
6092
6093    /// Writes data to a stream with zero copying, instead, it appends the
6094    /// provided buffer directly to the send queue if the capacity allows
6095    /// it.
6096    ///
6097    /// When a partial write happens (including when [`Error::Done`] is
6098    /// returned) the remaining (unwritten) buffer will also be returned.
6099    /// The application should retry the operation once the stream is
6100    /// reported as writable again.
6101    pub fn stream_send_zc(
6102        &mut self, stream_id: u64, buf: F::Buf, fin: bool,
6103    ) -> Result<(usize, Option<F::Buf>)>
6104    where
6105        F::Buf: BufSplit,
6106    {
6107        self.stream_do_send(
6108            stream_id,
6109            buf,
6110            fin,
6111            |stream: &mut stream::Stream<F>,
6112             buf: F::Buf,
6113             cap: usize,
6114             fin: bool| {
6115                let (sent, remaining) = stream.send.append_buf(buf, cap, fin)?;
6116                Ok((sent, (sent, remaining)))
6117            },
6118        )
6119    }
6120
6121    fn stream_do_send<B, R, SND>(
6122        &mut self, stream_id: u64, buf: B, fin: bool, write_fn: SND,
6123    ) -> Result<R>
6124    where
6125        B: AsRef<[u8]>,
6126        SND: FnOnce(&mut stream::Stream<F>, B, usize, bool) -> Result<(usize, R)>,
6127    {
6128        // We can't write on the peer's unidirectional streams.
6129        if !stream::is_bidi(stream_id) &&
6130            !stream::is_local(stream_id, self.is_server)
6131        {
6132            return Err(Error::InvalidStreamState(stream_id));
6133        }
6134
6135        let len = buf.as_ref().len();
6136
6137        // Mark the connection as blocked if the connection-level flow control
6138        // limit doesn't let us buffer all the data.
6139        //
6140        // Note that this is separate from "send capacity" as that also takes
6141        // congestion control into consideration.
6142        if self.max_tx_data - self.tx_data < len as u64 {
6143            self.blocked_limit = Some(self.max_tx_data);
6144        }
6145
6146        let cap = self.tx_cap;
6147
6148        // Get existing stream or create a new one.
6149        let stream = match self.get_or_create_stream(stream_id, true) {
6150            Ok(v) => v,
6151
6152            Err(Error::StreamLimit) => {
6153                // If the local endpoint has exhausted the peer's stream count
6154                // limit, record the current limit so that a STREAMS_BLOCKED
6155                // frame can be sent.
6156                if self.enable_send_streams_blocked &&
6157                    stream::is_local(stream_id, self.is_server)
6158                {
6159                    if stream::is_bidi(stream_id) {
6160                        let limit = self.streams.peer_max_streams_bidi();
6161                        self.streams_blocked_bidi_state.update_at(limit);
6162                    } else {
6163                        let limit = self.streams.peer_max_streams_uni();
6164                        self.streams_blocked_uni_state.update_at(limit);
6165                    }
6166                }
6167
6168                return Err(Error::StreamLimit);
6169            },
6170
6171            Err(e) => return Err(e),
6172        };
6173
6174        #[cfg(feature = "qlog")]
6175        let offset = stream.send.off_back();
6176
6177        let was_writable = stream.is_writable();
6178
6179        let was_flushable = stream.is_flushable();
6180
6181        // Return the stop before collecting a completed stream.
6182        if let Err(Error::StreamStopped(e)) =
6183            stream.send.cap_and_report_stop_sending()
6184        {
6185            self.streams.on_stop_sending_reported(stream_id);
6186            return Err(Error::StreamStopped(e));
6187        };
6188
6189        let priority_key = Arc::clone(&stream.priority_key);
6190
6191        // Truncate the input buffer based on the connection's send capacity if
6192        // necessary.
6193        //
6194        // When the cap is zero, the method returns Ok(0) *only* when the passed
6195        // buffer is empty. We return Error::Done otherwise.
6196        if cap == 0 && len > 0 {
6197            if was_writable {
6198                // When `stream_writable_next()` returns a stream, the writable
6199                // mark is removed, but because the stream is blocked by the
6200                // connection-level send capacity it won't be marked as writable
6201                // again once the capacity increases.
6202                //
6203                // Since the stream is writable already, mark it here instead.
6204                self.streams.insert_writable(&priority_key);
6205            }
6206
6207            return Err(Error::Done);
6208        }
6209
6210        let (cap, fin, blocked_by_cap) = if cap < len {
6211            (cap, false, true)
6212        } else {
6213            (len, fin, false)
6214        };
6215
6216        let (sent, ret) = match write_fn(stream, buf, cap, fin) {
6217            Ok(v) => v,
6218
6219            Err(e) => {
6220                self.streams.remove_writable(&priority_key);
6221                return Err(e);
6222            },
6223        };
6224
6225        let incremental = stream.incremental;
6226        let priority_key = Arc::clone(&stream.priority_key);
6227
6228        let flushable = stream.is_flushable();
6229
6230        let writable = stream.is_writable();
6231
6232        if sent < cap {
6233            let max_off = stream.send.max_off();
6234
6235            if stream.send.blocked_at() != Some(max_off) {
6236                stream.send.update_blocked_at(Some(max_off));
6237                self.streams.insert_blocked(stream_id, max_off);
6238            }
6239        } else {
6240            stream.send.update_blocked_at(None);
6241            self.streams.remove_blocked(stream_id);
6242        }
6243
6244        // If the stream is now flushable push it to the flushable queue, but
6245        // only if it wasn't already queued.
6246        if flushable && !was_flushable {
6247            self.streams.insert_flushable(&priority_key);
6248        }
6249
6250        if !writable {
6251            self.streams.remove_writable(&priority_key);
6252        } else if was_writable && blocked_by_cap {
6253            // When `stream_writable_next()` returns a stream, the writable
6254            // mark is removed, but because the stream is blocked by the
6255            // connection-level send capacity it won't be marked as writable
6256            // again once the capacity increases.
6257            //
6258            // Since the stream is writable already, mark it here instead.
6259            self.streams.insert_writable(&priority_key);
6260        }
6261
6262        self.tx_cap -= sent;
6263
6264        self.tx_data += sent as u64;
6265
6266        self.streams.add_tx_buffered(sent);
6267
6268        qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
6269            let ev_data = EventData::QuicStreamDataMoved(
6270                qlog::events::quic::StreamDataMoved {
6271                    stream_id: Some(stream_id),
6272                    offset: Some(offset),
6273                    raw: Some(RawInfo {
6274                        length: Some(sent as u64),
6275                        ..Default::default()
6276                    }),
6277                    from: Some(DataRecipient::Application),
6278                    to: Some(DataRecipient::Transport),
6279                    additional_info: fin
6280                        .then_some(DataMovedAdditionalInfo::FinSet),
6281                },
6282            );
6283
6284            let now = Instant::now();
6285            q.add_event_data_with_instant(ev_data, now).ok();
6286        });
6287
6288        if sent == 0 && cap > 0 {
6289            return Err(Error::Done);
6290        }
6291
6292        if incremental && writable {
6293            // Shuffle the incremental stream to the back of the queue.
6294            self.streams.remove_writable(&priority_key);
6295            self.streams.insert_writable(&priority_key);
6296        }
6297
6298        Ok(ret)
6299    }
6300
6301    /// Sets the priority for a stream.
6302    ///
6303    /// A stream's priority determines the order in which stream data is sent
6304    /// on the wire (streams with lower priority are sent first). Streams are
6305    /// created with a default priority of `127`.
6306    ///
6307    /// The target stream is created if it did not exist before calling this
6308    /// method.
6309    pub fn stream_priority(
6310        &mut self, stream_id: u64, urgency: u8, incremental: bool,
6311    ) -> Result<()> {
6312        // Get existing stream or create a new one, but if the stream
6313        // has already been closed and collected, ignore the prioritization.
6314        let stream = match self.get_or_create_stream(stream_id, true) {
6315            Ok(v) => v,
6316
6317            Err(Error::Done) => return Ok(()),
6318
6319            Err(e) => return Err(e),
6320        };
6321
6322        if stream.urgency == urgency && stream.incremental == incremental {
6323            return Ok(());
6324        }
6325
6326        stream.urgency = urgency;
6327        stream.incremental = incremental;
6328
6329        let new_priority_key = Arc::new(StreamPriorityKey {
6330            urgency: stream.urgency,
6331            incremental: stream.incremental,
6332            id: stream_id,
6333            ..Default::default()
6334        });
6335
6336        let old_priority_key =
6337            std::mem::replace(&mut stream.priority_key, new_priority_key.clone());
6338
6339        self.streams
6340            .update_priority(&old_priority_key, &new_priority_key);
6341
6342        Ok(())
6343    }
6344
6345    /// Shuts down reading or writing from/to the specified stream.
6346    ///
6347    /// When the `direction` argument is set to [`Shutdown::Read`], outstanding
6348    /// data in the stream's receive buffer is dropped, and no additional data
6349    /// is added to it. Data received after calling this method is still
6350    /// validated and acked but not stored, and [`stream_recv()`] will not
6351    /// return it to the application. In addition, a `STOP_SENDING` frame will
6352    /// be sent to the peer to signal it to stop sending data.
6353    ///
6354    /// When the `direction` argument is set to [`Shutdown::Write`], outstanding
6355    /// data in the stream's send buffer is dropped, and no additional data is
6356    /// added to it. Data passed to [`stream_send()`] after calling this method
6357    /// will be ignored. In addition, a `RESET_STREAM` frame will be sent to the
6358    /// peer to signal the reset, unless all outgoing data has already been
6359    /// acked by the peer (up to the `fin` offset).
6360    ///
6361    /// Locally-initiated unidirectional streams can only be closed in the
6362    /// [`Shutdown::Write`] direction. Remotely-initiated unidirectional streams
6363    /// can only be closed in the [`Shutdown::Read`] direction. Using an
6364    /// incorrect direction will return [`InvalidStreamState`].
6365    ///
6366    /// [`Shutdown::Read`]: enum.Shutdown.html#variant.Read
6367    /// [`Shutdown::Write`]: enum.Shutdown.html#variant.Write
6368    /// [`stream_recv()`]: struct.Connection.html#method.stream_recv
6369    /// [`stream_send()`]: struct.Connection.html#method.stream_send
6370    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
6371    pub fn stream_shutdown(
6372        &mut self, stream_id: u64, direction: Shutdown, err: u64,
6373    ) -> Result<()> {
6374        // Don't try to stop a local unidirectional stream.
6375        if direction == Shutdown::Read &&
6376            stream::is_local(stream_id, self.is_server) &&
6377            !stream::is_bidi(stream_id)
6378        {
6379            return Err(Error::InvalidStreamState(stream_id));
6380        }
6381
6382        // Don't try to reset a remote unidirectional stream.
6383        if direction == Shutdown::Write &&
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        // Get existing stream.
6391        let stream = self.streams.get_mut(stream_id).ok_or(Error::Done)?;
6392
6393        let priority_key = Arc::clone(&stream.priority_key);
6394
6395        match direction {
6396            Shutdown::Read => {
6397                let consumed = stream.recv.shutdown()?;
6398                self.flow_control.add_consumed(consumed);
6399
6400                // Discarding unread data can complete the receive side, so no
6401                // later read would collect the stream.
6402                let state = stream.state();
6403                let local = stream.local;
6404
6405                if !stream.recv.is_fin() {
6406                    self.streams.insert_stopped(stream_id, err);
6407                }
6408
6409                // Once shutdown, the stream is guaranteed to be non-readable.
6410                self.streams.remove_readable(&priority_key);
6411
6412                self.stopped_stream_local_count =
6413                    self.stopped_stream_local_count.saturating_add(1);
6414
6415                if state == stream::StreamState::Collectable {
6416                    self.streams.collect(stream_id, local);
6417                }
6418            },
6419
6420            Shutdown::Write => {
6421                // Save the buffered length before shutdown (shutdown clears the
6422                // buffer).
6423                let buffered_len = stream.send.buffered_bytes() as usize;
6424
6425                let (final_size, unsent) = stream.send.shutdown()?;
6426
6427                // Claw back some flow control allowance from data that was
6428                // buffered but not actually sent before the stream was reset.
6429                self.tx_data = self.tx_data.saturating_sub(unsent);
6430
6431                // Update tx_buffered: subtract only the buffered data, not
6432                // inflight data.
6433                self.streams.sub_tx_buffered(buffered_len);
6434
6435                // Match App-to-Transport moves with Transport-to-Dropped moves.
6436                // A Network transition would distinguish sent bytes from drops
6437                // before transmission.
6438                qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
6439                    let ev_data = EventData::QuicStreamDataMoved(
6440                        qlog::events::quic::StreamDataMoved {
6441                            stream_id: Some(stream_id),
6442                            offset: Some(final_size),
6443                            raw: Some(RawInfo {
6444                                length: Some(unsent),
6445                                ..Default::default()
6446                            }),
6447                            from: Some(DataRecipient::Transport),
6448                            to: Some(DataRecipient::Dropped),
6449                            ..Default::default()
6450                        },
6451                    );
6452
6453                    q.add_event_data_with_instant(ev_data, Instant::now()).ok();
6454                });
6455
6456                // Update send capacity.
6457                self.update_tx_cap();
6458
6459                self.streams.insert_reset(stream_id, err, final_size);
6460
6461                // Once shutdown, the stream is guaranteed to be non-writable
6462                // and has nothing left to flush. A stale flushable entry could
6463                // make send() return Done while DATAGRAMs are still queued.
6464                self.streams.remove_writable(&priority_key);
6465                self.streams.remove_flushable(&priority_key);
6466
6467                self.reset_stream_local_count =
6468                    self.reset_stream_local_count.saturating_add(1);
6469
6470                self.streams.try_collect(stream_id);
6471            },
6472        }
6473
6474        Ok(())
6475    }
6476
6477    /// Returns the stream's send capacity in bytes.
6478    ///
6479    /// The returned capacity takes into account the stream's flow control limit
6480    /// as well as connection level flow and congestion control.
6481    ///
6482    /// If the specified stream doesn't exist (including when it has already
6483    /// been completed and closed), the [`InvalidStreamState`] error will be
6484    /// returned.
6485    ///
6486    /// In addition, if the peer has signalled that it doesn't want to receive
6487    /// any more data from this stream by sending the `STOP_SENDING` frame, the
6488    /// [`StreamStopped`] error will be returned.
6489    ///
6490    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
6491    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
6492    #[inline]
6493    pub fn stream_capacity(&mut self, stream_id: u64) -> Result<usize> {
6494        if let Some(stream) = self.streams.get_mut(stream_id) {
6495            let stream_cap = match stream.send.cap_and_report_stop_sending() {
6496                Ok(v) => v,
6497
6498                Err(Error::StreamStopped(e)) => {
6499                    self.streams.on_stop_sending_reported(stream_id);
6500                    return Err(Error::StreamStopped(e));
6501                },
6502
6503                Err(e) => return Err(e),
6504            };
6505
6506            let cap = cmp::min(self.tx_cap, stream_cap);
6507            return Ok(cap);
6508        };
6509
6510        Err(Error::InvalidStreamState(stream_id))
6511    }
6512
6513    /// Returns the next stream that has data to read.
6514    ///
6515    /// Note that once returned by this method, a stream ID will not be returned
6516    /// again until it is "re-armed".
6517    ///
6518    /// The application will need to read all of the pending data on the stream,
6519    /// and new data has to be received before the stream is reported again.
6520    ///
6521    /// This is unlike the [`readable()`] method, that returns the same list of
6522    /// readable streams when called multiple times in succession.
6523    ///
6524    /// [`readable()`]: struct.Connection.html#method.readable
6525    pub fn stream_readable_next(&mut self) -> Option<u64> {
6526        let priority_key = self.streams.readable.front().clone_pointer()?;
6527
6528        self.streams.remove_readable(&priority_key);
6529
6530        Some(priority_key.id)
6531    }
6532
6533    /// Returns true if the stream has data that can be read.
6534    pub fn stream_readable(&self, stream_id: u64) -> bool {
6535        let stream = match self.streams.get(stream_id) {
6536            Some(v) => v,
6537
6538            None => return false,
6539        };
6540
6541        stream.is_readable()
6542    }
6543
6544    /// Returns the number of contiguous bytes buffered for a stream, up to
6545    /// `max_len`.
6546    ///
6547    /// This is the length of the contiguous, in-order data buffered at the
6548    /// stream's current read offset, i.e. the bytes a call to [`stream_recv`]
6549    /// would return right now. Data received out of order that sits behind a
6550    /// gap is not counted, so this never reports bytes that are not yet
6551    /// readable.
6552    ///
6553    /// This is a companion to [`stream_readable`], which only reports *whether*
6554    /// data is available; this reports *how much*. It is intended for sizing a
6555    /// receive buffer. The cost is proportional to the number of contiguous
6556    /// buffered chunks at the front of the stream, up to `max_len`, and no data
6557    /// is copied.
6558    ///
6559    /// Returns 0 if the stream does not exist.
6560    ///
6561    /// [`stream_recv`]: struct.Connection.html#method.stream_recv
6562    /// [`stream_readable`]: struct.Connection.html#method.stream_readable
6563    pub fn stream_readable_len(&self, stream_id: u64, max_len: usize) -> usize {
6564        match self.streams.get(stream_id) {
6565            Some(s) => s.recv.readable_len(max_len),
6566
6567            None => 0,
6568        }
6569    }
6570
6571    /// Returns the next stream that can be written to.
6572    ///
6573    /// Note that once returned by this method, a stream ID will not be returned
6574    /// again until it is "re-armed".
6575    ///
6576    /// This is unlike the [`writable()`] method, that returns the same list of
6577    /// writable streams when called multiple times in succession. It is not
6578    /// advised to use both `stream_writable_next()` and [`writable()`] on the
6579    /// same connection, as it may lead to unexpected results.
6580    ///
6581    /// The [`stream_writable()`] method can also be used to fine-tune when a
6582    /// stream is reported as writable again.
6583    ///
6584    /// A stopped stream is returned even without send capacity. Querying its
6585    /// capacity or writing to it returns [`StreamStopped`].
6586    ///
6587    /// [`stream_writable()`]: struct.Connection.html#method.stream_writable
6588    /// [`writable()`]: struct.Connection.html#method.writable
6589    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
6590    pub fn stream_writable_next(&mut self) -> Option<u64> {
6591        if self.tx_cap == 0 {
6592            return self.streams.pop_stopped_writable();
6593        }
6594
6595        let mut cursor = self.streams.writable.front();
6596
6597        while let Some(priority_key) = cursor.clone_pointer() {
6598            if let Some(stream) = self.streams.get(priority_key.id) {
6599                let cap = match stream.send.cap() {
6600                    Ok(v) => v,
6601
6602                    // Return the stream to the application immediately if it's
6603                    // stopped.
6604                    Err(_) =>
6605                        return {
6606                            self.streams.remove_writable(&priority_key);
6607
6608                            Some(priority_key.id)
6609                        },
6610                };
6611
6612                if cmp::min(self.tx_cap, cap) >= stream.send_lowat {
6613                    self.streams.remove_writable(&priority_key);
6614                    return Some(priority_key.id);
6615                }
6616            }
6617
6618            cursor.move_next();
6619        }
6620
6621        None
6622    }
6623
6624    /// Returns true if the stream has enough send capacity.
6625    ///
6626    /// When `len` more bytes can be buffered into the given stream's send
6627    /// buffer, `true` will be returned, `false` otherwise.
6628    ///
6629    /// In the latter case, if the additional data can't be buffered due to
6630    /// flow control limits, the peer will also be notified, and a "low send
6631    /// watermark" will be set for the stream, such that it is not going to be
6632    /// reported as writable again by [`stream_writable_next()`] until its send
6633    /// capacity reaches `len`.
6634    ///
6635    /// If the specified stream doesn't exist (including when it has already
6636    /// been completed and closed), the [`InvalidStreamState`] error will be
6637    /// returned.
6638    ///
6639    /// In addition, if the peer has signalled that it doesn't want to receive
6640    /// any more data from this stream by sending the `STOP_SENDING` frame, the
6641    /// [`StreamStopped`] error will be returned.
6642    ///
6643    /// [`stream_writable_next()`]: struct.Connection.html#method.stream_writable_next
6644    /// [`InvalidStreamState`]: enum.Error.html#variant.InvalidStreamState
6645    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
6646    #[inline]
6647    pub fn stream_writable(
6648        &mut self, stream_id: u64, len: usize,
6649    ) -> Result<bool> {
6650        if self.stream_capacity(stream_id)? >= len {
6651            return Ok(true);
6652        }
6653
6654        let stream = match self.streams.get_mut(stream_id) {
6655            Some(v) => v,
6656
6657            None => return Err(Error::InvalidStreamState(stream_id)),
6658        };
6659
6660        stream.send_lowat = cmp::max(1, len);
6661
6662        let is_writable = stream.is_writable();
6663
6664        let priority_key = Arc::clone(&stream.priority_key);
6665
6666        if self.max_tx_data - self.tx_data < len as u64 {
6667            self.blocked_limit = Some(self.max_tx_data);
6668        }
6669
6670        if stream.send.cap()? < len {
6671            let max_off = stream.send.max_off();
6672            if stream.send.blocked_at() != Some(max_off) {
6673                stream.send.update_blocked_at(Some(max_off));
6674                self.streams.insert_blocked(stream_id, max_off);
6675            }
6676        } else if is_writable {
6677            // When `stream_writable_next()` returns a stream, the writable
6678            // mark is removed, but because the stream is blocked by the
6679            // connection-level send capacity it won't be marked as writable
6680            // again once the capacity increases.
6681            //
6682            // Since the stream is writable already, mark it here instead.
6683            self.streams.insert_writable(&priority_key);
6684        }
6685
6686        Ok(false)
6687    }
6688
6689    /// Returns true if all the data has been read from the specified stream.
6690    ///
6691    /// This instructs the application that all the data received from the
6692    /// peer on the stream has been read, and there won't be anymore in the
6693    /// future.
6694    ///
6695    /// Basically this returns true when the peer either set the `fin` flag
6696    /// for the stream, or sent `RESET_STREAM`.
6697    #[inline]
6698    pub fn stream_finished(&self, stream_id: u64) -> bool {
6699        let stream = match self.streams.get(stream_id) {
6700            Some(v) => v,
6701
6702            None => return true,
6703        };
6704
6705        stream.recv.is_fin()
6706    }
6707
6708    /// Returns true if the specified stream is closed.
6709    ///
6710    /// For bidirectional streams this happens when both the receive and send
6711    /// sides have signaled `fin`. For unidirectional streams only the
6712    /// relevant direction is checked, depending on whether the stream was
6713    /// created locally or not.
6714    ///
6715    /// This also returns true if the stream has already been collected, but
6716    /// returns false if the stream was never opened.
6717    #[inline]
6718    pub fn stream_closed(&self, stream_id: u64) -> bool {
6719        let Some(stream) = self.streams.get(stream_id) else {
6720            return self.streams.is_collected(stream_id);
6721        };
6722
6723        match (stream.bidi, stream.local) {
6724            // For bidirectional streams both directions must have signaled
6725            // FIN.
6726            (true, _) => stream.recv.is_fin() && stream.send.is_fin(),
6727
6728            // For unidirectional streams created locally, only the send side
6729            // is checked.
6730            (false, true) => stream.send.is_fin(),
6731
6732            // For unidirectional streams created by the peer, only the
6733            // receive side is checked.
6734            (false, false) => stream.recv.is_fin(),
6735        }
6736    }
6737
6738    /// Returns the number of bidirectional streams that can be created
6739    /// before the peer's stream count limit is reached.
6740    ///
6741    /// This can be useful to know if it's possible to create a bidirectional
6742    /// stream without trying it first.
6743    #[inline]
6744    pub fn peer_streams_left_bidi(&self) -> u64 {
6745        self.streams.peer_streams_left_bidi()
6746    }
6747
6748    /// Returns the number of unidirectional streams that can be created
6749    /// before the peer's stream count limit is reached.
6750    ///
6751    /// This can be useful to know if it's possible to create a unidirectional
6752    /// stream without trying it first.
6753    #[inline]
6754    pub fn peer_streams_left_uni(&self) -> u64 {
6755        self.streams.peer_streams_left_uni()
6756    }
6757
6758    /// Returns an iterator over streams that have outstanding data to read.
6759    ///
6760    /// Note that the iterator will only include streams that were readable at
6761    /// the time the iterator itself was created (i.e. when `readable()` was
6762    /// called). To account for newly readable streams, the iterator needs to
6763    /// be created again.
6764    ///
6765    /// ## Examples:
6766    ///
6767    /// ```no_run
6768    /// # let mut buf = [0; 512];
6769    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6770    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6771    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6772    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6773    /// # let local = socket.local_addr().unwrap();
6774    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6775    /// // Iterate over readable streams.
6776    /// for stream_id in conn.readable() {
6777    ///     // Stream is readable, read until there's no more data.
6778    ///     while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
6779    ///         println!("Got {} bytes on stream {}", read, stream_id);
6780    ///     }
6781    /// }
6782    /// # Ok::<(), quiche::Error>(())
6783    /// ```
6784    #[inline]
6785    pub fn readable(&self) -> StreamIter {
6786        self.streams.readable()
6787    }
6788
6789    /// Returns an iterator over streams that can be written in priority order.
6790    ///
6791    /// The priority order is based on RFC 9218 scheduling recommendations.
6792    /// Stream priority can be controlled using [`stream_priority()`]. In order
6793    /// to support fairness requirements, each time this method is called,
6794    /// internal state is updated. Therefore the iterator ordering can change
6795    /// between calls, even if no streams were added or removed.
6796    ///
6797    /// A "writable" stream is a stream that has enough flow control capacity to
6798    /// send data to the peer. To avoid buffering an infinite amount of data,
6799    /// streams are only allowed to buffer outgoing data up to the amount that
6800    /// the peer allows to send.
6801    ///
6802    /// Stopped streams are also included so that a write or capacity query can
6803    /// return [`StreamStopped`], even without connection send capacity.
6804    ///
6805    /// Note that the iterator will only include streams that were writable at
6806    /// the time the iterator itself was created (i.e. when `writable()` was
6807    /// called). To account for newly writable streams, the iterator needs to be
6808    /// created again.
6809    ///
6810    /// ## Examples:
6811    ///
6812    /// ```no_run
6813    /// # let mut buf = [0; 512];
6814    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6815    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6816    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6817    /// # let local = socket.local_addr().unwrap();
6818    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6819    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6820    /// // Iterate over writable streams.
6821    /// for stream_id in conn.writable() {
6822    ///     // Stream is writable, write some data.
6823    ///     if let Ok(written) = conn.stream_send(stream_id, &buf, false) {
6824    ///         println!("Written {} bytes on stream {}", written, stream_id);
6825    ///     }
6826    /// }
6827    /// # Ok::<(), quiche::Error>(())
6828    /// ```
6829    /// [`stream_priority()`]: struct.Connection.html#method.stream_priority
6830    /// [`StreamStopped`]: enum.Error.html#variant.StreamStopped
6831    #[inline]
6832    pub fn writable(&self) -> StreamIter {
6833        // Stopped streams must be reported even without send capacity.
6834        if self.tx_cap == 0 {
6835            return self.streams.stopped_writable();
6836        }
6837
6838        self.streams.writable()
6839    }
6840
6841    /// Returns the maximum possible size of egress UDP payloads.
6842    ///
6843    /// This is the maximum size of UDP payloads that can be sent, and depends
6844    /// on both the configured maximum send payload size of the local endpoint
6845    /// (as configured with [`set_max_send_udp_payload_size()`]), as well as
6846    /// the transport parameter advertised by the remote peer.
6847    ///
6848    /// Note that this value can change during the lifetime of the connection,
6849    /// but should remain stable across consecutive calls to [`send()`].
6850    ///
6851    /// [`set_max_send_udp_payload_size()`]:
6852    ///     struct.Config.html#method.set_max_send_udp_payload_size
6853    /// [`send()`]: struct.Connection.html#method.send
6854    pub fn max_send_udp_payload_size(&self) -> usize {
6855        let max_datagram_size = self
6856            .paths
6857            .get_active()
6858            .ok()
6859            .map(|p| p.recovery.max_datagram_size());
6860
6861        if let Some(max_datagram_size) = max_datagram_size {
6862            if self.is_established() {
6863                // Cap the packet size at 16,383 bytes so a two-byte varint can
6864                // always encode it.
6865                return cmp::min(16383, max_datagram_size);
6866            }
6867        }
6868
6869        // Allow for 1200 bytes (minimum QUIC packet size) during the
6870        // handshake.
6871        MIN_CLIENT_INITIAL_LEN
6872    }
6873
6874    /// Schedule an ack-eliciting packet on the active path.
6875    ///
6876    /// QUIC packets might not contain ack-eliciting frames during normal
6877    /// operating conditions. If the packet would already contain
6878    /// ack-eliciting frames, this method does not change any behavior.
6879    /// However, if the packet would not ordinarily contain ack-eliciting
6880    /// frames, this method ensures that a PING frame sent.
6881    ///
6882    /// Calling this method multiple times before [`send()`] has no effect.
6883    ///
6884    /// [`send()`]: struct.Connection.html#method.send
6885    pub fn send_ack_eliciting(&mut self) -> Result<()> {
6886        if self.is_closed() || self.is_draining() {
6887            return Ok(());
6888        }
6889        self.paths.get_active_mut()?.needs_ack_eliciting = true;
6890        Ok(())
6891    }
6892
6893    /// Schedule an ack-eliciting packet on the specified path.
6894    ///
6895    /// See [`send_ack_eliciting()`] for more detail. [`InvalidState`] is
6896    /// returned if there is no record of the path.
6897    ///
6898    /// [`send_ack_eliciting()`]: struct.Connection.html#method.send_ack_eliciting
6899    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
6900    pub fn send_ack_eliciting_on_path(
6901        &mut self, local: SocketAddr, peer: SocketAddr,
6902    ) -> Result<()> {
6903        if self.is_closed() || self.is_draining() {
6904            return Ok(());
6905        }
6906        let path_id = self
6907            .paths
6908            .path_id_from_addrs(&(local, peer))
6909            .ok_or(Error::InvalidState)?;
6910        self.paths.get_mut(path_id)?.needs_ack_eliciting = true;
6911        Ok(())
6912    }
6913
6914    /// Reads the first received DATAGRAM.
6915    ///
6916    /// On success the DATAGRAM's data is returned along with its size.
6917    ///
6918    /// [`Done`] is returned if there is no data to read.
6919    ///
6920    /// [`BufferTooShort`] is returned if the provided buffer is too small for
6921    /// the DATAGRAM.
6922    ///
6923    /// [`Done`]: enum.Error.html#variant.Done
6924    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
6925    ///
6926    /// ## Examples:
6927    ///
6928    /// ```no_run
6929    /// # let mut buf = [0; 512];
6930    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
6931    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
6932    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
6933    /// # let peer = "127.0.0.1:1234".parse().unwrap();
6934    /// # let local = socket.local_addr().unwrap();
6935    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
6936    /// let mut dgram_buf = [0; 512];
6937    /// while let Ok((len)) = conn.dgram_recv(&mut dgram_buf) {
6938    ///     println!("Got {} bytes of DATAGRAM", len);
6939    /// }
6940    /// # Ok::<(), quiche::Error>(())
6941    /// ```
6942    #[inline]
6943    pub fn dgram_recv(&mut self, buf: &mut [u8]) -> Result<usize> {
6944        match self.dgram_recv_queue.pop() {
6945            Some(d) => {
6946                if d.as_ref().len() > buf.len() {
6947                    return Err(Error::BufferTooShort);
6948                }
6949                let len = d.as_ref().len();
6950
6951                buf[..len].copy_from_slice(d.as_ref());
6952                Ok(len)
6953            },
6954
6955            None => Err(Error::Done),
6956        }
6957    }
6958
6959    /// Reads the first received DATAGRAM.
6960    ///
6961    /// This is the same as [`dgram_recv()`] but returns the DATAGRAM as an
6962    /// owned buffer instead of copying into the provided buffer.
6963    ///
6964    /// [`dgram_recv()`]: struct.Connection.html#method.dgram_recv
6965    #[inline]
6966    pub fn dgram_recv_buf(&mut self) -> Result<F::DgramBuf> {
6967        self.dgram_recv_queue.pop().ok_or(Error::Done)
6968    }
6969
6970    /// Reads the first received DATAGRAM without removing it from the queue.
6971    ///
6972    /// On success the DATAGRAM's data is returned along with the actual number
6973    /// of bytes peeked. The requested length cannot exceed the DATAGRAM's
6974    /// actual length.
6975    ///
6976    /// [`Done`] is returned if there is no data to read.
6977    ///
6978    /// [`BufferTooShort`] is returned if the provided buffer is smaller the
6979    /// number of bytes to peek.
6980    ///
6981    /// [`Done`]: enum.Error.html#variant.Done
6982    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
6983    #[inline]
6984    pub fn dgram_recv_peek(&self, buf: &mut [u8], len: usize) -> Result<usize> {
6985        self.dgram_recv_queue.peek_front_bytes(buf, len)
6986    }
6987
6988    /// Returns the length of the first stored DATAGRAM.
6989    #[inline]
6990    pub fn dgram_recv_front_len(&self) -> Option<usize> {
6991        self.dgram_recv_queue.peek_front_len()
6992    }
6993
6994    /// Returns the number of items in the DATAGRAM receive queue.
6995    #[inline]
6996    pub fn dgram_recv_queue_len(&self) -> usize {
6997        self.dgram_recv_queue.len()
6998    }
6999
7000    /// Returns the total size of all items in the DATAGRAM receive queue.
7001    #[inline]
7002    pub fn dgram_recv_queue_byte_size(&self) -> usize {
7003        self.dgram_recv_queue.byte_size()
7004    }
7005
7006    /// Returns the number of items in the DATAGRAM send queue.
7007    #[inline]
7008    pub fn dgram_send_queue_len(&self) -> usize {
7009        self.dgram_send_queue.len()
7010    }
7011
7012    /// Returns the total size of all items in the DATAGRAM send queue.
7013    #[inline]
7014    pub fn dgram_send_queue_byte_size(&self) -> usize {
7015        self.dgram_send_queue.byte_size()
7016    }
7017
7018    /// Returns whether or not the DATAGRAM send queue is full.
7019    #[inline]
7020    pub fn is_dgram_send_queue_full(&self) -> bool {
7021        self.dgram_send_queue.is_full()
7022    }
7023
7024    /// Returns whether or not the DATAGRAM recv queue is full.
7025    #[inline]
7026    pub fn is_dgram_recv_queue_full(&self) -> bool {
7027        self.dgram_recv_queue.is_full()
7028    }
7029
7030    /// Sends data in a DATAGRAM frame.
7031    ///
7032    /// [`Done`] is returned if no data was written.
7033    /// [`InvalidState`] is returned if the peer does not support DATAGRAM.
7034    /// [`BufferTooShort`] is returned if the DATAGRAM frame length is larger
7035    /// than peer's supported DATAGRAM frame length. Use
7036    /// [`dgram_max_writable_len()`] to get the largest supported DATAGRAM
7037    /// frame length.
7038    ///
7039    /// Note that there is no flow control of DATAGRAM frames, so in order to
7040    /// avoid buffering an infinite amount of frames we apply an internal
7041    /// limit.
7042    ///
7043    /// [`Done`]: enum.Error.html#variant.Done
7044    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
7045    /// [`BufferTooShort`]: enum.Error.html#variant.BufferTooShort
7046    /// [`dgram_max_writable_len()`]:
7047    /// struct.Connection.html#method.dgram_max_writable_len
7048    ///
7049    /// ## Examples:
7050    ///
7051    /// ```no_run
7052    /// # let mut buf = [0; 512];
7053    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
7054    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
7055    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
7056    /// # let peer = "127.0.0.1:1234".parse().unwrap();
7057    /// # let local = socket.local_addr().unwrap();
7058    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
7059    /// conn.dgram_send(b"hello")?;
7060    /// # Ok::<(), quiche::Error>(())
7061    /// ```
7062    pub fn dgram_send(&mut self, buf: &[u8]) -> Result<()> {
7063        self.dgram_send_buf(F::dgram_buf_from_slice(buf))
7064    }
7065
7066    /// Sends data in a DATAGRAM frame.
7067    ///
7068    /// This is the same as [`dgram_send()`] but takes an owned buffer
7069    /// instead of a slice and avoids copying.
7070    ///
7071    /// [`dgram_send()`]: struct.Connection.html#method.dgram_send
7072    pub fn dgram_send_buf(&mut self, buf: F::DgramBuf) -> Result<()> {
7073        let max_payload_len = match self.dgram_max_writable_len() {
7074            Some(v) => v,
7075
7076            None => return Err(Error::InvalidState),
7077        };
7078
7079        if buf.as_ref().len() > max_payload_len {
7080            return Err(Error::BufferTooShort);
7081        }
7082
7083        self.dgram_send_queue.push(buf)?;
7084
7085        let active_path = self.paths.get_active_mut()?;
7086
7087        if self.dgram_send_queue.byte_size() >
7088            active_path.recovery.cwnd_available()
7089        {
7090            active_path.recovery.update_app_limited(false);
7091        }
7092
7093        Ok(())
7094    }
7095
7096    /// Purges queued outgoing DATAGRAMs matching the predicate.
7097    ///
7098    /// In other words, remove all elements `e` such that `f(&e)` returns true.
7099    ///
7100    /// ## Examples:
7101    /// ```no_run
7102    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
7103    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
7104    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
7105    /// # let peer = "127.0.0.1:1234".parse().unwrap();
7106    /// # let local = socket.local_addr().unwrap();
7107    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
7108    /// conn.dgram_send(b"hello")?;
7109    /// conn.dgram_purge_outgoing(&|d: &[u8]| -> bool { d[0] == 0 });
7110    /// # Ok::<(), quiche::Error>(())
7111    /// ```
7112    #[inline]
7113    pub fn dgram_purge_outgoing<FN: Fn(&[u8]) -> bool>(&mut self, f: FN) {
7114        self.dgram_send_queue.purge(f);
7115    }
7116
7117    /// Returns the maximum DATAGRAM payload that can be sent.
7118    ///
7119    /// [`None`] is returned if the peer hasn't advertised a maximum DATAGRAM
7120    /// frame size.
7121    ///
7122    /// ## Examples:
7123    ///
7124    /// ```no_run
7125    /// # let mut buf = [0; 512];
7126    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
7127    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
7128    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
7129    /// # let peer = "127.0.0.1:1234".parse().unwrap();
7130    /// # let local = socket.local_addr().unwrap();
7131    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
7132    /// if let Some(payload_size) = conn.dgram_max_writable_len() {
7133    ///     if payload_size > 5 {
7134    ///         conn.dgram_send(b"hello")?;
7135    ///     }
7136    /// }
7137    /// # Ok::<(), quiche::Error>(())
7138    /// ```
7139    #[inline]
7140    pub fn dgram_max_writable_len(&self) -> Option<usize> {
7141        match self.peer_transport_params.max_datagram_frame_size {
7142            None => None,
7143            Some(peer_frame_len) => {
7144                let dcid = self.destination_id();
7145                // Start from the maximum packet size...
7146                let mut max_len = self.max_send_udp_payload_size();
7147                // ...subtract the Short packet header overhead...
7148                // (1 byte of pkt_len + len of dcid)
7149                max_len = max_len.saturating_sub(1 + dcid.len());
7150                // ...subtract the packet number (max len)...
7151                max_len = max_len.saturating_sub(packet::MAX_PKT_NUM_LEN);
7152                // ...subtract the crypto overhead...
7153                max_len = max_len.saturating_sub(
7154                    self.crypto_ctx[packet::Epoch::Application]
7155                        .crypto_overhead()?,
7156                );
7157                // ...clamp to what peer can support...
7158                max_len = cmp::min(peer_frame_len as usize, max_len);
7159                // ...subtract frame overhead, checked for underflow.
7160                // (1 byte of frame type + len of length )
7161                max_len.checked_sub(1 + frame::MAX_DGRAM_OVERHEAD)
7162            },
7163        }
7164    }
7165
7166    fn dgram_enabled(&self) -> bool {
7167        self.local_transport_params
7168            .max_datagram_frame_size
7169            .is_some()
7170    }
7171
7172    /// Returns when the next timeout event will occur.
7173    ///
7174    /// Once the timeout Instant has been reached, the [`on_timeout()`] method
7175    /// should be called. A timeout of `None` means that the timer should be
7176    /// disarmed.
7177    ///
7178    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
7179    pub fn timeout_instant(&self) -> Option<Instant> {
7180        if self.is_closed() {
7181            return None;
7182        }
7183
7184        if self.is_draining() {
7185            // Draining timer takes precedence over all other timers. If it is
7186            // set it means the connection is closing so there's no point in
7187            // processing the other timers.
7188            self.draining_timer
7189        } else {
7190            // Use the lowest timer value (i.e. "sooner") among idle and loss
7191            // detection timers. If they are both unset (i.e. `None`) then the
7192            // result is `None`, but if at least one of them is set then a
7193            // `Some(...)` value is returned.
7194            let path_timer = self
7195                .paths
7196                .iter()
7197                .filter_map(|(_, p)| p.recovery.loss_detection_timer())
7198                .min();
7199
7200            let key_update_timer = self.crypto_ctx[packet::Epoch::Application]
7201                .key_update
7202                .as_ref()
7203                .map(|key_update| key_update.timer);
7204
7205            let timers = [self.idle_timer, path_timer, key_update_timer];
7206
7207            timers.iter().filter_map(|&x| x).min()
7208        }
7209    }
7210
7211    /// Returns the amount of time until the next timeout event.
7212    ///
7213    /// Once the given duration has elapsed, the [`on_timeout()`] method should
7214    /// be called. A timeout of `None` means that the timer should be disarmed.
7215    ///
7216    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
7217    pub fn timeout(&self) -> Option<Duration> {
7218        self.timeout_instant().map(|timeout| {
7219            let now = Instant::now();
7220
7221            if timeout <= now {
7222                Duration::ZERO
7223            } else {
7224                timeout.duration_since(now)
7225            }
7226        })
7227    }
7228
7229    /// Processes a timeout event.
7230    ///
7231    /// If no timeout has occurred it does nothing.
7232    pub fn on_timeout(&mut self) {
7233        let now = Instant::now();
7234
7235        if let Some(draining_timer) = self.draining_timer {
7236            if draining_timer <= now {
7237                trace!("{} draining timeout expired", self.trace_id);
7238
7239                self.mark_closed();
7240            }
7241
7242            // Draining timer takes precedence over all other timers. If it is
7243            // set it means the connection is closing so there's no point in
7244            // processing the other timers.
7245            return;
7246        }
7247
7248        if let Some(timer) = self.idle_timer {
7249            if timer <= now {
7250                trace!("{} idle timeout expired", self.trace_id);
7251
7252                self.mark_closed();
7253                self.timed_out = true;
7254                return;
7255            }
7256        }
7257
7258        if let Some(timer) = self.crypto_ctx[packet::Epoch::Application]
7259            .key_update
7260            .as_ref()
7261            .map(|key_update| key_update.timer)
7262        {
7263            if timer <= now {
7264                // Discard previous key once key update timer expired.
7265                let _ = self.crypto_ctx[packet::Epoch::Application]
7266                    .key_update
7267                    .take();
7268            }
7269        }
7270
7271        let handshake_status = self.handshake_status();
7272
7273        for (_, p) in self.paths.iter_mut() {
7274            if let Some(timer) = p.recovery.loss_detection_timer() {
7275                if timer <= now {
7276                    trace!("{} loss detection timeout expired", self.trace_id);
7277
7278                    let OnLossDetectionTimeoutOutcome {
7279                        lost_packets,
7280                        lost_bytes,
7281                    } = p.on_loss_detection_timeout(
7282                        handshake_status,
7283                        now,
7284                        self.is_server,
7285                        &self.trace_id,
7286                    );
7287
7288                    self.lost_count += lost_packets;
7289                    self.lost_bytes += lost_bytes as u64;
7290
7291                    qlog_with_type!(QLOG_METRICS, self.qlog, q, {
7292                        p.recovery.maybe_qlog(q, now);
7293                    });
7294                }
7295            }
7296        }
7297
7298        // Notify timeout events to the application.
7299        self.paths.notify_failed_validations();
7300
7301        // If the active path failed, try to find a new candidate.
7302        if self.paths.get_active_path_id().is_err() {
7303            match self.paths.find_candidate_path() {
7304                Some(pid) => {
7305                    if self.set_active_path(pid, now).is_err() {
7306                        // The connection cannot continue.
7307                        self.mark_closed();
7308                    }
7309                },
7310
7311                // The connection cannot continue.
7312                None => {
7313                    self.mark_closed();
7314                },
7315            }
7316        }
7317    }
7318
7319    /// Requests the stack to perform path validation of the proposed 4-tuple.
7320    ///
7321    /// Probing new paths requires spare Connection IDs at both the host and the
7322    /// peer sides. If it is not the case, it raises an [`OutOfIdentifiers`].
7323    ///
7324    /// The probing of new addresses can only be done by the client. The server
7325    /// can only probe network paths that were previously advertised by
7326    /// [`PathEvent::New`]. If the server tries to probe such an unseen network
7327    /// path, this call raises an [`InvalidState`].
7328    ///
7329    /// The caller might also want to probe an existing path. In such case, it
7330    /// triggers a PATH_CHALLENGE frame, but it does not require spare CIDs.
7331    ///
7332    /// A server always probes a new path it observes. Calling this method is
7333    /// hence not required to validate a new path. However, a server can still
7334    /// request an additional path validation of the proposed 4-tuple.
7335    ///
7336    /// Calling this method several times before calling [`send()`] or
7337    /// [`send_on_path()`] results in a single probe being generated. An
7338    /// application wanting to send multiple in-flight probes must call this
7339    /// method again after having sent packets.
7340    ///
7341    /// Returns the Destination Connection ID sequence number associated to that
7342    /// path.
7343    ///
7344    /// [`PathEvent::New`]: enum.PathEvent.html#variant.New
7345    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
7346    /// [`InvalidState`]: enum.Error.html#InvalidState
7347    /// [`send()`]: struct.Connection.html#method.send
7348    /// [`send_on_path()`]: struct.Connection.html#method.send_on_path
7349    pub fn probe_path(
7350        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
7351    ) -> Result<u64> {
7352        // We may want to probe an existing path.
7353        let pid = match self.paths.path_id_from_addrs(&(local_addr, peer_addr)) {
7354            Some(pid) => pid,
7355            None => self.create_path_on_client(local_addr, peer_addr)?,
7356        };
7357
7358        let path = self.paths.get_mut(pid)?;
7359        path.request_validation();
7360
7361        path.active_dcid_seq.ok_or(Error::InvalidState)
7362    }
7363
7364    /// Migrates the connection to a new local address `local_addr`.
7365    ///
7366    /// The behavior is similar to [`migrate()`], with the nuance that the
7367    /// connection only changes the local address, but not the peer one.
7368    ///
7369    /// See [`migrate()`] for the full specification of this method.
7370    ///
7371    /// [`migrate()`]: struct.Connection.html#method.migrate
7372    pub fn migrate_source(&mut self, local_addr: SocketAddr) -> Result<u64> {
7373        let peer_addr = self.paths.get_active()?.peer_addr();
7374        self.migrate(local_addr, peer_addr)
7375    }
7376
7377    /// Migrates the connection over the given network path between `local_addr`
7378    /// and `peer_addr`.
7379    ///
7380    /// Connection migration can only be initiated by the client. Calling this
7381    /// method as a server returns [`InvalidState`].
7382    ///
7383    /// To initiate voluntary migration, there should be enough Connection IDs
7384    /// at both sides. If this requirement is not satisfied, this call returns
7385    /// [`OutOfIdentifiers`].
7386    ///
7387    /// Returns the Destination Connection ID associated to that migrated path.
7388    ///
7389    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
7390    /// [`InvalidState`]: enum.Error.html#InvalidState
7391    pub fn migrate(
7392        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
7393    ) -> Result<u64> {
7394        if self.is_server {
7395            return Err(Error::InvalidState);
7396        }
7397
7398        // If the path already exists, mark it as the active one.
7399        let (pid, dcid_seq) = if let Some(pid) =
7400            self.paths.path_id_from_addrs(&(local_addr, peer_addr))
7401        {
7402            let path = self.paths.get_mut(pid)?;
7403
7404            // If it is already active, do nothing.
7405            if path.active() {
7406                return path.active_dcid_seq.ok_or(Error::OutOfIdentifiers);
7407            }
7408
7409            // Ensures that a Source Connection ID has been dedicated to this
7410            // path, or a free one is available. This is only required if the
7411            // host uses non-zero length Source Connection IDs.
7412            if !self.ids.zero_length_scid() &&
7413                path.active_scid_seq.is_none() &&
7414                self.ids.available_scids() == 0
7415            {
7416                return Err(Error::OutOfIdentifiers);
7417            }
7418
7419            // Ensures that the migrated path has a Destination Connection ID.
7420            let dcid_seq = if let Some(dcid_seq) = path.active_dcid_seq {
7421                dcid_seq
7422            } else {
7423                let dcid_seq = self
7424                    .ids
7425                    .lowest_available_dcid_seq()
7426                    .ok_or(Error::OutOfIdentifiers)?;
7427
7428                self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
7429                path.active_dcid_seq = Some(dcid_seq);
7430
7431                dcid_seq
7432            };
7433
7434            (pid, dcid_seq)
7435        } else {
7436            let pid = self.create_path_on_client(local_addr, peer_addr)?;
7437
7438            let dcid_seq = self
7439                .paths
7440                .get(pid)?
7441                .active_dcid_seq
7442                .ok_or(Error::InvalidState)?;
7443
7444            (pid, dcid_seq)
7445        };
7446
7447        // Change the active path.
7448        self.set_active_path(pid, Instant::now())?;
7449
7450        Ok(dcid_seq)
7451    }
7452
7453    /// Provides additional source Connection IDs that the peer can use to reach
7454    /// this host.
7455    ///
7456    /// This triggers sending NEW_CONNECTION_ID frames if the provided Source
7457    /// Connection ID is not already present. In the case the caller tries to
7458    /// reuse a Connection ID with a different reset token, this raises an
7459    /// `InvalidState`.
7460    ///
7461    /// At any time, the peer cannot have more Destination Connection IDs than
7462    /// the maximum number of active Connection IDs it negotiated. In such case
7463    /// (i.e., when [`scids_left()`] returns 0), if the host agrees to
7464    /// request the removal of previous connection IDs, it sets the
7465    /// `retire_if_needed` parameter. Otherwise, an [`IdLimit`] is returned.
7466    ///
7467    /// Note that setting `retire_if_needed` does not prevent this function from
7468    /// returning an [`IdLimit`] in the case the caller wants to retire still
7469    /// unannounced Connection IDs.
7470    ///
7471    /// The caller is responsible for ensuring that the provided `scid` is not
7472    /// repeated several times over the connection. quiche ensures that as long
7473    /// as the provided Connection ID is still in use (i.e., not retired), it
7474    /// does not assign a different sequence number.
7475    ///
7476    /// Note that if the host uses zero-length Source Connection IDs, it cannot
7477    /// advertise Source Connection IDs and calling this method returns an
7478    /// [`InvalidState`].
7479    ///
7480    /// Returns the sequence number associated to the provided Connection ID.
7481    ///
7482    /// [`scids_left()`]: struct.Connection.html#method.scids_left
7483    /// [`IdLimit`]: enum.Error.html#IdLimit
7484    /// [`InvalidState`]: enum.Error.html#InvalidState
7485    pub fn new_scid(
7486        &mut self, scid: &ConnectionId, reset_token: u128, retire_if_needed: bool,
7487    ) -> Result<u64> {
7488        self.ids.new_scid(
7489            scid.to_vec().into(),
7490            Some(reset_token),
7491            true,
7492            None,
7493            retire_if_needed,
7494        )
7495    }
7496
7497    /// Returns the number of source Connection IDs that are active. This is
7498    /// only meaningful if the host uses non-zero length Source Connection IDs.
7499    pub fn active_scids(&self) -> usize {
7500        self.ids.active_source_cids()
7501    }
7502
7503    /// Returns the number of additional source Connection IDs that can be
7504    /// provided to the peer without exceeding the limit it advertised.
7505    ///
7506    /// The limit is the minimum of the locally configured active connection
7507    /// ID limit and the one sent by the peer.
7508    ///
7509    /// Returns `0` when the peer's limit is already reached or temporarily
7510    /// exceeded (e.g. during a SCID rotation where a retirement is in
7511    /// flight and `active_scids()` transiently exceeds the advertised
7512    /// limit).
7513    ///
7514    /// To obtain the maximum possible value allowed by the peer an application
7515    /// can instead inspect the [`peer_active_conn_id_limit`] value.
7516    ///
7517    /// [`peer_active_conn_id_limit`]: struct.Stats.html#structfield.peer_active_conn_id_limit
7518    #[inline]
7519    pub fn scids_left(&self) -> usize {
7520        let max_active_source_cids = cmp::min(
7521            self.peer_transport_params.active_conn_id_limit,
7522            self.local_transport_params.active_conn_id_limit,
7523        ) as usize;
7524
7525        max_active_source_cids.saturating_sub(self.active_scids())
7526    }
7527
7528    /// Requests the retirement of the destination Connection ID used by the
7529    /// host to reach its peer.
7530    ///
7531    /// This triggers sending RETIRE_CONNECTION_ID frames.
7532    ///
7533    /// If the application tries to retire a non-existing Destination Connection
7534    /// ID sequence number, or if it uses zero-length Destination Connection ID,
7535    /// this method returns an [`InvalidState`].
7536    ///
7537    /// At any time, the host must have at least one Destination ID. If the
7538    /// application tries to retire the last one, or if the caller tries to
7539    /// retire the destination Connection ID used by the current active path
7540    /// while having neither spare Destination Connection IDs nor validated
7541    /// network paths, this method returns an [`OutOfIdentifiers`]. This
7542    /// behavior prevents the caller from stalling the connection due to the
7543    /// lack of validated path to send non-probing packets.
7544    ///
7545    /// [`InvalidState`]: enum.Error.html#InvalidState
7546    /// [`OutOfIdentifiers`]: enum.Error.html#OutOfIdentifiers
7547    pub fn retire_dcid(&mut self, dcid_seq: u64) -> Result<()> {
7548        if self.ids.zero_length_dcid() {
7549            return Err(Error::InvalidState);
7550        }
7551
7552        let active_path_dcid_seq = self
7553            .paths
7554            .get_active()?
7555            .active_dcid_seq
7556            .ok_or(Error::InvalidState)?;
7557
7558        let active_path_id = self.paths.get_active_path_id()?;
7559
7560        if active_path_dcid_seq == dcid_seq &&
7561            self.ids.lowest_available_dcid_seq().is_none() &&
7562            !self
7563                .paths
7564                .iter()
7565                .any(|(pid, p)| pid != active_path_id && p.usable())
7566        {
7567            return Err(Error::OutOfIdentifiers);
7568        }
7569
7570        if let Some(pid) = self.ids.retire_dcid(dcid_seq)? {
7571            // The retired Destination CID was associated to a given path. Let's
7572            // find an available DCID to associate to that path.
7573            let path = self.paths.get_mut(pid)?;
7574            let dcid_seq = self.ids.lowest_available_dcid_seq();
7575
7576            if let Some(dcid_seq) = dcid_seq {
7577                self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
7578            }
7579
7580            path.active_dcid_seq = dcid_seq;
7581        }
7582
7583        Ok(())
7584    }
7585
7586    /// Processes path-specific events.
7587    ///
7588    /// On success it returns a [`PathEvent`], or `None` when there are no
7589    /// events to report. Please refer to [`PathEvent`] for the exhaustive event
7590    /// list.
7591    ///
7592    /// Note that all events are edge-triggered, meaning that once reported they
7593    /// will not be reported again by calling this method again, until the event
7594    /// is re-armed.
7595    ///
7596    /// [`PathEvent`]: enum.PathEvent.html
7597    pub fn path_event_next(&mut self) -> Option<PathEvent> {
7598        self.paths.pop_event()
7599    }
7600
7601    /// Returns the number of source Connection IDs that are retired.
7602    pub fn retired_scids(&self) -> usize {
7603        self.ids.retired_source_cids()
7604    }
7605
7606    /// Returns a source `ConnectionId` that has been retired.
7607    ///
7608    /// On success it returns a [`ConnectionId`], or `None` when there are no
7609    /// more retired connection IDs.
7610    ///
7611    /// [`ConnectionId`]: struct.ConnectionId.html
7612    pub fn retired_scid_next(&mut self) -> Option<ConnectionId<'static>> {
7613        self.ids.pop_retired_scid()
7614    }
7615
7616    /// Returns the number of spare Destination Connection IDs, i.e.,
7617    /// Destination Connection IDs that are still unused.
7618    ///
7619    /// Note that this function returns 0 if the host uses zero length
7620    /// Destination Connection IDs.
7621    pub fn available_dcids(&self) -> usize {
7622        self.ids.available_dcids()
7623    }
7624
7625    /// Returns an iterator over destination `SockAddr`s whose association
7626    /// with `from` forms a known QUIC path on which packets can be sent to.
7627    ///
7628    /// This function is typically used in combination with [`send_on_path()`].
7629    ///
7630    /// Note that the iterator includes all the possible combination of
7631    /// destination `SockAddr`s, even those whose sending is not required now.
7632    /// In other words, this is another way for the application to recall from
7633    /// past [`PathEvent::New`] events.
7634    ///
7635    /// [`PathEvent::New`]: enum.PathEvent.html#variant.New
7636    /// [`send_on_path()`]: struct.Connection.html#method.send_on_path
7637    ///
7638    /// ## Examples:
7639    ///
7640    /// ```no_run
7641    /// # let mut out = [0; 512];
7642    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
7643    /// # let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
7644    /// # let scid = quiche::ConnectionId::from_ref(&[0xba; 16]);
7645    /// # let local = socket.local_addr().unwrap();
7646    /// # let peer = "127.0.0.1:1234".parse().unwrap();
7647    /// # let mut conn = quiche::accept(&scid, None, local, peer, &mut config)?;
7648    /// // Iterate over possible destinations for the given local `SockAddr`.
7649    /// for dest in conn.paths_iter(local) {
7650    ///     loop {
7651    ///         let (write, send_info) =
7652    ///             match conn.send_on_path(&mut out, Some(local), Some(dest)) {
7653    ///                 Ok(v) => v,
7654    ///
7655    ///                 Err(quiche::Error::Done) => {
7656    ///                     // Done writing for this destination.
7657    ///                     break;
7658    ///                 },
7659    ///
7660    ///                 Err(e) => {
7661    ///                     // An error occurred, handle it.
7662    ///                     break;
7663    ///                 },
7664    ///             };
7665    ///
7666    ///         socket.send_to(&out[..write], &send_info.to).unwrap();
7667    ///     }
7668    /// }
7669    /// # Ok::<(), quiche::Error>(())
7670    /// ```
7671    #[inline]
7672    pub fn paths_iter(&self, from: SocketAddr) -> SocketAddrIter {
7673        // Instead of trying to identify whether packets will be sent on the
7674        // given 4-tuple, simply filter paths that cannot be used.
7675        SocketAddrIter {
7676            sockaddrs: self
7677                .paths
7678                .iter()
7679                .filter(|(_, p)| p.active_dcid_seq.is_some())
7680                .filter(|(_, p)| p.usable() || p.probing_required())
7681                .filter(|(_, p)| p.local_addr() == from)
7682                .map(|(_, p)| p.peer_addr())
7683                .collect(),
7684
7685            index: 0,
7686        }
7687    }
7688
7689    /// Closes the connection with the given error and reason.
7690    ///
7691    /// The `app` parameter specifies whether an application close should be
7692    /// sent to the peer. Otherwise a normal connection close is sent.
7693    ///
7694    /// If `app` is true but the connection is not in a state that is safe to
7695    /// send an application error (not established nor in early data), in
7696    /// accordance with [RFC
7697    /// 9000](https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.3-3), the
7698    /// error code is changed to APPLICATION_ERROR and the reason phrase is
7699    /// cleared.
7700    ///
7701    /// Returns [`Done`] if the connection had already been closed.
7702    ///
7703    /// Note that the connection will not be closed immediately. An application
7704    /// should continue calling the [`recv()`], [`send()`], [`timeout()`] and
7705    /// [`on_timeout()`] methods as normal, until the [`is_closed()`] method
7706    /// returns `true`.
7707    ///
7708    /// [`Done`]: enum.Error.html#variant.Done
7709    /// [`recv()`]: struct.Connection.html#method.recv
7710    /// [`send()`]: struct.Connection.html#method.send
7711    /// [`timeout()`]: struct.Connection.html#method.timeout
7712    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
7713    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7714    pub fn close(&mut self, app: bool, err: u64, reason: &[u8]) -> Result<()> {
7715        if self.is_closed() || self.is_draining() {
7716            return Err(Error::Done);
7717        }
7718
7719        if self.local_error.is_some() {
7720            return Err(Error::Done);
7721        }
7722
7723        let is_safe_to_send_app_data =
7724            self.is_established() || self.is_in_early_data();
7725
7726        if app && !is_safe_to_send_app_data {
7727            // Clear error information.
7728            self.local_error = Some(ConnectionError {
7729                is_app: false,
7730                error_code: 0x0c,
7731                reason: vec![],
7732            });
7733        } else {
7734            self.local_error = Some(ConnectionError {
7735                is_app: app,
7736                error_code: err,
7737                reason: reason.to_vec(),
7738            });
7739        }
7740
7741        // Close immediately if no packet was processed successfully.
7742        if self.recv_count == 0 {
7743            self.mark_closed();
7744        }
7745
7746        Ok(())
7747    }
7748
7749    /// Returns a string uniquely representing the connection.
7750    ///
7751    /// This can be used for logging purposes to differentiate between multiple
7752    /// connections.
7753    #[inline]
7754    pub fn trace_id(&self) -> &str {
7755        &self.trace_id
7756    }
7757
7758    /// Returns the negotiated ALPN protocol.
7759    ///
7760    /// If no protocol has been negotiated, the returned value is empty.
7761    #[inline]
7762    pub fn application_proto(&self) -> &[u8] {
7763        self.alpn.as_ref()
7764    }
7765
7766    /// Returns the server name requested by the client.
7767    #[inline]
7768    pub fn server_name(&self) -> Option<&str> {
7769        self.handshake.server_name()
7770    }
7771
7772    /// Returns the peer's leaf certificate (if any) as a DER-encoded buffer.
7773    #[inline]
7774    pub fn peer_cert(&self) -> Option<&[u8]> {
7775        self.handshake.peer_cert()
7776    }
7777
7778    /// Returns the peer's certificate chain (if any) as a vector of DER-encoded
7779    /// buffers.
7780    ///
7781    /// The certificate at index 0 is the peer's leaf certificate, the other
7782    /// certificates (if any) are the chain certificate authorities used to
7783    /// sign the leaf certificate.
7784    #[inline]
7785    pub fn peer_cert_chain(&self) -> Option<Vec<&[u8]>> {
7786        self.handshake.peer_cert_chain()
7787    }
7788
7789    /// Returns the serialized cryptographic session for the connection.
7790    ///
7791    /// This can be used by a client to cache a connection's session, and resume
7792    /// it later using the [`set_session()`] method.
7793    ///
7794    /// [`set_session()`]: struct.Connection.html#method.set_session
7795    #[inline]
7796    pub fn session(&self) -> Option<&[u8]> {
7797        self.session.as_deref()
7798    }
7799
7800    /// Returns the source connection ID.
7801    ///
7802    /// When there are multiple IDs, and if there is an active path, the ID used
7803    /// on that path is returned. Otherwise the oldest ID is returned.
7804    ///
7805    /// Note that the value returned can change throughout the connection's
7806    /// lifetime.
7807    #[inline]
7808    pub fn source_id(&self) -> ConnectionId<'_> {
7809        if let Ok(path) = self.paths.get_active() {
7810            if let Some(active_scid_seq) = path.active_scid_seq {
7811                if let Ok(e) = self.ids.get_scid(active_scid_seq) {
7812                    return ConnectionId::from_ref(e.cid.as_ref());
7813                }
7814            }
7815        }
7816
7817        let e = self.ids.oldest_scid();
7818        ConnectionId::from_ref(e.cid.as_ref())
7819    }
7820
7821    /// Returns all active source connection IDs.
7822    ///
7823    /// An iterator is returned for all active IDs (i.e. ones that have not
7824    /// been explicitly retired yet).
7825    #[inline]
7826    pub fn source_ids(&self) -> impl Iterator<Item = &ConnectionId<'_>> {
7827        self.ids.scids_iter()
7828    }
7829
7830    /// Returns the destination connection ID.
7831    ///
7832    /// Note that the value returned can change throughout the connection's
7833    /// lifetime.
7834    #[inline]
7835    pub fn destination_id(&self) -> ConnectionId<'_> {
7836        if let Ok(path) = self.paths.get_active() {
7837            if let Some(active_dcid_seq) = path.active_dcid_seq {
7838                if let Ok(e) = self.ids.get_dcid(active_dcid_seq) {
7839                    return ConnectionId::from_ref(e.cid.as_ref());
7840                }
7841            }
7842        }
7843
7844        let e = self.ids.oldest_dcid();
7845        ConnectionId::from_ref(e.cid.as_ref())
7846    }
7847
7848    /// Returns the PMTU for the active path if it exists.
7849    ///
7850    /// This requires no additonal packets to be sent but simply checks if PMTUD
7851    /// has completed and has found a valid PMTU.
7852    #[inline]
7853    pub fn pmtu(&self) -> Option<usize> {
7854        if let Ok(path) = self.paths.get_active() {
7855            path.pmtud.as_ref().and_then(|pmtud| pmtud.get_pmtu())
7856        } else {
7857            None
7858        }
7859    }
7860
7861    /// Revalidates the PMTU for the active path by sending a new probe packet
7862    /// of PMTU size. If the probe is dropped PMTUD will restart and find a new
7863    /// valid PMTU.
7864    ///
7865    /// If revalidation invalidates a previously discovered larger size, a
7866    /// [`PathEvent::PmtuUpdated`] event is queued with QUIC's minimum packet
7867    /// size. Further events report larger sizes as probes validate them.
7868    #[inline]
7869    pub fn revalidate_pmtu(&mut self) {
7870        let Ok(active_path) = self.paths.get_active_mut() else {
7871            return;
7872        };
7873
7874        let local = active_path.local_addr();
7875        let peer = active_path.peer_addr();
7876        let Some(pmtud) = active_path.pmtud.as_mut() else {
7877            return;
7878        };
7879
7880        let old_pmtu = pmtud.get_current_mtu();
7881        pmtud.revalidate_pmtu();
7882
7883        let Some(event) =
7884            path::pmtu_event(local, peer, old_pmtu, pmtud.get_current_mtu())
7885        else {
7886            return;
7887        };
7888
7889        self.paths.notify_event(event);
7890    }
7891
7892    /// Returns true if the connection handshake is complete.
7893    #[inline]
7894    pub fn is_established(&self) -> bool {
7895        self.handshake_completed
7896    }
7897
7898    /// Returns true if the connection is resumed.
7899    #[inline]
7900    pub fn is_resumed(&self) -> bool {
7901        self.handshake.is_resumed()
7902    }
7903
7904    /// Returns true if the connection has a pending handshake that has
7905    /// progressed enough to send or receive early data.
7906    #[inline]
7907    pub fn is_in_early_data(&self) -> bool {
7908        self.handshake.is_in_early_data()
7909    }
7910
7911    /// Returns the early data reason for the connection.
7912    ///
7913    /// This status can be useful for logging and debugging. See [BoringSSL]
7914    /// documentation for a definition of the reasons.
7915    ///
7916    /// [BoringSSL]: https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_early_data_reason_t
7917    #[inline]
7918    pub fn early_data_reason(&self) -> u32 {
7919        self.handshake.early_data_reason()
7920    }
7921
7922    /// Returns whether there is stream or DATAGRAM data available to read.
7923    #[inline]
7924    pub fn is_readable(&self) -> bool {
7925        self.streams.has_readable() || self.dgram_recv_front_len().is_some()
7926    }
7927
7928    /// Returns whether the network path with local address `from` and remote
7929    /// address `peer` has been validated.
7930    ///
7931    /// If the 4-tuple does not exist over the connection, returns an
7932    /// [`InvalidState`].
7933    ///
7934    /// [`InvalidState`]: enum.Error.html#variant.InvalidState
7935    pub fn is_path_validated(
7936        &self, from: SocketAddr, to: SocketAddr,
7937    ) -> Result<bool> {
7938        let pid = self
7939            .paths
7940            .path_id_from_addrs(&(from, to))
7941            .ok_or(Error::InvalidState)?;
7942
7943        Ok(self.paths.get(pid)?.validated())
7944    }
7945
7946    /// Returns true if the connection is draining.
7947    ///
7948    /// If this returns `true`, the connection object cannot yet be dropped, but
7949    /// no new application data can be sent or received. An application should
7950    /// continue calling the [`recv()`], [`timeout()`], and [`on_timeout()`]
7951    /// methods as normal, until the [`is_closed()`] method returns `true`.
7952    ///
7953    /// In contrast, once `is_draining()` returns `true`, calling [`send()`]
7954    /// is not required because no new outgoing packets will be generated.
7955    ///
7956    /// [`recv()`]: struct.Connection.html#method.recv
7957    /// [`send()`]: struct.Connection.html#method.send
7958    /// [`timeout()`]: struct.Connection.html#method.timeout
7959    /// [`on_timeout()`]: struct.Connection.html#method.on_timeout
7960    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7961    #[inline]
7962    pub fn is_draining(&self) -> bool {
7963        self.draining_timer.is_some()
7964    }
7965
7966    /// Returns true if the connection is closed.
7967    ///
7968    /// If this returns true, the connection object can be dropped.
7969    #[inline]
7970    pub fn is_closed(&self) -> bool {
7971        self.closed
7972    }
7973
7974    /// Returns true if the connection was closed due to the idle timeout.
7975    #[inline]
7976    pub fn is_timed_out(&self) -> bool {
7977        self.timed_out
7978    }
7979
7980    /// Returns the error received from the peer, if any.
7981    ///
7982    /// Note that a `Some` return value does not necessarily imply
7983    /// [`is_closed()`] or any other connection state.
7984    ///
7985    /// [`is_closed()`]: struct.Connection.html#method.is_closed
7986    #[inline]
7987    pub fn peer_error(&self) -> Option<&ConnectionError> {
7988        self.peer_error.as_ref()
7989    }
7990
7991    /// Returns the error [`close()`] was called with, or internally
7992    /// created quiche errors, if any.
7993    ///
7994    /// Note that a `Some` return value does not necessarily imply
7995    /// [`is_closed()`] or any other connection state.
7996    /// `Some` also does not guarantee that the error has been sent to
7997    /// or received by the peer.
7998    ///
7999    /// [`close()`]: struct.Connection.html#method.close
8000    /// [`is_closed()`]: struct.Connection.html#method.is_closed
8001    #[inline]
8002    pub fn local_error(&self) -> Option<&ConnectionError> {
8003        self.local_error.as_ref()
8004    }
8005
8006    /// Collects and returns statistics about the connection.
8007    #[inline]
8008    pub fn stats(&self) -> Stats {
8009        Stats {
8010            recv: self.recv_count,
8011            sent: self.sent_count,
8012            lost: self.lost_count,
8013            spurious_lost: self.spurious_lost_count,
8014            retrans: self.retrans_count,
8015            sent_bytes: self.sent_bytes,
8016            recv_bytes: self.recv_bytes,
8017            acked_bytes: self.acked_bytes,
8018            lost_bytes: self.lost_bytes,
8019            stream_retrans_bytes: self.stream_retrans_bytes,
8020            dgram_recv: self.dgram_recv_count,
8021            dgram_sent: self.dgram_sent_count,
8022            paths_count: self.paths.len(),
8023            reset_stream_count_local: self.reset_stream_local_count,
8024            stopped_stream_count_local: self.stopped_stream_local_count,
8025            reset_stream_count_remote: self.reset_stream_remote_count,
8026            stopped_stream_count_remote: self.stopped_stream_remote_count,
8027            data_blocked_sent_count: self.data_blocked_sent_count,
8028            stream_data_blocked_sent_count: self.stream_data_blocked_sent_count,
8029            data_blocked_recv_count: self.data_blocked_recv_count,
8030            stream_data_blocked_recv_count: self.stream_data_blocked_recv_count,
8031            streams_blocked_bidi_recv_count: self.streams_blocked_bidi_recv_count,
8032            streams_blocked_uni_recv_count: self.streams_blocked_uni_recv_count,
8033            path_challenge_rx_count: self.path_challenge_rx_count,
8034            amplification_limited_count: self.amplification_limited_count,
8035            bytes_in_flight_duration: self.bytes_in_flight_duration(),
8036            tx_buffered_state: if self.streams.tx_buffered_is_consistent() {
8037                TxBufferTrackingState::Ok
8038            } else {
8039                TxBufferTrackingState::Inconsistent
8040            },
8041        }
8042    }
8043
8044    /// Returns the sum of the durations when each path in the
8045    /// connection was actively sending bytes or waiting for acks.
8046    /// Note that this could result in a duration that is longer than
8047    /// the actual connection duration in cases where multiple paths
8048    /// are active for extended periods of time.  In practice only 1
8049    /// path is typically active at a time.
8050    /// TODO revisit computation if in the future multiple paths are
8051    /// often active at the same time.
8052    fn bytes_in_flight_duration(&self) -> Duration {
8053        self.paths.iter().fold(Duration::ZERO, |acc, (_, path)| {
8054            acc + path.bytes_in_flight_duration()
8055        })
8056    }
8057
8058    /// Returns reference to peer's transport parameters. Returns `None` if we
8059    /// have not yet processed the peer's transport parameters.
8060    pub fn peer_transport_params(&self) -> Option<&TransportParams> {
8061        if !self.parsed_peer_transport_params {
8062            return None;
8063        }
8064
8065        Some(&self.peer_transport_params)
8066    }
8067
8068    /// Collects and returns statistics about each known path for the
8069    /// connection.
8070    pub fn path_stats(&self) -> impl Iterator<Item = PathStats> + '_ {
8071        self.paths.iter().map(|(_, p)| p.stats())
8072    }
8073
8074    /// Returns whether or not this is a server-side connection.
8075    pub fn is_server(&self) -> bool {
8076        self.is_server
8077    }
8078
8079    fn encode_transport_params(&mut self) -> Result<()> {
8080        self.handshake.set_quic_transport_params(
8081            &self.local_transport_params,
8082            self.is_server,
8083        )
8084    }
8085
8086    fn parse_peer_transport_params(
8087        &mut self, peer_params: TransportParams,
8088    ) -> Result<()> {
8089        // Validate initial_source_connection_id.
8090        match &peer_params.initial_source_connection_id {
8091            Some(v) if v != &self.destination_id() =>
8092                return Err(Error::InvalidTransportParam),
8093
8094            Some(_) => (),
8095
8096            // initial_source_connection_id must be sent by
8097            // both endpoints.
8098            None => return Err(Error::InvalidTransportParam),
8099        }
8100
8101        // Validate original_destination_connection_id.
8102        if let Some(odcid) = &self.odcid {
8103            match &peer_params.original_destination_connection_id {
8104                Some(v) if v != odcid =>
8105                    return Err(Error::InvalidTransportParam),
8106
8107                Some(_) => (),
8108
8109                // original_destination_connection_id must be
8110                // sent by the server.
8111                None if !self.is_server =>
8112                    return Err(Error::InvalidTransportParam),
8113
8114                None => (),
8115            }
8116        }
8117
8118        // Validate retry_source_connection_id.
8119        if let Some(rscid) = &self.rscid {
8120            match &peer_params.retry_source_connection_id {
8121                Some(v) if v != rscid =>
8122                    return Err(Error::InvalidTransportParam),
8123
8124                Some(_) => (),
8125
8126                // retry_source_connection_id must be sent by
8127                // the server.
8128                None => return Err(Error::InvalidTransportParam),
8129            }
8130        }
8131
8132        self.process_peer_transport_params(peer_params)?;
8133
8134        self.parsed_peer_transport_params = true;
8135
8136        Ok(())
8137    }
8138
8139    fn process_peer_transport_params(
8140        &mut self, peer_params: TransportParams,
8141    ) -> Result<()> {
8142        self.max_tx_data = peer_params.initial_max_data;
8143
8144        // Update send capacity.
8145        self.update_tx_cap();
8146
8147        self.streams
8148            .update_peer_max_streams_bidi(peer_params.initial_max_streams_bidi);
8149        self.streams
8150            .update_peer_max_streams_uni(peer_params.initial_max_streams_uni);
8151
8152        let max_ack_delay = Duration::from_millis(peer_params.max_ack_delay);
8153        let max_udp_payload_size =
8154            usize::try_from(peer_params.max_udp_payload_size)
8155                .unwrap_or(usize::MAX);
8156
8157        self.recovery_config.max_ack_delay = max_ack_delay;
8158        self.recovery_config
8159            .update_max_send_udp_payload_size(max_udp_payload_size);
8160
8161        let active_path = self.paths.get_active_mut()?;
8162
8163        active_path.recovery.update_max_ack_delay(max_ack_delay);
8164
8165        if active_path
8166            .pmtud
8167            .as_ref()
8168            .map(|pmtud| pmtud.should_probe())
8169            .unwrap_or(false)
8170        {
8171            active_path.recovery.pmtud_update_max_datagram_size(
8172                active_path
8173                    .pmtud
8174                    .as_mut()
8175                    .expect("PMTUD existence verified above")
8176                    .get_probe_size()
8177                    .min(max_udp_payload_size),
8178            );
8179        } else {
8180            active_path
8181                .recovery
8182                .update_max_datagram_size(max_udp_payload_size);
8183        }
8184
8185        // Record the max_active_conn_id parameter advertised by the peer.
8186        self.ids
8187            .set_source_conn_id_limit(peer_params.active_conn_id_limit);
8188
8189        self.peer_transport_params = peer_params;
8190
8191        Ok(())
8192    }
8193
8194    /// Continues the handshake.
8195    ///
8196    /// If the connection is already established, it does nothing.
8197    fn do_handshake(&mut self, now: Instant) -> Result<()> {
8198        let mut ex_data = tls::ExData {
8199            application_protos: &self.application_protos,
8200
8201            crypto_ctx: &mut self.crypto_ctx,
8202
8203            session: &mut self.session,
8204
8205            local_error: &mut self.local_error,
8206
8207            keylog: self.keylog.as_mut(),
8208
8209            trace_id: &self.trace_id,
8210
8211            local_transport_params: self.local_transport_params.clone(),
8212
8213            recovery_config: self.recovery_config,
8214
8215            tx_cap_factor: self.tx_cap_factor,
8216
8217            max_outstanding_sent_packets: self.max_outstanding_sent_packets,
8218
8219            pmtud: None,
8220
8221            is_server: self.is_server,
8222        };
8223
8224        if self.handshake_completed {
8225            return self.handshake.process_post_handshake(&mut ex_data);
8226        }
8227
8228        let handshake_needs_retry =
8229            match self.handshake.do_handshake(&mut ex_data) {
8230                Ok(_) => false,
8231                Err(Error::Done) => true,
8232                Err(e) => return Err(e),
8233            };
8234
8235        // BoringSSL reports success when entering early data before the
8236        // handshake completes. Apply callback configuration after either
8237        // non-fatal outcome so it is not lost on that path.
8238        if self
8239            .paths
8240            .get_active()
8241            .map(|p| p.can_reinit_recovery())
8242            .unwrap_or(false)
8243        {
8244            if ex_data.recovery_config != self.recovery_config {
8245                // If we received peer transport parameters already, respect the
8246                // peer's `max_udp_payload_size`.
8247                if self.parsed_peer_transport_params {
8248                    let max_udp_payload_size = usize::try_from(
8249                        self.peer_transport_params.max_udp_payload_size,
8250                    )
8251                    .unwrap_or(usize::MAX);
8252                    ex_data
8253                        .recovery_config
8254                        .update_max_send_udp_payload_size(max_udp_payload_size);
8255                }
8256
8257                if let Ok(path) = self.paths.get_active_mut() {
8258                    self.recovery_config = ex_data.recovery_config;
8259                    path.reinit_recovery(&self.recovery_config);
8260                }
8261            }
8262
8263            if ex_data.tx_cap_factor != self.tx_cap_factor {
8264                self.tx_cap_factor = ex_data.tx_cap_factor;
8265            }
8266
8267            self.max_outstanding_sent_packets =
8268                ex_data.max_outstanding_sent_packets;
8269
8270            if let Some((discover, max_probes)) = ex_data.pmtud {
8271                self.paths.set_discover_pmtu_on_existing_paths(
8272                    discover,
8273                    self.recovery_config.max_send_udp_payload_size,
8274                    max_probes,
8275                );
8276            }
8277
8278            if ex_data.local_transport_params != self.local_transport_params {
8279                self.streams.set_max_streams_bidi(
8280                    ex_data.local_transport_params.initial_max_streams_bidi,
8281                );
8282
8283                self.local_transport_params = ex_data.local_transport_params;
8284            }
8285        }
8286
8287        if handshake_needs_retry {
8288            // Try to parse transport parameters as soon as the first flight of
8289            // handshake data is processed.
8290            //
8291            // This is potentially dangerous as the handshake hasn't been
8292            // completed yet, though it's required to be able to send data in
8293            // 0.5 RTT.
8294            let raw_params = self.handshake.quic_transport_params();
8295
8296            if !self.parsed_peer_transport_params && !raw_params.is_empty() {
8297                let peer_params = TransportParams::decode(
8298                    raw_params,
8299                    self.is_server,
8300                    self.peer_transport_params_track_unknown,
8301                )?;
8302
8303                self.parse_peer_transport_params(peer_params)?;
8304            }
8305
8306            return Ok(());
8307        }
8308
8309        self.handshake_completed = self.handshake.is_completed();
8310
8311        self.alpn = self.handshake.alpn_protocol().to_vec();
8312
8313        let raw_params = self.handshake.quic_transport_params();
8314
8315        if !self.parsed_peer_transport_params && !raw_params.is_empty() {
8316            let peer_params = TransportParams::decode(
8317                raw_params,
8318                self.is_server,
8319                self.peer_transport_params_track_unknown,
8320            )?;
8321
8322            self.parse_peer_transport_params(peer_params)?;
8323        }
8324
8325        if self.handshake_completed {
8326            // The handshake is considered confirmed at the server when the
8327            // handshake completes, at which point we can also drop the
8328            // handshake epoch.
8329            if self.is_server {
8330                self.handshake_confirmed = true;
8331
8332                self.drop_epoch_state(packet::Epoch::Handshake, now);
8333            }
8334
8335            // Once the handshake is completed there's no point in processing
8336            // 0-RTT packets anymore, so clear the buffer now.
8337            self.undecryptable_pkts.clear();
8338
8339            trace!("{} connection established: proto={:?} cipher={:?} curve={:?} sigalg={:?} resumed={} {:?}",
8340                   self.trace_id,
8341                   std::str::from_utf8(self.application_proto()),
8342                   self.handshake.cipher(),
8343                   self.handshake.curve(),
8344                   self.handshake.sigalg(),
8345                   self.handshake.is_resumed(),
8346                   self.peer_transport_params);
8347        }
8348
8349        Ok(())
8350    }
8351
8352    /// Selects the packet type for the next outgoing packet.
8353    fn write_pkt_type(&self, send_pid: usize) -> Result<Type> {
8354        // On error send packet in the latest epoch available, but only send
8355        // 1-RTT ones when the handshake is completed.
8356        if self
8357            .local_error
8358            .as_ref()
8359            .is_some_and(|conn_err| !conn_err.is_app)
8360        {
8361            let epoch = match self.handshake.write_level() {
8362                crypto::Level::Initial => packet::Epoch::Initial,
8363                crypto::Level::ZeroRTT => unreachable!(),
8364                crypto::Level::Handshake => packet::Epoch::Handshake,
8365                crypto::Level::OneRTT => packet::Epoch::Application,
8366            };
8367
8368            if !self.handshake_confirmed {
8369                match epoch {
8370                    // Downgrade the epoch to Handshake as the handshake is not
8371                    // completed yet.
8372                    packet::Epoch::Application => return Ok(Type::Handshake),
8373
8374                    // Downgrade the epoch to Initial as the remote peer might
8375                    // not be able to decrypt handshake packets yet.
8376                    packet::Epoch::Handshake
8377                        if self.crypto_ctx[packet::Epoch::Initial].has_keys() =>
8378                        return Ok(Type::Initial),
8379
8380                    _ => (),
8381                };
8382            }
8383
8384            return Ok(Type::from_epoch(epoch));
8385        }
8386
8387        // APPLICATION_CLOSE can only be sent in a 1-RTT packet. Prioritize it
8388        // over obsolete lower-epoch PTO probes, which cannot be consumed while
8389        // closing because PING frames are suppressed.
8390        if self.is_established() &&
8391            self.local_error
8392                .as_ref()
8393                .is_some_and(|conn_err| conn_err.is_app)
8394        {
8395            return Ok(Type::Short);
8396        }
8397
8398        for &epoch in packet::Epoch::epochs(
8399            packet::Epoch::Initial..=packet::Epoch::Application,
8400        ) {
8401            let crypto_ctx = &self.crypto_ctx[epoch];
8402            let pkt_space = &self.pkt_num_spaces[epoch];
8403
8404            // Only send packets in a space when we have the send keys for it.
8405            if crypto_ctx.crypto_seal.is_none() {
8406                continue;
8407            }
8408
8409            // We are ready to send data for this packet number space.
8410            if crypto_ctx.data_available() || pkt_space.ready() {
8411                return Ok(Type::from_epoch(epoch));
8412            }
8413
8414            // There are lost frames in this packet number space.
8415            for (_, p) in self.paths.iter() {
8416                if p.recovery.has_lost_frames(epoch) {
8417                    return Ok(Type::from_epoch(epoch));
8418                }
8419
8420                // We need to send PTO probe packets.
8421                if p.recovery.loss_probes(epoch) > 0 {
8422                    return Ok(Type::from_epoch(epoch));
8423                }
8424            }
8425        }
8426
8427        // If there are flushable, almost full or blocked streams, use the
8428        // Application epoch.
8429        let send_path = self.paths.get(send_pid)?;
8430        if (self.is_established() || self.is_in_early_data()) &&
8431            (self.should_send_handshake_done() ||
8432                self.flow_control.should_update_max_data() ||
8433                self.should_send_max_data ||
8434                self.blocked_limit.is_some() ||
8435                self.streams_blocked_bidi_state
8436                    .has_pending_stream_blocked_frame() ||
8437                self.streams_blocked_uni_state
8438                    .has_pending_stream_blocked_frame() ||
8439                self.dgram_send_queue.has_pending() ||
8440                self.local_error
8441                    .as_ref()
8442                    .is_some_and(|conn_err| conn_err.is_app) ||
8443                self.should_send_max_streams_bidi ||
8444                self.streams.should_update_max_streams_bidi() ||
8445                self.should_send_max_streams_uni ||
8446                self.streams.should_update_max_streams_uni() ||
8447                self.streams.has_flushable() ||
8448                self.streams.has_almost_full() ||
8449                self.streams.has_blocked() ||
8450                self.streams.has_reset() ||
8451                self.streams.has_stopped() ||
8452                self.ids.has_new_scids() ||
8453                self.ids.has_retire_dcids() ||
8454                send_path
8455                    .pmtud
8456                    .as_ref()
8457                    .is_some_and(|pmtud| pmtud.should_probe()) ||
8458                send_path.needs_ack_eliciting ||
8459                send_path.probing_required())
8460        {
8461            // Only clients can send 0-RTT packets.
8462            if !self.is_server && self.is_in_early_data() {
8463                return Ok(Type::ZeroRTT);
8464            }
8465
8466            return Ok(Type::Short);
8467        }
8468
8469        Err(Error::Done)
8470    }
8471
8472    /// Returns the mutable stream with the given ID if it exists, or creates
8473    /// a new one otherwise.
8474    fn get_or_create_stream(
8475        &mut self, id: u64, local: bool,
8476    ) -> Result<&mut stream::Stream<F>> {
8477        self.streams.get_or_create(
8478            id,
8479            &self.local_transport_params,
8480            &self.peer_transport_params,
8481            local,
8482            self.is_server,
8483        )
8484    }
8485
8486    /// Gets or creates a stream referenced by a received frame.
8487    fn get_or_create_stream_for_received_frame(
8488        &mut self, id: u64,
8489    ) -> Result<&mut stream::Stream<F>> {
8490        let local = stream::is_local(id, self.is_server);
8491
8492        // Opening a higher-numbered stream also opens lower streams of the
8493        // same type, even if they do not have Stream objects yet.
8494        if local && !self.streams.local_stream_opened(id) {
8495            return Err(Error::InvalidStreamState(id));
8496        }
8497
8498        self.get_or_create_stream(id, local)
8499    }
8500
8501    /// Processes an incoming frame.
8502    fn process_frame(
8503        &mut self, frame: frame::Frame, hdr: &Header, recv_path_id: usize,
8504        epoch: packet::Epoch, now: Instant,
8505    ) -> Result<()> {
8506        trace!("{} rx frm {:?}", self.trace_id, frame);
8507
8508        match frame {
8509            frame::Frame::Padding { .. } => (),
8510
8511            frame::Frame::Ping { .. } => (),
8512
8513            frame::Frame::ACK {
8514                ranges, ack_delay, ..
8515            } => {
8516                let ack_delay = ack_delay
8517                    .checked_mul(2_u64.pow(
8518                        self.peer_transport_params.ack_delay_exponent as u32,
8519                    ))
8520                    .ok_or(Error::InvalidFrame)?;
8521
8522                if epoch == packet::Epoch::Handshake ||
8523                    (epoch == packet::Epoch::Application &&
8524                        self.is_established())
8525                {
8526                    self.peer_verified_initial_address = true;
8527                }
8528
8529                let handshake_status = self.handshake_status();
8530
8531                let is_app_limited = self.delivery_rate_check_if_app_limited();
8532
8533                let largest_acked = ranges.last().expect(
8534                    "ACK frames should always have at least one ack range",
8535                );
8536
8537                for (_, p) in self.paths.iter_mut() {
8538                    if self.pkt_num_spaces[epoch]
8539                        .largest_tx_pkt_num
8540                        .is_some_and(|largest_sent| largest_sent < largest_acked)
8541                    {
8542                        // https://www.rfc-editor.org/rfc/rfc9000#section-13.1
8543                        // An endpoint SHOULD treat receipt of an acknowledgment
8544                        // for a packet it did not send as
8545                        // a connection error of type PROTOCOL_VIOLATION
8546                        return Err(Error::InvalidAckRange);
8547                    }
8548
8549                    if is_app_limited {
8550                        p.recovery.delivery_rate_update_app_limited(true);
8551                    }
8552
8553                    let OnAckReceivedOutcome {
8554                        lost_packets,
8555                        lost_bytes,
8556                        acked_bytes,
8557                        spurious_losses,
8558                    } = p.recovery.on_ack_received(
8559                        &ranges,
8560                        ack_delay,
8561                        epoch,
8562                        handshake_status,
8563                        now,
8564                        self.pkt_num_manager.skip_pn(),
8565                        &self.trace_id,
8566                    )?;
8567
8568                    let skip_pn = self.pkt_num_manager.skip_pn();
8569                    let largest_acked =
8570                        p.recovery.get_largest_acked_on_epoch(epoch);
8571
8572                    // A higher ACK validates `skip_pn`.
8573                    if let Some((largest_acked, skip_pn)) =
8574                        largest_acked.zip(skip_pn)
8575                    {
8576                        if largest_acked > skip_pn {
8577                            self.pkt_num_manager.set_skip_pn(None);
8578                        }
8579                    }
8580
8581                    self.lost_count += lost_packets;
8582                    self.lost_bytes += lost_bytes as u64;
8583                    self.acked_bytes += acked_bytes as u64;
8584                    self.spurious_lost_count += spurious_losses;
8585                }
8586            },
8587
8588            frame::Frame::ResetStream {
8589                stream_id,
8590                error_code,
8591                final_size,
8592            } => {
8593                // Peer can't send on our unidirectional streams.
8594                if !stream::is_bidi(stream_id) &&
8595                    stream::is_local(stream_id, self.is_server)
8596                {
8597                    return Err(Error::InvalidStreamState(stream_id));
8598                }
8599
8600                let max_rx_data_left = self.max_rx_data() - self.rx_data;
8601
8602                // Get existing stream or create a new one, but if the stream
8603                // has already been closed and collected, ignore the frame.
8604                //
8605                // This can happen if e.g. an ACK frame is lost, and the peer
8606                // retransmits another frame before it realizes that the stream
8607                // is gone.
8608                //
8609                // Note that it makes it impossible to check if the frame is
8610                // illegal, since we have no state, but since we ignore the
8611                // frame, it should be fine.
8612                let stream = match self
8613                    .get_or_create_stream_for_received_frame(stream_id)
8614                {
8615                    Ok(v) => v,
8616
8617                    Err(Error::Done) => return Ok(()),
8618
8619                    Err(e) => return Err(e),
8620                };
8621
8622                let was_readable = stream.is_readable();
8623                let priority_key = Arc::clone(&stream.priority_key);
8624
8625                let stream::RecvBufResetReturn {
8626                    max_data_delta,
8627                    consumed_flowcontrol,
8628                } = stream.recv.reset(error_code, final_size)?;
8629
8630                if max_data_delta > max_rx_data_left {
8631                    return Err(Error::FlowControl);
8632                }
8633
8634                // The receive side can complete without the stream becoming
8635                // readable, so no later read would collect it.
8636                let state = stream.state();
8637                let local = stream.local;
8638
8639                if !was_readable && stream.is_readable() {
8640                    self.streams.insert_readable(&priority_key);
8641                }
8642
8643                self.rx_data += max_data_delta;
8644                // We dropped the receive buffer, return connection level
8645                // flow-control
8646                self.flow_control.add_consumed(consumed_flowcontrol);
8647
8648                self.reset_stream_remote_count =
8649                    self.reset_stream_remote_count.saturating_add(1);
8650
8651                if state == stream::StreamState::Collectable {
8652                    self.streams.collect(stream_id, local);
8653                }
8654            },
8655
8656            frame::Frame::StopSending {
8657                stream_id,
8658                error_code,
8659            } => {
8660                // STOP_SENDING on a receive-only stream is a fatal error.
8661                if !stream::is_local(stream_id, self.is_server) &&
8662                    !stream::is_bidi(stream_id)
8663                {
8664                    return Err(Error::InvalidStreamState(stream_id));
8665                }
8666
8667                // Get existing stream or create a new one, but if the stream
8668                // has already been closed and collected, ignore the frame.
8669                //
8670                // This can happen if e.g. an ACK frame is lost, and the peer
8671                // retransmits another frame before it realizes that the stream
8672                // is gone.
8673                //
8674                // Note that it makes it impossible to check if the frame is
8675                // illegal, since we have no state, but since we ignore the
8676                // frame, it should be fine.
8677                let stream = match self
8678                    .get_or_create_stream_for_received_frame(stream_id)
8679                {
8680                    Ok(v) => v,
8681
8682                    Err(Error::Done) => return Ok(()),
8683
8684                    Err(e) => return Err(e),
8685                };
8686
8687                let priority_key = Arc::clone(&stream.priority_key);
8688
8689                // Save the buffered length before stopping (stop clears the
8690                // buffer).
8691                let buffered_len = stream.send.buffered_bytes() as usize;
8692
8693                // Try stopping the stream.
8694                if let Ok((final_size, unsent)) = stream.send.stop(error_code) {
8695                    // Claw back some flow control allowance from data that was
8696                    // buffered but not actually sent before the stream was
8697                    // reset.
8698                    //
8699                    // Note that `tx_cap` will be updated later on, so no need
8700                    // to touch it here.
8701                    self.tx_data = self.tx_data.saturating_sub(unsent);
8702
8703                    // Update tx_buffered: subtract only the buffered data, not
8704                    // inflight data.
8705                    self.streams.sub_tx_buffered(buffered_len);
8706
8707                    // Match moves from App to Transport with moves from
8708                    // Transport to Dropped.
8709                    // A Network transition would distinguish sent bytes from
8710                    // drops before transmission.
8711                    qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
8712                        let ev_data = EventData::QuicStreamDataMoved(
8713                            qlog::events::quic::StreamDataMoved {
8714                                stream_id: Some(stream_id),
8715                                offset: Some(final_size),
8716                                raw: Some(RawInfo {
8717                                    length: Some(unsent),
8718                                    ..Default::default()
8719                                }),
8720                                from: Some(DataRecipient::Transport),
8721                                to: Some(DataRecipient::Dropped),
8722                                ..Default::default()
8723                            },
8724                        );
8725
8726                        q.add_event_data_with_instant(ev_data, now).ok();
8727                    });
8728
8729                    self.streams.insert_reset(stream_id, error_code, final_size);
8730
8731                    self.streams.insert_stopped_writable(&priority_key);
8732
8733                    // A stopped stream has nothing left to flush. A stale
8734                    // flushable entry could make send() return Done while
8735                    // DATAGRAMs are still queued.
8736                    self.streams.remove_flushable(&priority_key);
8737
8738                    self.stopped_stream_remote_count =
8739                        self.stopped_stream_remote_count.saturating_add(1);
8740                    self.reset_stream_local_count =
8741                        self.reset_stream_local_count.saturating_add(1);
8742                }
8743            },
8744
8745            frame::Frame::Crypto { data } => {
8746                if data.max_off() >= MAX_CRYPTO_STREAM_OFFSET {
8747                    return Err(Error::CryptoBufferExceeded);
8748                }
8749
8750                // Push the data to the stream so it can be re-ordered.
8751                self.crypto_ctx[epoch].crypto_stream.recv.write(data)?;
8752
8753                // Feed crypto data to the TLS state, if there's data
8754                // available at the expected offset.
8755                let mut crypto_buf = [0; 512];
8756
8757                let level = crypto::Level::from_epoch(epoch);
8758
8759                let stream = &mut self.crypto_ctx[epoch].crypto_stream;
8760
8761                while let Ok((read, _)) = stream.recv.emit(&mut crypto_buf) {
8762                    let recv_buf = &crypto_buf[..read];
8763                    self.handshake.provide_data(level, recv_buf)?;
8764                }
8765
8766                self.do_handshake(now)?;
8767            },
8768
8769            frame::Frame::CryptoHeader { .. } => unreachable!(),
8770
8771            // TODO: implement stateless retry
8772            frame::Frame::NewToken { .. } =>
8773                if self.is_server {
8774                    return Err(Error::InvalidPacket);
8775                },
8776
8777            frame::Frame::Stream { stream_id, data } => {
8778                // Peer can't send on our unidirectional streams.
8779                if !stream::is_bidi(stream_id) &&
8780                    stream::is_local(stream_id, self.is_server)
8781                {
8782                    return Err(Error::InvalidStreamState(stream_id));
8783                }
8784
8785                let max_rx_data_left = self.max_rx_data() - self.rx_data;
8786
8787                // Get existing stream or create a new one, but if the stream
8788                // has already been closed and collected, ignore the frame.
8789                //
8790                // This can happen if e.g. an ACK frame is lost, and the peer
8791                // retransmits another frame before it realizes that the stream
8792                // is gone.
8793                //
8794                // Note that it makes it impossible to check if the frame is
8795                // illegal, since we have no state, but since we ignore the
8796                // frame, it should be fine.
8797                let stream = match self
8798                    .get_or_create_stream_for_received_frame(stream_id)
8799                {
8800                    Ok(v) => v,
8801
8802                    Err(Error::Done) => return Ok(()),
8803
8804                    Err(e) => return Err(e),
8805                };
8806
8807                // Check for the connection-level flow control limit.
8808                let max_off_delta =
8809                    data.max_off().saturating_sub(stream.recv.max_off());
8810
8811                if max_off_delta > max_rx_data_left {
8812                    return Err(Error::FlowControl);
8813                }
8814
8815                let was_readable = stream.is_readable();
8816                let priority_key = Arc::clone(&stream.priority_key);
8817
8818                let was_draining = stream.recv.is_draining();
8819
8820                stream.recv.write(data)?;
8821
8822                // The receive side can complete without the stream becoming
8823                // readable, so no later read would collect it.
8824                let state = stream.state();
8825                let local = stream.local;
8826
8827                if !was_readable && stream.is_readable() {
8828                    self.streams.insert_readable(&priority_key);
8829                }
8830
8831                self.rx_data += max_off_delta;
8832
8833                if was_draining {
8834                    // When a stream is in draining state it will not queue
8835                    // incoming data for the application to read, so consider
8836                    // the received data as consumed, which might trigger a flow
8837                    // control update.
8838                    self.flow_control.add_consumed(max_off_delta);
8839                }
8840
8841                if state == stream::StreamState::Collectable {
8842                    self.streams.collect(stream_id, local);
8843                }
8844            },
8845
8846            frame::Frame::StreamHeader { .. } => unreachable!(),
8847
8848            frame::Frame::MaxData { max } => {
8849                self.max_tx_data = cmp::max(self.max_tx_data, max);
8850            },
8851
8852            frame::Frame::MaxStreamData { stream_id, max } => {
8853                // Peer can't receive on its own unidirectional streams.
8854                if !stream::is_bidi(stream_id) &&
8855                    !stream::is_local(stream_id, self.is_server)
8856                {
8857                    return Err(Error::InvalidStreamState(stream_id));
8858                }
8859
8860                // Get existing stream or create a new one, but if the stream
8861                // has already been closed and collected, ignore the frame.
8862                //
8863                // This can happen if e.g. an ACK frame is lost, and the peer
8864                // retransmits another frame before it realizes that the stream
8865                // is gone.
8866                //
8867                // Note that it makes it impossible to check if the frame is
8868                // illegal, since we have no state, but since we ignore the
8869                // frame, it should be fine.
8870                let stream = match self
8871                    .get_or_create_stream_for_received_frame(stream_id)
8872                {
8873                    Ok(v) => v,
8874
8875                    Err(Error::Done) => return Ok(()),
8876
8877                    Err(e) => return Err(e),
8878                };
8879
8880                let was_flushable = stream.is_flushable();
8881
8882                stream.send.update_max_data(max);
8883
8884                let writable = stream.is_writable();
8885
8886                let priority_key = Arc::clone(&stream.priority_key);
8887
8888                // If the stream became flushable, add it to the queue unless it
8889                // is already present.
8890                if stream.is_flushable() && !was_flushable {
8891                    let priority_key = Arc::clone(&stream.priority_key);
8892                    self.streams.insert_flushable(&priority_key);
8893                }
8894
8895                if writable {
8896                    self.streams.insert_writable(&priority_key);
8897                }
8898            },
8899
8900            frame::Frame::MaxStreamsBidi { max } => {
8901                if max > MAX_STREAM_ID {
8902                    return Err(Error::InvalidFrame);
8903                }
8904
8905                self.streams.update_peer_max_streams_bidi(max);
8906            },
8907
8908            frame::Frame::MaxStreamsUni { max } => {
8909                if max > MAX_STREAM_ID {
8910                    return Err(Error::InvalidFrame);
8911                }
8912
8913                self.streams.update_peer_max_streams_uni(max);
8914            },
8915
8916            frame::Frame::DataBlocked { .. } => {
8917                self.data_blocked_recv_count =
8918                    self.data_blocked_recv_count.saturating_add(1);
8919            },
8920
8921            frame::Frame::StreamDataBlocked { .. } => {
8922                self.stream_data_blocked_recv_count =
8923                    self.stream_data_blocked_recv_count.saturating_add(1);
8924            },
8925
8926            frame::Frame::StreamsBlockedBidi { limit } => {
8927                if limit > MAX_STREAM_ID {
8928                    return Err(Error::InvalidFrame);
8929                }
8930
8931                self.streams_blocked_bidi_recv_count =
8932                    self.streams_blocked_bidi_recv_count.saturating_add(1);
8933            },
8934
8935            frame::Frame::StreamsBlockedUni { limit } => {
8936                if limit > MAX_STREAM_ID {
8937                    return Err(Error::InvalidFrame);
8938                }
8939
8940                self.streams_blocked_uni_recv_count =
8941                    self.streams_blocked_uni_recv_count.saturating_add(1);
8942            },
8943
8944            frame::Frame::NewConnectionId {
8945                seq_num,
8946                retire_prior_to,
8947                conn_id,
8948                reset_token,
8949            } => {
8950                if self.ids.zero_length_dcid() {
8951                    return Err(Error::InvalidState);
8952                }
8953
8954                let mut retired_path_ids = SmallVec::new();
8955
8956                // Retire pending path IDs before propagating the error code to
8957                // make sure retired connection IDs are not in use anymore.
8958                let new_dcid_res = self.ids.new_dcid(
8959                    conn_id.into(),
8960                    seq_num,
8961                    u128::from_be_bytes(reset_token),
8962                    retire_prior_to,
8963                    &mut retired_path_ids,
8964                );
8965
8966                for (dcid_seq, pid) in retired_path_ids {
8967                    let path = self.paths.get_mut(pid)?;
8968
8969                    // Maybe the path already switched to another DCID.
8970                    if path.active_dcid_seq != Some(dcid_seq) {
8971                        continue;
8972                    }
8973
8974                    if let Some(new_dcid_seq) =
8975                        self.ids.lowest_available_dcid_seq()
8976                    {
8977                        path.active_dcid_seq = Some(new_dcid_seq);
8978
8979                        self.ids.link_dcid_to_path_id(new_dcid_seq, pid)?;
8980
8981                        trace!(
8982                            "{} path ID {} changed DCID: old seq num {} new seq num {}",
8983                            self.trace_id, pid, dcid_seq, new_dcid_seq,
8984                        );
8985                    } else {
8986                        // We cannot use this path anymore for now.
8987                        path.active_dcid_seq = None;
8988
8989                        trace!(
8990                            "{} path ID {} cannot be used; DCID seq num {} has been retired",
8991                            self.trace_id, pid, dcid_seq,
8992                        );
8993                    }
8994                }
8995
8996                // Propagate error (if any) now...
8997                new_dcid_res?;
8998            },
8999
9000            frame::Frame::RetireConnectionId { seq_num } => {
9001                if self.ids.zero_length_scid() {
9002                    return Err(Error::InvalidState);
9003                }
9004
9005                if let Some(pid) = self.ids.retire_scid(seq_num, &hdr.dcid)? {
9006                    let path = self.paths.get_mut(pid)?;
9007
9008                    // Maybe we already linked a new SCID to that path.
9009                    if path.active_scid_seq == Some(seq_num) {
9010                        // XXX: We do not remove unused paths now, we instead
9011                        // wait until we need to maintain more paths than the
9012                        // host is willing to.
9013                        path.active_scid_seq = None;
9014                    }
9015                }
9016            },
9017
9018            frame::Frame::PathChallenge { data } => {
9019                self.path_challenge_rx_count += 1;
9020
9021                self.paths
9022                    .get_mut(recv_path_id)?
9023                    .on_challenge_received(data);
9024            },
9025
9026            frame::Frame::PathResponse { data } => {
9027                self.paths.on_response_received(data)?;
9028            },
9029
9030            frame::Frame::ConnectionClose {
9031                error_code, reason, ..
9032            } => {
9033                self.peer_error = Some(ConnectionError {
9034                    is_app: false,
9035                    error_code,
9036                    reason,
9037                });
9038
9039                let path = self.paths.get_active()?;
9040                self.draining_timer = Some(now + (path.recovery.pto() * 3));
9041            },
9042
9043            frame::Frame::ApplicationClose { error_code, reason } => {
9044                self.peer_error = Some(ConnectionError {
9045                    is_app: true,
9046                    error_code,
9047                    reason,
9048                });
9049
9050                let path = self.paths.get_active()?;
9051                self.draining_timer = Some(now + (path.recovery.pto() * 3));
9052            },
9053
9054            frame::Frame::HandshakeDone => {
9055                if self.is_server {
9056                    return Err(Error::InvalidPacket);
9057                }
9058
9059                self.peer_verified_initial_address = true;
9060
9061                self.handshake_confirmed = true;
9062
9063                // Once the handshake is confirmed, we can drop Handshake keys.
9064                self.drop_epoch_state(packet::Epoch::Handshake, now);
9065            },
9066
9067            frame::Frame::Datagram { data } => {
9068                // Close the connection if DATAGRAMs are not enabled.
9069                // quiche always advertises support for 64K sized DATAGRAM
9070                // frames, as recommended by the standard, so we don't need a
9071                // size check.
9072                if !self.dgram_enabled() {
9073                    return Err(Error::InvalidState);
9074                }
9075
9076                // If recv queue is full, discard oldest
9077                if self.dgram_recv_queue.is_full() {
9078                    self.dgram_recv_queue.pop();
9079                }
9080
9081                self.dgram_recv_queue.push(data.into())?;
9082
9083                self.dgram_recv_count = self.dgram_recv_count.saturating_add(1);
9084
9085                let path = self.paths.get_mut(recv_path_id)?;
9086                path.dgram_recv_count = path.dgram_recv_count.saturating_add(1);
9087            },
9088
9089            frame::Frame::DatagramHeader { .. } => unreachable!(),
9090        }
9091
9092        Ok(())
9093    }
9094
9095    /// Drops the keys and recovery state for the given epoch.
9096    fn drop_epoch_state(&mut self, epoch: packet::Epoch, now: Instant) {
9097        let crypto_ctx = &mut self.crypto_ctx[epoch];
9098        if crypto_ctx.crypto_open.is_none() {
9099            return;
9100        }
9101        crypto_ctx.clear();
9102        self.pkt_num_spaces[epoch].clear();
9103
9104        let handshake_status = self.handshake_status();
9105        for (_, p) in self.paths.iter_mut() {
9106            p.recovery
9107                .on_pkt_num_space_discarded(epoch, handshake_status, now);
9108        }
9109
9110        trace!("{} dropped epoch {} state", self.trace_id, epoch);
9111    }
9112
9113    /// Returns the connection level flow control limit.
9114    fn max_rx_data(&self) -> u64 {
9115        self.flow_control.max_data()
9116    }
9117
9118    /// Returns true if the HANDSHAKE_DONE frame needs to be sent.
9119    fn should_send_handshake_done(&self) -> bool {
9120        self.is_established() && !self.handshake_done_sent && self.is_server
9121    }
9122
9123    /// Returns the idle timeout value.
9124    ///
9125    /// `None` is returned if both end-points disabled the idle timeout.
9126    fn idle_timeout(&self) -> Option<Duration> {
9127        // If the transport parameter is set to 0, then the respective endpoint
9128        // decided to disable the idle timeout. If both are disabled we should
9129        // not set any timeout.
9130        if self.local_transport_params.max_idle_timeout == 0 &&
9131            self.peer_transport_params.max_idle_timeout == 0
9132        {
9133            return None;
9134        }
9135
9136        // If the local endpoint or the peer disabled the idle timeout, use the
9137        // other peer's value, otherwise use the minimum of the two values.
9138        let idle_timeout = if self.local_transport_params.max_idle_timeout == 0 {
9139            self.peer_transport_params.max_idle_timeout
9140        } else if self.peer_transport_params.max_idle_timeout == 0 {
9141            self.local_transport_params.max_idle_timeout
9142        } else {
9143            cmp::min(
9144                self.local_transport_params.max_idle_timeout,
9145                self.peer_transport_params.max_idle_timeout,
9146            )
9147        };
9148
9149        let path_pto = match self.paths.get_active() {
9150            Ok(p) => p.recovery.pto(),
9151            Err(_) => Duration::ZERO,
9152        };
9153
9154        let idle_timeout = Duration::from_millis(idle_timeout);
9155        let idle_timeout = cmp::max(idle_timeout, 3 * path_pto);
9156
9157        Some(idle_timeout)
9158    }
9159
9160    /// Returns the connection's handshake status for use in loss recovery.
9161    fn handshake_status(&self) -> recovery::HandshakeStatus {
9162        recovery::HandshakeStatus {
9163            has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
9164                .has_keys(),
9165
9166            peer_verified_address: self.peer_verified_initial_address,
9167
9168            completed: self.is_established(),
9169        }
9170    }
9171
9172    /// Updates send capacity.
9173    fn update_tx_cap(&mut self) {
9174        let cwin_available = match self.paths.get_active() {
9175            Ok(p) => p.recovery.cwnd_available() as u64,
9176            Err(_) => 0,
9177        };
9178
9179        let cap =
9180            cmp::min(cwin_available, self.max_tx_data - self.tx_data) as usize;
9181        self.tx_cap = (cap as f64 * self.tx_cap_factor).ceil() as usize;
9182    }
9183
9184    fn delivery_rate_check_if_app_limited(&self) -> bool {
9185        // Enter the app-limited phase of delivery rate when these conditions
9186        // are met:
9187        //
9188        // - The remaining capacity exceeds the available bytes in CWND (there
9189        //   is more room to send).
9190        // - New data since the last `send()` is smaller than available bytes in
9191        //   CWND (we queued less than what we can send).
9192        // - CWND has room for more data.
9193        //
9194        // In application-limited phases the transmission rate is limited by the
9195        // application rather than the congestion control algorithm.
9196        //
9197        // This mirrors `CheckIfApplicationLimited()` from the delivery-rate
9198        // draft but affects only delivery-rate calculation, not
9199        // `recovery.app_limited`.
9200        let cwin_available = self
9201            .paths
9202            .iter()
9203            .filter(|&(_, p)| p.active())
9204            .map(|(_, p)| p.recovery.cwnd_available())
9205            .sum();
9206
9207        ((self.streams.tx_buffered() + self.dgram_send_queue_byte_size()) <
9208            cwin_available) &&
9209            (self.tx_data.saturating_sub(self.last_tx_data)) <
9210                cwin_available as u64 &&
9211            cwin_available > 0
9212    }
9213
9214    fn set_initial_dcid(
9215        &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
9216        path_id: usize,
9217    ) -> Result<()> {
9218        self.ids.set_initial_dcid(cid, reset_token, Some(path_id));
9219        self.paths.get_mut(path_id)?.active_dcid_seq = Some(0);
9220
9221        Ok(())
9222    }
9223
9224    /// Selects the path that the incoming packet belongs to, or creates a new
9225    /// one if no existing path matches.
9226    fn get_or_create_recv_path_id(
9227        &mut self, recv_pid: Option<usize>, dcid: &ConnectionId, buf_len: usize,
9228        info: &RecvInfo,
9229    ) -> Result<usize> {
9230        let ids = &mut self.ids;
9231
9232        let (in_scid_seq, mut in_scid_pid) =
9233            ids.find_scid_seq(dcid).ok_or(Error::InvalidState)?;
9234
9235        if let Some(recv_pid) = recv_pid {
9236            // If the path observes a change of SCID used, note it.
9237            let recv_path = self.paths.get_mut(recv_pid)?;
9238
9239            let cid_entry =
9240                recv_path.active_scid_seq.and_then(|v| ids.get_scid(v).ok());
9241
9242            if cid_entry.map(|e| &e.cid) != Some(dcid) {
9243                let incoming_cid_entry = ids.get_scid(in_scid_seq)?;
9244
9245                let prev_recv_pid =
9246                    incoming_cid_entry.path_id.unwrap_or(recv_pid);
9247
9248                if prev_recv_pid != recv_pid {
9249                    trace!(
9250                        "{} peer reused CID {:?} from path {} on path {}",
9251                        self.trace_id,
9252                        dcid,
9253                        prev_recv_pid,
9254                        recv_pid
9255                    );
9256
9257                    // TODO: reset congestion control.
9258                }
9259
9260                trace!(
9261                    "{} path ID {} now see SCID with seq num {}",
9262                    self.trace_id,
9263                    recv_pid,
9264                    in_scid_seq
9265                );
9266
9267                recv_path.active_scid_seq = Some(in_scid_seq);
9268                ids.link_scid_to_path_id(in_scid_seq, recv_pid)?;
9269            }
9270
9271            return Ok(recv_pid);
9272        }
9273
9274        // This is a new 4-tuple. See if the CID has not been assigned on
9275        // another path.
9276
9277        // Ignore this step if are using zero-length SCID.
9278        if ids.zero_length_scid() {
9279            in_scid_pid = None;
9280        }
9281
9282        // Capture old path info before insert_path() so we can emit the
9283        // ReusedSourceConnectionId event after successful insertion. This
9284        // ensures the event count is bounded by path Slab capacity.
9285        let reused_cid_info = match in_scid_pid {
9286            Some(pid) => {
9287                let old_path = self.paths.get(pid)?;
9288                Some((pid, old_path.local_addr(), old_path.peer_addr()))
9289            },
9290
9291            None => None,
9292        };
9293
9294        // This is a new path using an unassigned CID; create it!
9295        let mut path = path::Path::new(
9296            info.to,
9297            info.from,
9298            &self.recovery_config,
9299            self.path_challenge_recv_max_queue_len,
9300            false,
9301            None,
9302        );
9303
9304        path.max_send_bytes = buf_len * self.max_amplification_factor;
9305        path.active_scid_seq = Some(in_scid_seq);
9306
9307        // Automatically probes the new path.
9308        path.request_validation();
9309
9310        let pid = self.paths.insert_path(path, self.is_server)?;
9311
9312        // Notify the application of CID reuse only after the path was
9313        // successfully admitted. This bounds event queue growth by path Slab
9314        // capacity, preventing an attacker from growing the queue unboundedly
9315        // by rotating source ports.
9316        match reused_cid_info {
9317            Some((old_pid, old_local_addr, old_peer_addr)) => {
9318                trace!(
9319                    "{} reused CID seq {} of ({},{}) (path {}) on ({},{})",
9320                    self.trace_id,
9321                    in_scid_seq,
9322                    old_local_addr,
9323                    old_peer_addr,
9324                    old_pid,
9325                    info.to,
9326                    info.from
9327                );
9328
9329                self.paths.notify_event(PathEvent::ReusedSourceConnectionId(
9330                    in_scid_seq,
9331                    (old_local_addr, old_peer_addr),
9332                    (info.to, info.from),
9333                ));
9334            },
9335
9336            None => {
9337                ids.link_scid_to_path_id(in_scid_seq, pid)?;
9338            },
9339        }
9340
9341        Ok(pid)
9342    }
9343
9344    /// Selects the path on which the next packet must be sent.
9345    fn get_send_path_id(
9346        &self, from: Option<SocketAddr>, to: Option<SocketAddr>,
9347    ) -> Result<usize> {
9348        // A probing packet must be sent, but only if the connection is fully
9349        // established. A closing connection only sends the CONNECTION_CLOSE
9350        // frame, on the active path.
9351        if self.is_established() && self.local_error.is_none() {
9352            let mut probing = self
9353                .paths
9354                .iter()
9355                .filter(|(_, p)| from.is_none() || Some(p.local_addr()) == from)
9356                .filter(|(_, p)| to.is_none() || Some(p.peer_addr()) == to)
9357                .filter(|(_, p)| p.active_dcid_seq.is_some())
9358                .filter(|(_, p)| p.probing_required())
9359                .map(|(pid, _)| pid);
9360
9361            if let Some(pid) = probing.next() {
9362                return Ok(pid);
9363            }
9364        }
9365
9366        if let Some((pid, p)) = self.paths.get_active_with_pid() {
9367            if from.is_some() && Some(p.local_addr()) != from {
9368                return Err(Error::Done);
9369            }
9370
9371            if to.is_some() && Some(p.peer_addr()) != to {
9372                return Err(Error::Done);
9373            }
9374
9375            return Ok(pid);
9376        };
9377
9378        Err(Error::InvalidState)
9379    }
9380
9381    /// Sets the path with identifier 'path_id' to be active.
9382    fn set_active_path(&mut self, path_id: usize, now: Instant) -> Result<()> {
9383        if let Ok(old_active_path) = self.paths.get_active_mut() {
9384            for &e in packet::Epoch::epochs(
9385                packet::Epoch::Initial..=packet::Epoch::Application,
9386            ) {
9387                let (lost_packets, lost_bytes) = old_active_path
9388                    .recovery
9389                    .on_path_change(e, now, &self.trace_id);
9390
9391                self.lost_count += lost_packets;
9392                self.lost_bytes += lost_bytes as u64;
9393            }
9394        }
9395
9396        self.paths.set_active_path(path_id)
9397    }
9398
9399    /// Handles potential connection migration.
9400    fn on_peer_migrated(
9401        &mut self, new_pid: usize, disable_dcid_reuse: bool, now: Instant,
9402    ) -> Result<()> {
9403        let active_path_id = self.paths.get_active_path_id()?;
9404
9405        if active_path_id == new_pid {
9406            return Ok(());
9407        }
9408
9409        self.set_active_path(new_pid, now)?;
9410
9411        let no_spare_dcid =
9412            self.paths.get_mut(new_pid)?.active_dcid_seq.is_none();
9413
9414        if no_spare_dcid && !disable_dcid_reuse {
9415            self.paths.get_mut(new_pid)?.active_dcid_seq =
9416                self.paths.get_mut(active_path_id)?.active_dcid_seq;
9417        }
9418
9419        Ok(())
9420    }
9421
9422    /// Creates a new client-side path.
9423    fn create_path_on_client(
9424        &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
9425    ) -> Result<usize> {
9426        if self.is_server {
9427            return Err(Error::InvalidState);
9428        }
9429
9430        // If we use zero-length SCID and go over our local active CID limit,
9431        // the `insert_path()` call will raise an error.
9432        if !self.ids.zero_length_scid() && self.ids.available_scids() == 0 {
9433            return Err(Error::OutOfIdentifiers);
9434        }
9435
9436        // Do we have a spare DCID? If we are using zero-length DCID, just use
9437        // the default having sequence 0 (note that if we exceed our local CID
9438        // limit, the `insert_path()` call will raise an error.
9439        let dcid_seq = if self.ids.zero_length_dcid() {
9440            0
9441        } else {
9442            self.ids
9443                .lowest_available_dcid_seq()
9444                .ok_or(Error::OutOfIdentifiers)?
9445        };
9446
9447        let mut path = path::Path::new(
9448            local_addr,
9449            peer_addr,
9450            &self.recovery_config,
9451            self.path_challenge_recv_max_queue_len,
9452            false,
9453            None,
9454        );
9455        path.active_dcid_seq = Some(dcid_seq);
9456
9457        let pid = self
9458            .paths
9459            .insert_path(path, false)
9460            .map_err(|_| Error::OutOfIdentifiers)?;
9461        self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
9462
9463        Ok(pid)
9464    }
9465
9466    // Marks the connection as closed and does any related tidyup.
9467    fn mark_closed(&mut self) {
9468        #[cfg(feature = "qlog")]
9469        {
9470            let cc = match (self.is_established(), self.timed_out, &self.peer_error, &self.local_error) {
9471                (false, _, _, _) => qlog::events::quic::ConnectionClosed {
9472                    initiator: Some(TransportInitiator::Local),
9473                    connection_error: None,
9474                    application_error: None,
9475                    error_code: None,
9476                    internal_code: None,
9477                    reason: Some("Failed to establish connection".to_string()),
9478                    trigger: Some(qlog::events::quic::ConnectionClosedTrigger::HandshakeTimeout)
9479                },
9480
9481                (true, true, _, _) => qlog::events::quic::ConnectionClosed {
9482                    initiator: Some(TransportInitiator::Local),
9483                    connection_error: None,
9484                    application_error: None,
9485                    error_code: None,
9486                    internal_code: None,
9487                    reason: Some("Idle timeout".to_string()),
9488                    trigger: Some(qlog::events::quic::ConnectionClosedTrigger::IdleTimeout)
9489                },
9490
9491                (true, false, Some(peer_error), None) => {
9492                    let (connection_code, application_error, trigger) = if peer_error.is_app {
9493                        (None, Some(qlog::events::ApplicationError::Unknown), None)
9494                    } else {
9495                        let trigger = if peer_error.error_code == WireErrorCode::NoError as u64 {
9496                            Some(qlog::events::quic::ConnectionClosedTrigger::Clean)
9497                        } else {
9498                            Some(qlog::events::quic::ConnectionClosedTrigger::Error)
9499                        };
9500
9501                        (Some(qlog::events::ConnectionClosedEventError::TransportError(qlog::events::quic::TransportError::Unknown)), None, trigger)
9502                    };
9503
9504                    // TODO: select more appopriate connection_code and application_error than unknown.
9505                    qlog::events::quic::ConnectionClosed {
9506                        initiator: Some(TransportInitiator::Remote),
9507                        connection_error: connection_code,
9508                        application_error,
9509                        error_code: Some(peer_error.error_code),
9510                        internal_code: None,
9511                        reason: Some(String::from_utf8_lossy(&peer_error.reason).to_string()),
9512                        trigger,
9513                    }
9514                },
9515
9516                (true, false, None, Some(local_error)) => {
9517                    let (connection_code, application_error, trigger) = if local_error.is_app {
9518                        (None, Some(qlog::events::ApplicationError::Unknown), None)
9519                    } else {
9520                        let trigger = if local_error.error_code == WireErrorCode::NoError as u64 {
9521                            Some(qlog::events::quic::ConnectionClosedTrigger::Clean)
9522                        } else {
9523                            Some(qlog::events::quic::ConnectionClosedTrigger::Error)
9524                        };
9525
9526                        (Some(qlog::events::ConnectionClosedEventError::TransportError(qlog::events::quic::TransportError::Unknown)), None, trigger)
9527                    };
9528
9529                    // TODO: select more appopriate connection_code and application_error than unknown.
9530                    qlog::events::quic::ConnectionClosed {
9531                        initiator: Some(TransportInitiator::Local),
9532                        connection_error: connection_code,
9533                        application_error,
9534                        error_code: Some(local_error.error_code),
9535                        internal_code: None,
9536                        reason: Some(String::from_utf8_lossy(&local_error.reason).to_string()),
9537                        trigger,
9538                    }
9539                },
9540
9541                _ => qlog::events::quic::ConnectionClosed {
9542                    initiator: None,
9543                    connection_error: None,
9544                    application_error: None,
9545                    error_code: None,
9546                    internal_code: None,
9547                    reason: None,
9548                    trigger: None,
9549                },
9550            };
9551
9552            qlog_with_type!(QLOG_CONNECTION_CLOSED, self.qlog, q, {
9553                let ev_data = EventData::QuicConnectionClosed(cc);
9554
9555                q.add_event_data_now(ev_data).ok();
9556            });
9557            self.qlog.streamer = None;
9558        }
9559        self.closed = true;
9560    }
9561}
9562
9563#[cfg(feature = "boringssl-boring-crate")]
9564impl<F: BufFactory> AsMut<boring::ssl::SslRef> for Connection<F> {
9565    fn as_mut(&mut self) -> &mut boring::ssl::SslRef {
9566        self.handshake.ssl_mut()
9567    }
9568}
9569
9570/// Maps an `Error` to `Error::Done`, or itself.
9571///
9572/// When a received packet that hasn't yet been authenticated triggers a failure
9573/// it should, in most cases, be ignored, instead of raising a connection error,
9574/// to avoid potential man-in-the-middle and man-on-the-side attacks.
9575///
9576/// However, if no other packet was previously received, the connection should
9577/// indeed be closed as the received packet might just be network background
9578/// noise, and it shouldn't keep resources occupied indefinitely.
9579///
9580/// This function maps an error to `Error::Done` to ignore a packet failure
9581/// without aborting the connection, except when no other packet was previously
9582/// received, in which case the error itself is returned, but only on the
9583/// server-side as the client will already have armed the idle timer.
9584///
9585/// This must only be used for errors preceding packet authentication. Failures
9586/// happening after a packet has been authenticated should still cause the
9587/// connection to be aborted.
9588fn drop_pkt_on_err(
9589    e: Error, recv_count: usize, is_server: bool, trace_id: &str,
9590) -> Error {
9591    // On the server, if no other packet has been successfully processed, abort
9592    // the connection to avoid keeping the connection open when only junk is
9593    // received.
9594    if is_server && recv_count == 0 {
9595        return e;
9596    }
9597
9598    trace!("{trace_id} dropped invalid packet");
9599
9600    // Ignore other invalid packets that haven't been authenticated to prevent
9601    // man-in-the-middle and man-on-the-side attacks.
9602    Error::Done
9603}
9604
9605struct AddrTupleFmt(SocketAddr, SocketAddr);
9606
9607impl std::fmt::Display for AddrTupleFmt {
9608    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
9609        let AddrTupleFmt(src, dst) = &self;
9610
9611        if src.ip().is_unspecified() || dst.ip().is_unspecified() {
9612            return Ok(());
9613        }
9614
9615        f.write_fmt(format_args!("src:{src} dst:{dst}"))
9616    }
9617}
9618
9619/// Statistics about the connection.
9620///
9621/// A connection's statistics can be collected using the [`stats()`] method.
9622///
9623/// [`stats()`]: struct.Connection.html#method.stats
9624#[derive(Clone, Default)]
9625#[non_exhaustive]
9626pub struct Stats {
9627    /// The number of QUIC packets received.
9628    pub recv: usize,
9629
9630    /// The number of QUIC packets sent.
9631    pub sent: usize,
9632
9633    /// The number of QUIC packets that were lost.
9634    pub lost: usize,
9635
9636    /// The number of QUIC packets that were marked as lost but later acked.
9637    pub spurious_lost: usize,
9638
9639    /// The number of sent QUIC packets with retransmitted data.
9640    pub retrans: usize,
9641
9642    /// The number of sent bytes.
9643    pub sent_bytes: u64,
9644
9645    /// The number of received bytes.
9646    pub recv_bytes: u64,
9647
9648    /// The number of bytes sent acked.
9649    pub acked_bytes: u64,
9650
9651    /// The number of bytes sent lost.
9652    pub lost_bytes: u64,
9653
9654    /// The number of stream bytes retransmitted.
9655    pub stream_retrans_bytes: u64,
9656
9657    /// The number of DATAGRAM frames received.
9658    pub dgram_recv: usize,
9659
9660    /// The number of DATAGRAM frames sent.
9661    pub dgram_sent: usize,
9662
9663    /// The number of known paths for the connection.
9664    pub paths_count: usize,
9665
9666    /// The number of streams reset by local.
9667    pub reset_stream_count_local: u64,
9668
9669    /// The number of streams stopped by local.
9670    pub stopped_stream_count_local: u64,
9671
9672    /// The number of streams reset by remote.
9673    pub reset_stream_count_remote: u64,
9674
9675    /// The number of streams stopped by remote.
9676    pub stopped_stream_count_remote: u64,
9677
9678    /// The number of DATA_BLOCKED frames sent due to hitting the connection
9679    /// flow control limit.
9680    pub data_blocked_sent_count: u64,
9681
9682    /// The number of STREAM_DATA_BLOCKED frames sent due to a stream hitting
9683    /// the stream flow control limit.
9684    pub stream_data_blocked_sent_count: u64,
9685
9686    /// The number of DATA_BLOCKED frames received from the remote.
9687    pub data_blocked_recv_count: u64,
9688
9689    /// The number of STREAM_DATA_BLOCKED frames received from the remote.
9690    pub stream_data_blocked_recv_count: u64,
9691
9692    /// The number of STREAMS_BLOCKED frames for bidirectional streams received
9693    /// from the remote, indicating the peer is blocked on opening new
9694    /// bidirectional streams.
9695    pub streams_blocked_bidi_recv_count: u64,
9696
9697    /// The number of STREAMS_BLOCKED frames for unidirectional streams received
9698    /// from the remote, indicating the peer is blocked on opening new
9699    /// unidirectional streams.
9700    pub streams_blocked_uni_recv_count: u64,
9701
9702    /// The total number of PATH_CHALLENGE frames that were received.
9703    pub path_challenge_rx_count: u64,
9704
9705    /// The number of times send() was blocked because the anti-amplification
9706    /// budget (bytes received × max_amplification_factor) was exhausted.
9707    pub amplification_limited_count: u64,
9708
9709    /// Total duration during which this side of the connection was
9710    /// actively sending bytes or waiting for those bytes to be acked.
9711    pub bytes_in_flight_duration: Duration,
9712
9713    /// Health state of the connection's tx_buffered.
9714    ///
9715    /// Indicates whether the streams.tx_buffered value is consistent with
9716    /// the actual sum of bytes buffered across all stream send buffers.
9717    /// Returns `Ok` if consistent, `Inconsistent` if there's a mismatch.
9718    pub tx_buffered_state: TxBufferTrackingState,
9719}
9720
9721impl std::fmt::Debug for Stats {
9722    #[inline]
9723    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
9724        write!(
9725            f,
9726            "recv={} sent={} lost={} retrans={}",
9727            self.recv, self.sent, self.lost, self.retrans,
9728        )?;
9729
9730        write!(
9731            f,
9732            " sent_bytes={} recv_bytes={} lost_bytes={}",
9733            self.sent_bytes, self.recv_bytes, self.lost_bytes,
9734        )?;
9735
9736        Ok(())
9737    }
9738}
9739
9740#[doc(hidden)]
9741#[cfg(any(test, feature = "internal"))]
9742pub mod test_utils;
9743
9744#[cfg(test)]
9745mod tests;
9746
9747pub use crate::packet::ConnectionId;
9748pub use crate::packet::Header;
9749pub use crate::packet::Type;
9750
9751pub use crate::path::PathEvent;
9752pub use crate::path::PathStats;
9753pub use crate::path::SocketAddrIter;
9754
9755pub use crate::recovery::BbrBwLoReductionStrategy;
9756pub use crate::recovery::BbrParams;
9757#[cfg(feature = "internal")]
9758pub use crate::recovery::BbrRttJumpDetector;
9759pub use crate::recovery::CongestionControlAlgorithm;
9760pub use crate::recovery::StartupExit;
9761pub use crate::recovery::StartupExitReason;
9762
9763pub use crate::stream::StreamIter;
9764
9765pub use crate::transport_params::TransportParams;
9766pub use crate::transport_params::UnknownTransportParameter;
9767pub use crate::transport_params::UnknownTransportParameterIterator;
9768pub use crate::transport_params::UnknownTransportParameters;
9769pub use crate::transport_params::MAX_ACK_DELAY_EXPONENT;
9770
9771pub use crate::buffers::BufFactory;
9772pub use crate::buffers::BufSplit;
9773
9774pub use crate::error::ConnectionError;
9775pub use crate::error::Error;
9776pub use crate::error::Result;
9777pub use crate::error::WireErrorCode;
9778
9779mod buffers;
9780mod cid;
9781mod crypto;
9782mod dgram;
9783mod error;
9784#[cfg(feature = "ffi")]
9785mod ffi;
9786mod flowcontrol;
9787mod frame;
9788pub mod h3;
9789mod minmax;
9790mod packet;
9791mod path;
9792mod pmtud;
9793mod rand;
9794mod range_buf;
9795mod ranges;
9796mod recovery;
9797mod stream;
9798mod tls;
9799mod transport_params;