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