quiche/
lib.rs

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