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