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