Skip to main content

quiche/
lib.rs

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