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