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