Skip to main content

quinn_proto/connection/
mod.rs

1use std::{
2    cmp,
3    collections::VecDeque,
4    convert::TryFrom,
5    fmt, io, mem,
6    net::{IpAddr, SocketAddr},
7    sync::Arc,
8};
9
10use bytes::{Bytes, BytesMut};
11use frame::StreamMetaVec;
12
13use rand::{RngExt, SeedableRng, rngs::StdRng};
14use thiserror::Error;
15use tracing::{debug, error, trace, trace_span, warn};
16
17use crate::{
18    Dir, Duration, EndpointConfig, Frame, Instant, MAX_CID_SIZE, MAX_STREAM_COUNT,
19    MIN_INITIAL_SIZE, Side, StreamId, TIMER_GRANULARITY, TokenStore, Transmit, TransportError,
20    TransportErrorCode, VarInt,
21    cid_generator::ConnectionIdGenerator,
22    cid_queue::CidQueue,
23    coding::BufMutExt,
24    config::{ServerConfig, TransportConfig},
25    crypto::{self, KeyPair, Keys, PacketKey},
26    frame::{self, Close, Datagram, FrameStruct, NewConnectionId, NewToken},
27    packet::{
28        FixedLengthConnectionIdParser, Header, InitialHeader, InitialPacket, LongType, Packet,
29        PacketNumber, PartialDecode, SpaceId,
30    },
31    range_set::ArrayRangeSet,
32    shared::{
33        ConnectionEvent, ConnectionEventInner, ConnectionId, DatagramConnectionEvent, EcnCodepoint,
34        EndpointEvent, EndpointEventInner,
35    },
36    token::{ResetToken, Token, TokenPayload},
37    transport_parameters::TransportParameters,
38};
39
40mod ack_frequency;
41use ack_frequency::AckFrequencyState;
42
43mod assembler;
44pub use assembler::Chunk;
45
46mod cid_state;
47use cid_state::CidState;
48
49mod datagrams;
50use datagrams::DatagramState;
51pub use datagrams::{Datagrams, SendDatagramError};
52
53mod mtud;
54mod pacing;
55
56mod packet_builder;
57use packet_builder::PacketBuilder;
58
59mod packet_crypto;
60use packet_crypto::{PrevCrypto, ZeroRttCrypto};
61
62mod paths;
63pub use paths::RttEstimator;
64use paths::{PathData, PathResponses};
65
66pub(crate) mod qlog;
67
68mod send_buffer;
69
70mod spaces;
71#[cfg(fuzzing)]
72pub use spaces::Retransmits;
73#[cfg(not(fuzzing))]
74use spaces::Retransmits;
75use spaces::{PacketNumberFilter, PacketSpace, SendableFrames, SentPacket, ThinRetransmits};
76
77mod stats;
78pub use stats::{ConnectionStats, FrameStats, PathStats, UdpStats};
79
80mod streams;
81#[cfg(fuzzing)]
82pub use streams::StreamsState;
83#[cfg(not(fuzzing))]
84use streams::StreamsState;
85pub use streams::{
86    Chunks, ClosedStream, FinishError, ReadError, ReadableError, RecvStream, SendStream,
87    ShouldTransmit, StreamEvent, Streams, WriteError, Written,
88};
89
90mod timer;
91use crate::congestion::Controller;
92use timer::{Timer, TimerTable};
93
94/// Protocol state and logic for a single QUIC connection
95///
96/// Objects of this type receive [`ConnectionEvent`]s and emit [`EndpointEvent`]s and application
97/// [`Event`]s to make progress. To handle timeouts, a `Connection` returns timer updates and
98/// expects timeouts through various methods. A number of simple getter methods are exposed
99/// to allow callers to inspect some of the connection state.
100///
101/// `Connection` has roughly 4 types of methods:
102///
103/// - A. Simple getters, taking `&self`
104/// - B. Handlers for incoming events from the network or system, named `handle_*`.
105/// - C. State machine mutators, for incoming commands from the application. For convenience we
106///   refer to this as "performing I/O" below, however as per the design of this library none of the
107///   functions actually perform system-level I/O. For example, [`read`](RecvStream::read) and
108///   [`write`](SendStream::write), but also things like [`reset`](SendStream::reset).
109/// - D. Polling functions for outgoing events or actions for the caller to
110///   take, named `poll_*`.
111///
112/// The simplest way to use this API correctly is to call (B) and (C) whenever
113/// appropriate, then after each of those calls, as soon as feasible call all
114/// polling methods (D) and deal with their outputs appropriately, e.g. by
115/// passing it to the application or by making a system-level I/O call. You
116/// should call the polling functions in this order:
117///
118/// 1. [`poll_transmit`](Self::poll_transmit)
119/// 2. [`poll_timeout`](Self::poll_timeout)
120/// 3. [`poll_endpoint_events`](Self::poll_endpoint_events)
121/// 4. [`poll`](Self::poll)
122///
123/// Currently the only actual dependency is from (2) to (1), however additional
124/// dependencies may be added in future, so the above order is recommended.
125///
126/// (A) may be called whenever desired.
127///
128/// Care should be made to ensure that the input events represent monotonically
129/// increasing time. Specifically, calling [`handle_timeout`](Self::handle_timeout)
130/// with events of the same [`Instant`] may be interleaved in any order with a
131/// call to [`handle_event`](Self::handle_event) at that same instant; however
132/// events or timeouts with different instants must not be interleaved.
133pub struct Connection {
134    endpoint_config: Arc<EndpointConfig>,
135    config: Arc<TransportConfig>,
136    rng: StdRng,
137    crypto: Box<dyn crypto::Session>,
138    /// The CID we initially chose, for use during the handshake
139    handshake_cid: ConnectionId,
140    /// The CID the peer initially chose, for use during the handshake
141    rem_handshake_cid: ConnectionId,
142    /// The "real" local IP address which was was used to receive the initial packet.
143    /// This is only populated for the server case, and if known
144    local_ip: Option<IpAddr>,
145    path: PathData,
146    /// Incremented every time we see a new path
147    ///
148    /// Stored separately from `path.generation` to account for aborted migrations
149    path_counter: u64,
150    /// Whether MTU detection is supported in this environment
151    allow_mtud: bool,
152    prev_path: Option<(ConnectionId, PathData)>,
153    state: State,
154    side: ConnectionSide,
155    /// Whether or not 0-RTT was enabled during the handshake. Does not imply acceptance.
156    zero_rtt_enabled: bool,
157    /// Set if 0-RTT is supported, then cleared when no longer needed.
158    zero_rtt_crypto: Option<ZeroRttCrypto>,
159    key_phase: bool,
160    /// How many packets are in the current key phase. Used only for `Data` space.
161    key_phase_size: u64,
162    /// Transport parameters set by the peer
163    peer_params: TransportParameters,
164    /// Source ConnectionId of the first packet received from the peer
165    orig_rem_cid: ConnectionId,
166    /// Destination ConnectionId sent by the client on the first Initial
167    initial_dst_cid: ConnectionId,
168    /// The value that the server included in the Source Connection ID field of a Retry packet, if
169    /// one was received
170    retry_src_cid: Option<ConnectionId>,
171    events: VecDeque<Event>,
172    endpoint_events: VecDeque<EndpointEventInner>,
173    /// Whether the spin bit is in use for this connection
174    spin_enabled: bool,
175    /// Outgoing spin bit state
176    spin: bool,
177    /// Packet number spaces: initial, handshake, 1-RTT
178    spaces: [PacketSpace; 3],
179    /// Highest usable packet number space
180    highest_space: SpaceId,
181    /// 1-RTT keys used prior to a key update
182    prev_crypto: Option<PrevCrypto>,
183    /// 1-RTT keys to be used for the next key update
184    ///
185    /// These are generated in advance to prevent timing attacks and/or DoS by third-party attackers
186    /// spoofing key updates.
187    next_crypto: Option<KeyPair<Box<dyn PacketKey>>>,
188    accepted_0rtt: bool,
189    /// Whether the idle timer should be reset the next time an ack-eliciting packet is transmitted.
190    permit_idle_reset: bool,
191    /// Negotiated idle timeout
192    idle_timeout: Option<Duration>,
193    /// The time we send next bundled ACK
194    ///
195    /// The goal is to wait long enough for the peer to acknowledge our previous
196    /// bundled ACK (see `next_bundled_ack_delay`).
197    /// A packet-count threshold would over- or under-shoot this depending on how fast we happen
198    /// to be sending, so a time threshold is used instead.
199    next_bundled_ack_time: Option<Instant>,
200    timers: TimerTable,
201    /// Number of packets received which could not be authenticated
202    authentication_failures: u64,
203    /// Why the connection was lost, if it has been
204    error: Option<ConnectionError>,
205    /// Identifies Data-space packet numbers to skip. Not used in earlier spaces.
206    packet_number_filter: PacketNumberFilter,
207
208    //
209    // Queued non-retransmittable 1-RTT data
210    //
211    /// Responses to PATH_CHALLENGE frames
212    path_responses: PathResponses,
213    close: bool,
214
215    //
216    // ACK frequency
217    //
218    ack_frequency: AckFrequencyState,
219
220    //
221    // Loss Detection
222    //
223    /// The number of times a PTO has been sent without receiving an ack.
224    pto_count: u32,
225
226    //
227    // Congestion Control
228    //
229    /// Whether the most recently received packet had an ECN codepoint set
230    receiving_ecn: bool,
231    /// Number of packets authenticated
232    total_authed_packets: u64,
233    /// Whether the last `poll_transmit` call yielded no data because there was
234    /// no outgoing application data.
235    app_limited: bool,
236
237    streams: StreamsState,
238    /// Surplus remote CIDs for future use on new paths
239    rem_cids: CidQueue,
240    // Attributes of CIDs generated by local peer
241    local_cid_state: CidState,
242    /// State of the unreliable datagram extension
243    datagrams: DatagramState,
244    /// Connection level statistics
245    stats: ConnectionStats,
246    /// QUIC version used for the connection.
247    version: u32,
248}
249
250impl Connection {
251    pub(crate) fn new(
252        endpoint_config: Arc<EndpointConfig>,
253        config: Arc<TransportConfig>,
254        init_cid: ConnectionId,
255        loc_cid: ConnectionId,
256        rem_cid: ConnectionId,
257        remote: SocketAddr,
258        local_ip: Option<IpAddr>,
259        crypto: Box<dyn crypto::Session>,
260        cid_gen: &dyn ConnectionIdGenerator,
261        now: Instant,
262        version: u32,
263        allow_mtud: bool,
264        rng_seed: [u8; 32],
265        side_args: SideArgs,
266    ) -> Self {
267        let pref_addr_cid = side_args.pref_addr_cid();
268        let path_validated = side_args.path_validated();
269        let connection_side = ConnectionSide::from(side_args);
270        let side = connection_side.side();
271        let initial_space = PacketSpace {
272            crypto: Some(crypto.initial_keys(&init_cid, side)),
273            ..PacketSpace::new(now)
274        };
275        let state = State::Handshake(state::Handshake {
276            rem_cid_set: side.is_server(),
277            expected_token: Bytes::new(),
278            client_hello: None,
279        });
280        let mut rng = StdRng::from_seed(rng_seed);
281        let mut this = Self {
282            endpoint_config,
283            crypto,
284            handshake_cid: loc_cid,
285            rem_handshake_cid: rem_cid,
286            local_cid_state: CidState::new(
287                cid_gen.cid_len(),
288                cid_gen.cid_lifetime(),
289                now,
290                if pref_addr_cid.is_some() { 2 } else { 1 },
291            ),
292            path: PathData::new(remote, allow_mtud, None, 0, now, &config),
293            path_counter: 0,
294            allow_mtud,
295            local_ip,
296            prev_path: None,
297            state,
298            side: connection_side,
299            zero_rtt_enabled: false,
300            zero_rtt_crypto: None,
301            key_phase: false,
302            // A small initial key phase size ensures peers that don't handle key updates correctly
303            // fail sooner rather than later. It's okay for both peers to do this, as the first one
304            // to perform an update will reset the other's key phase size in `update_keys`, and a
305            // simultaneous key update by both is just like a regular key update with a really fast
306            // response. Inspired by quic-go's similar behavior of performing the first key update
307            // at the 100th short-header packet.
308            key_phase_size: rng.random_range(10..1000),
309            peer_params: TransportParameters::default(),
310            orig_rem_cid: rem_cid,
311            initial_dst_cid: init_cid,
312            retry_src_cid: None,
313            events: VecDeque::new(),
314            endpoint_events: VecDeque::new(),
315            spin_enabled: config.allow_spin && rng.random_ratio(7, 8),
316            spin: false,
317            spaces: [initial_space, PacketSpace::new(now), PacketSpace::new(now)],
318            highest_space: SpaceId::Initial,
319            prev_crypto: None,
320            next_crypto: None,
321            accepted_0rtt: false,
322            permit_idle_reset: true,
323            idle_timeout: match config.max_idle_timeout {
324                None | Some(VarInt(0)) => None,
325                Some(dur) => Some(Duration::from_millis(dur.0)),
326            },
327            timers: TimerTable::default(),
328            authentication_failures: 0,
329            error: None,
330            #[cfg(test)]
331            packet_number_filter: match config.deterministic_packet_numbers {
332                false => PacketNumberFilter::new(&mut rng),
333                true => PacketNumberFilter::disabled(),
334            },
335            #[cfg(not(test))]
336            packet_number_filter: PacketNumberFilter::new(&mut rng),
337
338            path_responses: PathResponses::default(),
339            close: false,
340
341            ack_frequency: AckFrequencyState::new(get_max_ack_delay(
342                &TransportParameters::default(),
343            )),
344            next_bundled_ack_time: None,
345
346            pto_count: 0,
347
348            app_limited: false,
349            receiving_ecn: false,
350            total_authed_packets: 0,
351
352            streams: StreamsState::new(
353                side,
354                config.max_concurrent_uni_streams,
355                config.max_concurrent_bidi_streams,
356                config.send_window,
357                config.receive_window,
358                config.stream_receive_window,
359            ),
360            datagrams: DatagramState::default(),
361            config,
362            rem_cids: CidQueue::new(rem_cid),
363            rng,
364            stats: ConnectionStats::default(),
365            version,
366        };
367        if path_validated {
368            this.on_path_validated();
369        }
370        if side.is_client() {
371            // Kick off the connection
372            this.write_crypto();
373            this.init_0rtt();
374        }
375        this
376    }
377
378    /// Returns the next time at which `handle_timeout` should be called
379    ///
380    /// The value returned may change after:
381    /// - the application performed some I/O on the connection
382    /// - a call was made to `handle_event`
383    /// - a call to `poll_transmit` returned `Some`
384    /// - a call was made to `handle_timeout`
385    #[must_use]
386    pub fn poll_timeout(&mut self) -> Option<Instant> {
387        self.timers.next_timeout()
388    }
389
390    /// Returns application-facing events
391    ///
392    /// Connections should be polled for events after:
393    /// - a call was made to `handle_event`
394    /// - a call was made to `handle_timeout`
395    #[must_use]
396    pub fn poll(&mut self) -> Option<Event> {
397        if let Some(x) = self.events.pop_front() {
398            return Some(x);
399        }
400
401        if let Some(event) = self.streams.poll() {
402            return Some(Event::Stream(event));
403        }
404
405        if let Some(err) = self.error.take() {
406            return Some(Event::ConnectionLost { reason: err });
407        }
408
409        None
410    }
411
412    /// Return endpoint-facing events
413    #[must_use]
414    pub fn poll_endpoint_events(&mut self) -> Option<EndpointEvent> {
415        self.endpoint_events.pop_front().map(EndpointEvent)
416    }
417
418    /// Provide control over streams
419    #[must_use]
420    pub fn streams(&mut self) -> Streams<'_> {
421        Streams {
422            state: &mut self.streams,
423            conn_state: &self.state,
424        }
425    }
426
427    /// Provide control over streams
428    #[must_use]
429    pub fn recv_stream(&mut self, id: StreamId) -> RecvStream<'_> {
430        assert!(id.dir() == Dir::Bi || id.initiator() != self.side.side());
431        RecvStream {
432            id,
433            state: &mut self.streams,
434            pending: &mut self.spaces[SpaceId::Data].pending,
435        }
436    }
437
438    /// Provide control over streams
439    #[must_use]
440    pub fn send_stream(&mut self, id: StreamId) -> SendStream<'_> {
441        assert!(id.dir() == Dir::Bi || id.initiator() == self.side.side());
442        SendStream {
443            id,
444            state: &mut self.streams,
445            pending: &mut self.spaces[SpaceId::Data].pending,
446            conn_state: &self.state,
447        }
448    }
449
450    /// Returns packets to transmit
451    ///
452    /// Connections should be polled for transmit after:
453    /// - the application performed some I/O on the connection
454    /// - a call was made to `handle_event`
455    /// - a call was made to `handle_timeout`
456    ///
457    /// `max_datagrams` specifies how many datagrams can be returned inside a
458    /// single Transmit using GSO. This must be at least 1.
459    #[must_use]
460    pub fn poll_transmit(
461        &mut self,
462        now: Instant,
463        max_datagrams: usize,
464        buf: &mut Vec<u8>,
465    ) -> Option<Transmit> {
466        assert!(max_datagrams != 0);
467        let max_datagrams = match self.config.enable_segmentation_offload {
468            false => 1,
469            true => max_datagrams,
470        };
471
472        let mut num_datagrams = 0;
473        // Position in `buf` of the first byte of the current UDP datagram. When coalescing QUIC
474        // packets, this can be earlier than the start of the current QUIC packet.
475        let mut datagram_start = 0;
476        let mut segment_size = usize::from(self.path.current_mtu());
477        // The peer's maximum UDP payload size can reduce the path MTU below our configured minimum.
478        let min_mtu = Ord::min(self.config.min_mtu, self.path.current_mtu());
479
480        if let Some(challenge) = self.send_path_challenge(now, buf) {
481            return Some(challenge);
482        }
483
484        // If we need to send a probe, make sure we have something to send.
485        for space in SpaceId::iter() {
486            let request_immediate_ack =
487                space == SpaceId::Data && self.peer_supports_ack_frequency();
488            self.spaces[space].maybe_queue_probe(request_immediate_ack, &self.streams);
489        }
490
491        // Check whether we need to send a close message
492        let close = match self.state {
493            State::Drained => {
494                self.app_limited = true;
495                return None;
496            }
497            State::Draining | State::Closed(_) => {
498                // self.close is only reset once the associated packet had been
499                // encoded successfully
500                if !self.close {
501                    self.app_limited = true;
502                    return None;
503                }
504                true
505            }
506            _ => false,
507        };
508
509        // Check whether we need to send an ACK_FREQUENCY frame
510        if let Some(config) = &self.config.ack_frequency_config {
511            self.spaces[SpaceId::Data].pending.ack_frequency = self
512                .ack_frequency
513                .should_send_ack_frequency(self.path.rtt.get(), config, &self.peer_params)
514                && self.highest_space == SpaceId::Data
515                && self.peer_supports_ack_frequency();
516        }
517
518        // Reserving capacity can provide more capacity than we asked for. However, we are not
519        // allowed to write more than `segment_size`. Therefore the maximum capacity is tracked
520        // separately.
521        let mut buf_capacity = 0;
522
523        let mut coalesce = true;
524        let mut builder_storage: Option<PacketBuilder> = None;
525        let mut sent_frames = None;
526        let mut pad_datagram = false;
527        let mut pad_datagram_to_mtu = false;
528        let mut congestion_blocked = false;
529
530        // Iterate over all spaces and find data to send
531        let mut space_idx = 0;
532        let spaces = [SpaceId::Initial, SpaceId::Handshake, SpaceId::Data];
533        // This loop will potentially spend multiple iterations in the same `SpaceId`,
534        // so we cannot trivially rewrite it to take advantage of `SpaceId::iter()`.
535        while space_idx < spaces.len() {
536            let space_id = spaces[space_idx];
537            // Number of bytes available for frames if this is a 1-RTT packet. We're guaranteed to
538            // be able to send an individual frame at least this large in the next 1-RTT
539            // packet. This could be generalized to support every space, but it's only needed to
540            // handle large fixed-size frames, which only exist in 1-RTT (application datagrams). We
541            // don't account for coalesced packets potentially occupying space because frames can
542            // always spill into the next datagram.
543            let pn = self.packet_number_filter.peek(&self.spaces[SpaceId::Data]);
544            let frame_space_1rtt =
545                segment_size.saturating_sub(self.predict_1rtt_overhead(Some(pn)));
546
547            // Is there data or a close message to send in this space?
548            let can_send = self.space_can_send(space_id, frame_space_1rtt);
549            if can_send.is_empty() && (!close || self.spaces[space_id].crypto.is_none()) {
550                space_idx += 1;
551                continue;
552            }
553
554            let mut ack_eliciting = !self.spaces[space_id].pending.is_empty(&self.streams)
555                || self.spaces[space_id].ping_pending
556                || self.spaces[space_id].immediate_ack_pending;
557            if space_id == SpaceId::Data {
558                ack_eliciting |= self.can_send_1rtt(frame_space_1rtt);
559            }
560
561            pad_datagram_to_mtu |= space_id == SpaceId::Data && self.config.pad_to_mtu;
562
563            // Can we append more data into the current buffer?
564            // It is not safe to assume that `buf.len()` is the end of the data,
565            // since the last packet might not have been finished.
566            let buf_end = if let Some(builder) = &builder_storage {
567                buf.len().max(builder.min_size) + builder.tag_len
568            } else {
569                buf.len()
570            };
571
572            let tag_len = if let Some(ref crypto) = self.spaces[space_id].crypto {
573                crypto.packet.local.tag_len()
574            } else if space_id == SpaceId::Data {
575                self.zero_rtt_crypto.as_ref().expect(
576                    "sending packets in the application data space requires known 0-RTT or 1-RTT keys",
577                ).packet.tag_len()
578            } else {
579                unreachable!("tried to send {:?} packet without keys", space_id)
580            };
581            if !coalesce || buf_capacity - buf_end < MIN_PACKET_SPACE + tag_len {
582                // We need to send 1 more datagram and extend the buffer for that.
583
584                // Is 1 more datagram allowed?
585                if num_datagrams >= max_datagrams {
586                    // No more datagrams allowed
587                    break;
588                }
589
590                // Anti-amplification is only based on `total_sent`, which gets
591                // updated at the end of this method. Therefore we pass the amount
592                // of bytes for datagrams that are already created, as well as 1 byte
593                // for starting another datagram. If there is any anti-amplification
594                // budget left, we always allow a full MTU to be sent
595                // (see https://github.com/quinn-rs/quinn/issues/1082)
596                if self
597                    .path
598                    .anti_amplification_blocked(segment_size as u64 * (num_datagrams as u64) + 1)
599                {
600                    trace!("blocked by anti-amplification");
601                    break;
602                }
603
604                // Congestion control and pacing checks
605                // Tail loss probes must not be blocked by congestion, or a deadlock could arise
606                if ack_eliciting && self.spaces[space_id].loss_probes == 0 {
607                    // Assume the current packet will get padded to fill the segment
608                    let untracked_bytes = if let Some(builder) = &builder_storage {
609                        buf_capacity - builder.partial_encode.start
610                    } else {
611                        0
612                    } as u64;
613                    debug_assert!(untracked_bytes <= segment_size as u64);
614
615                    let bytes_to_send = segment_size as u64 + untracked_bytes;
616                    if self.path.in_flight.bytes + bytes_to_send >= self.path.congestion.window() {
617                        space_idx += 1;
618                        congestion_blocked = true;
619                        // We continue instead of breaking here in order to avoid
620                        // blocking loss probes queued for higher spaces.
621                        trace!("blocked by congestion control");
622                        continue;
623                    }
624
625                    // Check whether the next datagram is blocked by pacing
626                    let smoothed_rtt = self.path.rtt.get();
627                    if let Some(delay) = self.path.pacing.delay(
628                        smoothed_rtt,
629                        bytes_to_send,
630                        self.path.current_mtu(),
631                        self.path.congestion.window(),
632                        now,
633                    ) {
634                        self.timers.set(Timer::Pacing, delay);
635                        congestion_blocked = true;
636                        // Loss probes should be subject to pacing, even though
637                        // they are not congestion controlled.
638                        trace!("blocked by pacing");
639                        break;
640                    }
641                }
642
643                // Finish current packet
644                if let Some(mut builder) = builder_storage.take() {
645                    if pad_datagram {
646                        builder.pad_to(min_mtu);
647                    }
648
649                    if num_datagrams > 1 || pad_datagram_to_mtu {
650                        // If too many padding bytes would be required to continue the GSO batch
651                        // after this packet, end the GSO batch here. Ensures that fixed-size frames
652                        // with heterogeneous sizes (e.g. application datagrams) won't inadvertently
653                        // waste large amounts of bandwidth. The exact threshold is a bit arbitrary
654                        // and might benefit from further tuning, though there's no universally
655                        // optimal value.
656                        //
657                        // Additionally, if this datagram is a loss probe and `segment_size` is
658                        // larger than `min_mtu`, then padding it to `segment_size` to continue
659                        // the GSO batch would risk failure to recover from a reduction in path
660                        // MTU. Loss probes are the only packets for which we might grow
661                        // `buf_capacity` by less than `segment_size`.
662                        const MAX_PADDING: usize = 16;
663                        let packet_len_unpadded = cmp::max(builder.min_size, buf.len())
664                            - datagram_start
665                            + builder.tag_len;
666                        if (packet_len_unpadded + MAX_PADDING < segment_size
667                            && !pad_datagram_to_mtu)
668                            || datagram_start + segment_size > buf_capacity
669                        {
670                            trace!(
671                                "GSO truncated by demand for {} padding bytes or loss probe",
672                                segment_size - packet_len_unpadded
673                            );
674                            builder_storage = Some(builder);
675                            break;
676                        }
677
678                        // Pad the current datagram to GSO segment size so it can be included in the
679                        // GSO batch.
680                        builder.pad_to(segment_size as u16);
681                    }
682
683                    builder.finish_and_track(now, self, sent_frames.take(), buf);
684
685                    if num_datagrams == 1 {
686                        // Set the segment size for this GSO batch to the size of the first UDP
687                        // datagram in the batch. Larger data that cannot be fragmented
688                        // (e.g. application datagrams) will be included in a future batch. When
689                        // sending large enough volumes of data for GSO to be useful, we expect
690                        // packet sizes to usually be consistent, e.g. populated by max-size STREAM
691                        // frames or uniformly sized datagrams.
692                        segment_size = buf.len();
693                        // Clip the unused capacity out of the buffer so future packets don't
694                        // overrun
695                        buf_capacity = buf.len();
696
697                        // Check whether the data we planned to send will fit in the reduced segment
698                        // size. If not, bail out and leave it for the next GSO batch so we don't
699                        // end up trying to send an empty packet. We can't easily compute the right
700                        // segment size before the original call to `space_can_send`, because at
701                        // that time we haven't determined whether we're going to coalesce with the
702                        // first datagram or potentially pad it to `min_mtu`.
703                        if space_id == SpaceId::Data {
704                            let frame_space_1rtt =
705                                segment_size.saturating_sub(self.predict_1rtt_overhead(Some(pn)));
706                            if self.space_can_send(space_id, frame_space_1rtt).is_empty() {
707                                break;
708                            }
709                        }
710                    }
711                }
712
713                // Allocate space for another datagram
714                let next_datagram_size_limit = match self.spaces[space_id].loss_probes {
715                    0 => segment_size,
716                    _ => {
717                        self.spaces[space_id].loss_probes -= 1;
718                        // Clamp the datagram to at most the minimum MTU to ensure that loss probes
719                        // can get through and enable recovery even if the path MTU has shrank
720                        // unexpectedly.
721                        std::cmp::min(segment_size, usize::from(min_mtu))
722                    }
723                };
724                buf_capacity += next_datagram_size_limit;
725                if buf.capacity() < buf_capacity {
726                    // We reserve the maximum space for sending `max_datagrams` upfront
727                    // to avoid any reallocations if more datagrams have to be appended later on.
728                    // Benchmarks have shown shown a 5-10% throughput improvement
729                    // compared to continuously resizing the datagram buffer.
730                    // While this will lead to over-allocation for small transmits
731                    // (e.g. purely containing ACKs), modern memory allocators
732                    // (e.g. mimalloc and jemalloc) will pool certain allocation sizes
733                    // and therefore this is still rather efficient.
734                    buf.reserve(max_datagrams * segment_size);
735                }
736                num_datagrams += 1;
737                coalesce = true;
738                pad_datagram = false;
739                datagram_start = buf.len();
740
741                debug_assert_eq!(
742                    datagram_start % segment_size,
743                    0,
744                    "datagrams in a GSO batch must be aligned to the segment size"
745                );
746            } else {
747                // We can append/coalesce the next packet into the current
748                // datagram.
749                // Finish current packet without adding extra padding
750                if let Some(builder) = builder_storage.take() {
751                    builder.finish_and_track(now, self, sent_frames.take(), buf);
752                }
753            }
754
755            debug_assert!(buf_capacity - buf.len() >= MIN_PACKET_SPACE);
756
757            //
758            // From here on, we've determined that a packet will definitely be sent.
759            //
760
761            if self.spaces[SpaceId::Initial].crypto.is_some()
762                && space_id == SpaceId::Handshake
763                && self.side.is_client()
764            {
765                // A client stops both sending and processing Initial packets when it
766                // sends its first Handshake packet.
767                self.discard_space(now, SpaceId::Initial);
768            }
769            if let Some(ref mut prev) = self.prev_crypto {
770                prev.update_unacked = false;
771            }
772
773            debug_assert!(
774                builder_storage.is_none() && sent_frames.is_none(),
775                "Previous packet must have been finished"
776            );
777
778            let builder = builder_storage.insert(PacketBuilder::new(
779                now,
780                space_id,
781                self.rem_cids.active(),
782                buf,
783                buf_capacity,
784                datagram_start,
785                ack_eliciting,
786                self,
787            )?);
788            coalesce = coalesce && !builder.short_header;
789
790            // https://tools.ietf.org/html/draft-ietf-quic-transport-34#section-14.1
791            pad_datagram |=
792                space_id == SpaceId::Initial && (self.side.is_client() || ack_eliciting);
793
794            if close {
795                trace!("sending CONNECTION_CLOSE");
796                // Encode ACKs before the ConnectionClose message, to give the receiver
797                // a better approximate on what data has been processed. This is
798                // especially important with ack delay, since the peer might not
799                // have gotten any other ACK for the data earlier on.
800                if !self.spaces[space_id].pending_acks.ranges().is_empty() {
801                    // Reserve room for CONNECTION_CLOSE even when an Initial token leaves
802                    // little space after the header.
803                    Self::try_populate_acks(
804                        now,
805                        self.receiving_ecn,
806                        &mut SentFrames::default(),
807                        &mut self.spaces[space_id],
808                        buf,
809                        &mut self.stats,
810                        builder.max_size - frame::ConnectionClose::SIZE_BOUND,
811                    );
812                }
813
814                if buf.len() + frame::ConnectionClose::SIZE_BOUND <= builder.max_size {
815                    let max_frame_size = builder.max_size - buf.len();
816                    match self.state {
817                        State::Closed(state::Closed { ref reason }) => {
818                            if space_id == SpaceId::Data || reason.is_transport_layer() {
819                                reason.encode(buf, max_frame_size)
820                            } else {
821                                frame::ConnectionClose {
822                                    error_code: TransportErrorCode::APPLICATION_ERROR,
823                                    frame_type: None,
824                                    reason: Bytes::new(),
825                                }
826                                .encode(buf, max_frame_size)
827                            }
828                        }
829                        State::Draining => frame::ConnectionClose {
830                            error_code: TransportErrorCode::NO_ERROR,
831                            frame_type: None,
832                            reason: Bytes::new(),
833                        }
834                        .encode(buf, max_frame_size),
835                        _ => unreachable!(
836                            "tried to make a close packet when the connection wasn't closed"
837                        ),
838                    }
839                }
840                if space_id == self.highest_space {
841                    // Don't send another close packet
842                    self.close = false;
843                    // `CONNECTION_CLOSE` is the final packet
844                    break;
845                } else {
846                    // Send a close frame in every possible space for robustness, per RFC9000
847                    // "Immediate Close during the Handshake". Don't bother trying to send anything
848                    // else.
849                    space_idx += 1;
850                    continue;
851                }
852            }
853
854            // Send an off-path PATH_RESPONSE. Prioritized over on-path data to ensure that path
855            // validation can occur while the link is saturated.
856            if space_id == SpaceId::Data && num_datagrams == 1 {
857                if let Some((token, remote)) = self.path_responses.pop_off_path(self.path.remote) {
858                    // `unwrap` guaranteed to succeed because `builder_storage` was populated just
859                    // above.
860                    let mut builder = builder_storage.take().unwrap();
861                    trace!("PATH_RESPONSE {:08x} (off-path)", token);
862                    buf.write(frame::FrameType::PATH_RESPONSE);
863                    buf.write(token);
864                    self.stats.frame_tx.path_response += 1;
865                    builder.pad_to(MIN_INITIAL_SIZE);
866                    builder.finish_and_track(
867                        now,
868                        self,
869                        Some(SentFrames {
870                            non_retransmits: true,
871                            ..SentFrames::default()
872                        }),
873                        buf,
874                    );
875                    self.stats.udp_tx.on_sent(1, buf.len());
876                    return Some(Transmit {
877                        destination: remote,
878                        size: buf.len(),
879                        ecn: None,
880                        segment_size: None,
881                        src_ip: self.local_ip,
882                    });
883                }
884            }
885
886            let sent =
887                self.populate_packet(now, space_id, buf, builder.max_size, builder.exact_number);
888
889            // ACK-only packets should only be sent when explicitly allowed. If we write them due to
890            // any other reason, there is a bug which leads to one component announcing write
891            // readiness while not writing any data. This degrades performance. The condition is
892            // only checked if the full MTU is available and when potentially large fixed-size
893            // frames aren't queued, so that lack of space in the datagram isn't the reason for just
894            // writing ACKs.
895            debug_assert!(
896                !(sent.is_ack_only(&self.streams)
897                    && !can_send.acks
898                    && can_send.other
899                    && (buf_capacity - builder.datagram_start) == self.path.current_mtu() as usize
900                    && self.datagrams.outgoing.is_empty()),
901                "SendableFrames was {can_send:?}, but only ACKs have been written"
902            );
903            pad_datagram |= sent.requires_padding;
904
905            if sent.largest_acked.is_some() {
906                self.spaces[space_id].pending_acks.acks_sent();
907                self.timers.stop(Timer::MaxAckDelay);
908                self.next_bundled_ack_time = Some(now + self.next_bundled_ack_delay());
909            }
910
911            // Keep information about the packet around until it gets finalized
912            sent_frames = Some(sent);
913
914            // Don't increment space_idx.
915            // We stay in the current space and check if there is more data to send.
916        }
917
918        // Finish the last packet
919        if let Some(mut builder) = builder_storage {
920            if pad_datagram {
921                builder.pad_to(min_mtu);
922            }
923
924            // If this datagram is a loss probe and `segment_size` is larger than `min_mtu`,
925            // then padding it to `segment_size` would risk failure to recover from a reduction in
926            // path MTU.
927            // Loss probes are the only packets for which we might grow `buf_capacity`
928            // by less than `segment_size`.
929            if pad_datagram_to_mtu && buf_capacity >= datagram_start + segment_size {
930                builder.pad_to(segment_size as u16);
931            }
932
933            let last_packet_number = builder.exact_number;
934            builder.finish_and_track(now, self, sent_frames, buf);
935            self.path
936                .congestion
937                .on_sent(now, buf.len() as u64, last_packet_number);
938
939            self.config.qlog_sink.emit_recovery_metrics(
940                self.pto_count,
941                &mut self.path,
942                now,
943                self.orig_rem_cid,
944            );
945        }
946
947        self.app_limited = buf.is_empty() && !congestion_blocked;
948
949        // Send MTU probe if necessary
950        if buf.is_empty() && self.state.is_established() {
951            let space_id = SpaceId::Data;
952            let probe_size = self
953                .path
954                .mtud
955                .poll_transmit(now, self.packet_number_filter.peek(&self.spaces[space_id]))?;
956
957            let buf_capacity = probe_size as usize;
958            buf.reserve(buf_capacity);
959
960            let mut builder = PacketBuilder::new(
961                now,
962                space_id,
963                self.rem_cids.active(),
964                buf,
965                buf_capacity,
966                0,
967                true,
968                self,
969            )?;
970
971            // We implement MTU probes as ping packets padded up to the probe size
972            buf.write(frame::FrameType::PING);
973            self.stats.frame_tx.ping += 1;
974
975            // If supported by the peer, we want no delays to the probe's ACK
976            if self.peer_supports_ack_frequency() {
977                buf.write(frame::FrameType::IMMEDIATE_ACK);
978                self.stats.frame_tx.immediate_ack += 1;
979            }
980
981            builder.pad_to(probe_size);
982            let sent_frames = SentFrames {
983                non_retransmits: true,
984                ..Default::default()
985            };
986            builder.finish_and_track(now, self, Some(sent_frames), buf);
987
988            self.stats.path.sent_plpmtud_probes += 1;
989            num_datagrams = 1;
990
991            trace!(?probe_size, "writing MTUD probe");
992        }
993
994        if buf.is_empty() {
995            return None;
996        }
997
998        trace!("sending {} bytes in {} datagrams", buf.len(), num_datagrams);
999        self.path.total_sent = self.path.total_sent.saturating_add(buf.len() as u64);
1000
1001        self.stats.udp_tx.on_sent(num_datagrams as u64, buf.len());
1002
1003        Some(Transmit {
1004            destination: self.path.remote,
1005            size: buf.len(),
1006            ecn: if self.path.sending_ecn {
1007                Some(EcnCodepoint::Ect0)
1008            } else {
1009                None
1010            },
1011            segment_size: match num_datagrams {
1012                1 => None,
1013                _ => Some(segment_size),
1014            },
1015            src_ip: self.local_ip,
1016        })
1017    }
1018
1019    /// Send PATH_CHALLENGE for a previous path if necessary
1020    fn send_path_challenge(&mut self, now: Instant, buf: &mut Vec<u8>) -> Option<Transmit> {
1021        let (prev_cid, prev_path) = self.prev_path.as_mut()?;
1022        if !prev_path.challenge_pending {
1023            return None;
1024        }
1025        prev_path.challenge_pending = false;
1026        let token = prev_path
1027            .challenge
1028            .expect("previous path challenge pending without token");
1029        let destination = prev_path.remote;
1030        debug_assert_eq!(
1031            self.highest_space,
1032            SpaceId::Data,
1033            "PATH_CHALLENGE queued without 1-RTT keys"
1034        );
1035        buf.reserve(MIN_INITIAL_SIZE as usize);
1036
1037        let buf_capacity = buf.capacity();
1038
1039        // Use the previous CID to avoid linking the new path with the previous path. We
1040        // don't bother accounting for possible retirement of that prev_cid because this is
1041        // sent once, immediately after migration, when the CID is known to be valid. Even
1042        // if a post-migration packet caused the CID to be retired, it's fair to pretend
1043        // this is sent first.
1044        let mut builder = PacketBuilder::new(
1045            now,
1046            SpaceId::Data,
1047            *prev_cid,
1048            buf,
1049            buf_capacity,
1050            0,
1051            false,
1052            self,
1053        )?;
1054        trace!("validating previous path with PATH_CHALLENGE {:08x}", token);
1055        buf.write(frame::FrameType::PATH_CHALLENGE);
1056        buf.write(token);
1057        self.stats.frame_tx.path_challenge += 1;
1058
1059        // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
1060        // to at least the smallest allowed maximum datagram size of 1200 bytes,
1061        // unless the anti-amplification limit for the path does not permit
1062        // sending a datagram of this size
1063        builder.pad_to(MIN_INITIAL_SIZE);
1064
1065        builder.finish(self, now, buf);
1066        self.stats.udp_tx.on_sent(1, buf.len());
1067
1068        Some(Transmit {
1069            destination,
1070            size: buf.len(),
1071            ecn: None,
1072            segment_size: None,
1073            src_ip: self.local_ip,
1074        })
1075    }
1076
1077    /// Indicate what types of frames are ready to send for the given space
1078    fn space_can_send(&self, space_id: SpaceId, frame_space_1rtt: usize) -> SendableFrames {
1079        if self.spaces[space_id].crypto.is_none()
1080            && (space_id != SpaceId::Data
1081                || self.zero_rtt_crypto.is_none()
1082                || self.side.is_server())
1083        {
1084            // No keys available for this space
1085            return SendableFrames::empty();
1086        }
1087        let mut can_send = self.spaces[space_id].can_send(&self.streams);
1088        if space_id == SpaceId::Data {
1089            can_send.other |= self.can_send_1rtt(frame_space_1rtt);
1090        }
1091        can_send
1092    }
1093
1094    /// The delay to wait after sending an ACK before bundling the next one.
1095    ///
1096    /// This delay prevents waste of peer's resources with processing bundled
1097    /// ACKs unnecessarily frequently.
1098    ///
1099    /// If we receive an ack-eliciting packet while this delay is still pending,
1100    /// `next_bundled_ack_time` is reset to `now`, which means this delay will be ignored.
1101    /// So this delay only matters when we keep sending but stop receiving ack-eliciting
1102    /// packets for a while.
1103    ///
1104    /// This should be at least `RTT + peer's max_ack_delay`: since a bundled ACK frame rides
1105    /// along with an ack-eliciting frame, the packet carrying it is itself ack-eliciting.
1106    /// We should give the peer enough time to acknowledge it.
1107    /// Otherwise, we risk bundling another ACK before the peer has even had a chance
1108    /// to acknowledge the previous one, which is a waste of remote peer's resources.
1109    fn next_bundled_ack_delay(&self) -> Duration {
1110        self.path.rtt.get() + self.ack_frequency.peer_max_ack_delay + TIMER_GRANULARITY
1111    }
1112
1113    /// Process `ConnectionEvent`s generated by the associated `Endpoint`
1114    ///
1115    /// Will execute protocol logic upon receipt of a connection event, in turn preparing signals
1116    /// (including application `Event`s, `EndpointEvent`s and outgoing datagrams) that should be
1117    /// extracted through the relevant methods.
1118    pub fn handle_event(&mut self, event: ConnectionEvent) {
1119        use ConnectionEventInner::*;
1120        match event.0 {
1121            Datagram(DatagramConnectionEvent {
1122                now,
1123                remote,
1124                ecn,
1125                first_decode,
1126                remaining,
1127            }) => {
1128                // If this packet could initiate a migration and we're a client or a server that
1129                // forbids migration, drop the datagram. This could be relaxed to heuristically
1130                // permit NAT-rebinding-like migration.
1131                if remote != self.path.remote && !self.side.remote_may_migrate() {
1132                    trace!("discarding packet from unrecognized peer {}", remote);
1133                    return;
1134                }
1135
1136                let was_anti_amplification_blocked = self.path.anti_amplification_blocked(1);
1137
1138                self.stats.udp_rx.datagrams += 1;
1139                self.stats.udp_rx.bytes += first_decode.len() as u64;
1140                let data_len = first_decode.len();
1141
1142                self.handle_decode(now, remote, ecn, first_decode);
1143                // The current `path` might have changed inside `handle_decode`,
1144                // since the packet could have triggered a migration. Make sure
1145                // the data received is accounted for the most recent path by accessing
1146                // `path` after `handle_decode`.
1147                self.path.total_recvd = self.path.total_recvd.saturating_add(data_len as u64);
1148
1149                if let Some(data) = remaining {
1150                    self.stats.udp_rx.bytes += data.len() as u64;
1151                    self.handle_coalesced(now, remote, ecn, data);
1152                }
1153
1154                self.config.qlog_sink.emit_recovery_metrics(
1155                    self.pto_count,
1156                    &mut self.path,
1157                    now,
1158                    self.orig_rem_cid,
1159                );
1160
1161                if was_anti_amplification_blocked {
1162                    // A prior attempt to set the loss detection timer may have failed due to
1163                    // anti-amplification, so ensure it's set now. Prevents a handshake deadlock if
1164                    // the server's first flight is lost.
1165                    self.set_loss_detection_timer(now);
1166                }
1167            }
1168            NewIdentifiers(ids, now) => {
1169                self.local_cid_state.new_cids(&ids, now);
1170                ids.into_iter().rev().for_each(|frame| {
1171                    self.spaces[SpaceId::Data].pending.new_cids.push(frame);
1172                });
1173                // Update Timer::PushNewCid
1174                if self.timers.get(Timer::PushNewCid).is_none_or(|x| x <= now) {
1175                    self.reset_cid_retirement();
1176                }
1177            }
1178        }
1179    }
1180
1181    /// Process timer expirations
1182    ///
1183    /// Executes protocol logic, potentially preparing signals (including application `Event`s,
1184    /// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant
1185    /// methods.
1186    ///
1187    /// It is most efficient to call this immediately after the system clock reaches the latest
1188    /// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply
1189    /// no-op and therefore are safe.
1190    pub fn handle_timeout(&mut self, now: Instant) {
1191        for &timer in &Timer::VALUES {
1192            if !self.timers.is_expired(timer, now) {
1193                continue;
1194            }
1195            self.timers.stop(timer);
1196            trace!(timer = ?timer, "timeout");
1197            match timer {
1198                Timer::Close => {
1199                    self.state = State::Drained;
1200                    self.endpoint_events.push_back(EndpointEventInner::Drained);
1201                }
1202                Timer::Idle => {
1203                    self.kill(ConnectionError::TimedOut);
1204                }
1205                Timer::KeepAlive => {
1206                    trace!("sending keep-alive");
1207                    self.ping();
1208                }
1209                Timer::LossDetection => {
1210                    self.on_loss_detection_timeout(now);
1211
1212                    self.config.qlog_sink.emit_recovery_metrics(
1213                        self.pto_count,
1214                        &mut self.path,
1215                        now,
1216                        self.orig_rem_cid,
1217                    );
1218                }
1219                Timer::KeyDiscard => {
1220                    self.zero_rtt_crypto = None;
1221                    self.prev_crypto = None;
1222                }
1223                Timer::PathValidation => {
1224                    debug!("path validation failed");
1225                    if let Some((_, prev)) = self.prev_path.take() {
1226                        self.path = prev;
1227                    }
1228                    self.path.challenge = None;
1229                    self.path.challenge_pending = false;
1230                }
1231                Timer::Pacing => trace!("pacing timer expired"),
1232                Timer::PushNewCid => {
1233                    // Update `retire_prior_to` field in NEW_CONNECTION_ID frame
1234                    let num_new_cid = self.local_cid_state.on_cid_timeout().into();
1235                    if !self.state.is_closed() {
1236                        trace!(
1237                            "push a new cid to peer RETIRE_PRIOR_TO field {}",
1238                            self.local_cid_state.retire_prior_to()
1239                        );
1240                        self.endpoint_events
1241                            .push_back(EndpointEventInner::NeedIdentifiers(now, num_new_cid));
1242                    }
1243                }
1244                Timer::MaxAckDelay => {
1245                    trace!("max ack delay reached");
1246                    // This timer is only armed in the Data space
1247                    self.spaces[SpaceId::Data]
1248                        .pending_acks
1249                        .on_max_ack_delay_timeout()
1250                }
1251            }
1252        }
1253    }
1254
1255    /// Close a connection immediately
1256    ///
1257    /// This does not ensure delivery of outstanding data. It is the application's responsibility to
1258    /// call this only when all important communications have been completed, e.g. by calling
1259    /// [`SendStream::finish`] on outstanding streams and waiting for the corresponding
1260    /// [`StreamEvent::Finished`] event.
1261    ///
1262    /// If [`Streams::send_streams`] returns 0, all outstanding stream data has been
1263    /// delivered. There may still be data from the peer that has not been received.
1264    ///
1265    /// [`StreamEvent::Finished`]: crate::StreamEvent::Finished
1266    pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) {
1267        self.close_inner(
1268            now,
1269            Close::Application(frame::ApplicationClose { error_code, reason }),
1270        )
1271    }
1272
1273    fn close_inner(&mut self, now: Instant, reason: Close) {
1274        let was_closed = self.state.is_closed();
1275        if !was_closed {
1276            self.close_common();
1277            self.set_close_timer(now);
1278            self.close = true;
1279            self.state = State::Closed(state::Closed { reason });
1280        }
1281    }
1282
1283    /// Control datagrams
1284    pub fn datagrams(&mut self) -> Datagrams<'_> {
1285        Datagrams { conn: self }
1286    }
1287
1288    /// Returns connection statistics
1289    pub fn stats(&self) -> ConnectionStats {
1290        let mut stats = self.stats;
1291        stats.path.rtt = self.path.rtt.get();
1292        stats.path.min_rtt = self.path.rtt.min();
1293        stats.path.cwnd = self.path.congestion.window();
1294        stats.path.current_mtu = self.path.mtud.current_mtu();
1295
1296        stats
1297    }
1298
1299    /// Ping the remote endpoint
1300    ///
1301    /// Causes an ACK-eliciting packet to be transmitted.
1302    pub fn ping(&mut self) {
1303        self.spaces[self.highest_space].ping_pending = true;
1304    }
1305
1306    /// Update traffic keys spontaneously
1307    ///
1308    /// This can be useful for testing key updates, as they otherwise only happen infrequently.
1309    pub fn force_key_update(&mut self) {
1310        if !self.state.is_established() {
1311            debug!("ignoring forced key update in illegal state");
1312            return;
1313        }
1314        if self.prev_crypto.is_some() {
1315            // We already just updated, or are currently updating, the keys. Concurrent key updates
1316            // are illegal.
1317            debug!("ignoring redundant forced key update");
1318            return;
1319        }
1320        self.update_keys(None, false);
1321    }
1322
1323    // Compatibility wrapper for quinn < 0.11.7. Remove for 0.12.
1324    #[doc(hidden)]
1325    #[deprecated]
1326    pub fn initiate_key_update(&mut self) {
1327        self.force_key_update();
1328    }
1329
1330    /// Get a session reference
1331    pub fn crypto_session(&self) -> &dyn crypto::Session {
1332        &*self.crypto
1333    }
1334
1335    /// Whether the connection is in the process of being established
1336    ///
1337    /// If this returns `false`, the connection may be either established or closed, signaled by the
1338    /// emission of a `Connected` or `ConnectionLost` message respectively.
1339    pub fn is_handshaking(&self) -> bool {
1340        self.state.is_handshake()
1341    }
1342
1343    /// Whether the connection is closed
1344    ///
1345    /// Closed connections cannot transport any further data. A connection becomes closed when
1346    /// either peer application intentionally closes it, or when either transport layer detects an
1347    /// error such as a time-out or certificate validation failure.
1348    ///
1349    /// A `ConnectionLost` event is emitted with details when the connection becomes closed.
1350    pub fn is_closed(&self) -> bool {
1351        self.state.is_closed()
1352    }
1353
1354    /// Whether there is no longer any need to keep the connection around
1355    ///
1356    /// Closed connections become drained after a brief timeout to absorb any remaining in-flight
1357    /// packets from the peer. All drained connections have been closed.
1358    pub fn is_drained(&self) -> bool {
1359        self.state.is_drained()
1360    }
1361
1362    /// For clients, if the peer accepted the 0-RTT data packets
1363    ///
1364    /// The value is meaningless until after the handshake completes.
1365    pub fn accepted_0rtt(&self) -> bool {
1366        self.accepted_0rtt
1367    }
1368
1369    /// Whether 0-RTT is/was possible during the handshake
1370    pub fn has_0rtt(&self) -> bool {
1371        self.zero_rtt_enabled
1372    }
1373
1374    /// Whether there are any pending retransmits
1375    pub fn has_pending_retransmits(&self) -> bool {
1376        !self.spaces[SpaceId::Data].pending.is_empty(&self.streams)
1377    }
1378
1379    /// Look up whether we're the client or server of this Connection
1380    pub fn side(&self) -> Side {
1381        self.side.side()
1382    }
1383
1384    /// The latest socket address for this connection's peer
1385    pub fn remote_address(&self) -> SocketAddr {
1386        self.path.remote
1387    }
1388
1389    /// The local IP address which was used when the peer established
1390    /// the connection
1391    ///
1392    /// This can be different from the address the endpoint is bound to, in case
1393    /// the endpoint is bound to a wildcard address like `0.0.0.0` or `::`.
1394    ///
1395    /// This will return `None` for clients, or when no `local_ip` was passed to
1396    /// [`Endpoint::handle()`](crate::Endpoint::handle) for the datagrams establishing this
1397    /// connection.
1398    pub fn local_ip(&self) -> Option<IpAddr> {
1399        self.local_ip
1400    }
1401
1402    /// Current best estimate of this connection's latency (round-trip-time)
1403    pub fn rtt(&self) -> Duration {
1404        self.path.rtt.get()
1405    }
1406
1407    /// Minimum RTT seen on this path, ignoring ack delay
1408    pub fn min_rtt(&self) -> Duration {
1409        self.path.rtt.min()
1410    }
1411
1412    /// Current state of this connection's congestion controller, for debugging purposes
1413    pub fn congestion_state(&self) -> &dyn Controller {
1414        self.path.congestion.as_ref()
1415    }
1416
1417    /// Resets path-specific settings.
1418    ///
1419    /// This will force-reset several subsystems related to a specific network path.
1420    /// Currently this is the congestion controller, round-trip estimator, pacer, and MTU
1421    /// discovery.
1422    ///
1423    /// This is useful when it is known the underlying network path has changed and the old
1424    /// state of these subsystems is no longer valid or optimal. In this case it might be
1425    /// faster or reduce loss to settle on optimal values by restarting from the initial
1426    /// configuration in the [`TransportConfig`].
1427    pub fn path_changed(&mut self, now: Instant) {
1428        self.path.reset(now, &self.config);
1429        self.datagrams().drop_oversized();
1430    }
1431
1432    /// Modify the number of remotely initiated streams that may be concurrently open
1433    ///
1434    /// No streams may be opened by the peer unless fewer than `count` are already open. Large
1435    /// `count`s increase both minimum and worst-case memory consumption.
1436    pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) {
1437        self.streams.set_max_concurrent(dir, count);
1438        // If the limit was reduced, then a flow control update previously deemed insignificant may
1439        // now be significant.
1440        let pending = &mut self.spaces[SpaceId::Data].pending;
1441        self.streams.queue_max_stream_id(pending);
1442    }
1443
1444    /// Current number of remotely initiated streams that may be concurrently open
1445    ///
1446    /// If the target for this limit is reduced using [`set_max_concurrent_streams`](Self::set_max_concurrent_streams),
1447    /// it will not change immediately, even if fewer streams are open. Instead, it will
1448    /// decrement by one for each time a remotely initiated stream of matching directionality is closed.
1449    pub fn max_concurrent_streams(&self, dir: Dir) -> u64 {
1450        self.streams.max_concurrent(dir)
1451    }
1452
1453    /// See [`TransportConfig::send_window()`]
1454    pub fn set_send_window(&mut self, send_window: u64) {
1455        self.streams.set_send_window(send_window);
1456    }
1457
1458    /// See [`TransportConfig::receive_window()`]
1459    pub fn set_receive_window(&mut self, receive_window: VarInt) {
1460        if self.streams.set_receive_window(receive_window) {
1461            self.spaces[SpaceId::Data].pending.max_data = true;
1462        }
1463    }
1464
1465    fn on_ack_received(
1466        &mut self,
1467        now: Instant,
1468        space: SpaceId,
1469        ack: frame::Ack,
1470    ) -> Result<(), TransportError> {
1471        if ack.largest >= self.spaces[space].next_packet_number {
1472            return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked"));
1473        }
1474        let new_largest = {
1475            let space = &mut self.spaces[space];
1476            if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) {
1477                space.largest_acked_packet = Some(ack.largest);
1478                if let Some(info) = space.sent_packets.get(&ack.largest) {
1479                    // This should always succeed, but a misbehaving peer might ACK a packet we
1480                    // haven't sent. At worst, that will result in us spuriously reducing the
1481                    // congestion window.
1482                    space.largest_acked_packet_sent = info.time_sent;
1483                }
1484                true
1485            } else {
1486                false
1487            }
1488        };
1489
1490        // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks.
1491        let mut newly_acked = ArrayRangeSet::new();
1492        for range in ack.iter() {
1493            self.packet_number_filter.check_ack(space, range.clone())?;
1494            for (&pn, _) in self.spaces[space].sent_packets.range(range) {
1495                newly_acked.insert_one(pn);
1496            }
1497        }
1498
1499        if newly_acked.is_empty() {
1500            return Ok(());
1501        }
1502
1503        let mut ack_eliciting_acked = false;
1504        for packet in newly_acked.elts() {
1505            if let Some(info) = self.spaces[space].take(packet) {
1506                if let Some(acked) = info.largest_acked {
1507                    // Assume ACKs for all packets below the largest acknowledged in `packet` have
1508                    // been received. This can cause the peer to spuriously retransmit if some of
1509                    // our earlier ACKs were lost, but allows for simpler state tracking. See
1510                    // discussion at
1511                    // https://www.rfc-editor.org/rfc/rfc9000.html#name-limiting-ranges-by-tracking
1512                    self.spaces[space].pending_acks.subtract_below(acked);
1513                }
1514                ack_eliciting_acked |= info.ack_eliciting;
1515
1516                // Notify MTU discovery that a packet was acked, because it might be an MTU probe
1517                let mtu_updated = self.path.mtud.on_acked(space, packet, info.size);
1518                if mtu_updated {
1519                    self.path
1520                        .congestion
1521                        .on_mtu_update(self.path.mtud.current_mtu());
1522                }
1523
1524                // Notify ack frequency that a packet was acked, because it might contain an ACK_FREQUENCY frame
1525                self.ack_frequency.on_acked(packet);
1526
1527                self.on_packet_acked(now, info);
1528            }
1529        }
1530
1531        self.path.congestion.on_end_acks(
1532            now,
1533            self.path.in_flight.bytes,
1534            self.app_limited,
1535            self.spaces[space].largest_acked_packet,
1536        );
1537
1538        if new_largest && ack_eliciting_acked {
1539            let ack_delay = if space != SpaceId::Data {
1540                Duration::from_micros(0)
1541            } else {
1542                cmp::min(
1543                    self.ack_frequency.peer_max_ack_delay,
1544                    Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0),
1545                )
1546            };
1547            let rtt = now.saturating_duration_since(self.spaces[space].largest_acked_packet_sent);
1548            self.path.rtt.update(ack_delay, rtt);
1549            if self.path.first_packet_after_rtt_sample.is_none() {
1550                self.path.first_packet_after_rtt_sample =
1551                    Some((space, self.spaces[space].next_packet_number));
1552            }
1553        }
1554
1555        // Must be called before crypto/pto_count are clobbered
1556        self.detect_lost_packets(now, space, true);
1557
1558        if self.peer_completed_address_validation() {
1559            self.pto_count = 0;
1560        }
1561
1562        // Explicit congestion notification
1563        if self.path.sending_ecn {
1564            if let Some(ecn) = ack.ecn {
1565                // We only examine ECN counters from ACKs that we are certain we received in transmit
1566                // order, allowing us to compute an increase in ECN counts to compare against the number
1567                // of newly acked packets that remains well-defined in the presence of arbitrary packet
1568                // reordering.
1569                if new_largest {
1570                    let sent = self.spaces[space].largest_acked_packet_sent;
1571                    self.process_ecn(now, space, newly_acked.len() as u64, ecn, sent);
1572                }
1573            } else {
1574                // We always start out sending ECN, so any ack that doesn't acknowledge it disables it.
1575                debug!("ECN not acknowledged by peer");
1576                self.path.sending_ecn = false;
1577            }
1578        }
1579
1580        self.set_loss_detection_timer(now);
1581        Ok(())
1582    }
1583
1584    /// Process a new ECN block from an in-order ACK
1585    fn process_ecn(
1586        &mut self,
1587        now: Instant,
1588        space: SpaceId,
1589        newly_acked: u64,
1590        ecn: frame::EcnCounts,
1591        largest_sent_time: Instant,
1592    ) {
1593        match self.spaces[space].detect_ecn(newly_acked, ecn) {
1594            Err(e) => {
1595                debug!("halting ECN due to verification failure: {}", e);
1596                self.path.sending_ecn = false;
1597                // Wipe out the existing value because it might be garbage and could interfere with
1598                // future attempts to use ECN on new paths.
1599                self.spaces[space].ecn_feedback = frame::EcnCounts::ZERO;
1600            }
1601            Ok(false) => {}
1602            Ok(true) => {
1603                self.stats.path.congestion_events += 1;
1604                self.path
1605                    .congestion
1606                    .on_congestion_event(now, largest_sent_time, false, 0);
1607            }
1608        }
1609    }
1610
1611    // Not timing-aware, so it's safe to call this for inferred acks, such as arise from
1612    // high-latency handshakes
1613    fn on_packet_acked(&mut self, now: Instant, info: SentPacket) {
1614        self.remove_in_flight(&info);
1615        if info.ack_eliciting && self.path.challenge.is_none() {
1616            // Only pass ACKs to the congestion controller if we are not validating the current
1617            // path, so as to ignore any ACKs from older paths still coming in.
1618            self.path.congestion.on_ack(
1619                now,
1620                info.time_sent,
1621                info.size.into(),
1622                self.app_limited,
1623                &self.path.rtt,
1624            );
1625        }
1626
1627        // Update state for confirmed delivery of frames
1628        if let Some(retransmits) = info.retransmits.get() {
1629            for (id, _) in retransmits.reset_stream.iter() {
1630                self.streams.reset_acked(*id);
1631            }
1632        }
1633
1634        for frame in info.stream_frames {
1635            self.streams.received_ack_of(frame);
1636        }
1637    }
1638
1639    fn set_key_discard_timer(&mut self, now: Instant, space: SpaceId) {
1640        let start = if self.zero_rtt_crypto.is_some() {
1641            now
1642        } else {
1643            self.prev_crypto
1644                .as_ref()
1645                .expect("no previous keys")
1646                .end_packet
1647                .as_ref()
1648                .expect("update not acknowledged yet")
1649                .1
1650        };
1651        self.timers
1652            .set(Timer::KeyDiscard, start + self.pto(space) * 3);
1653    }
1654
1655    fn on_loss_detection_timeout(&mut self, now: Instant) {
1656        if let Some((_, pn_space)) = self.loss_time_and_space() {
1657            // Time threshold loss Detection
1658            self.detect_lost_packets(now, pn_space, false);
1659            self.set_loss_detection_timer(now);
1660            return;
1661        }
1662
1663        let (_, space) = match self.pto_time_and_space(now) {
1664            Some(x) => x,
1665            None => {
1666                error!("PTO expired while unset");
1667                return;
1668            }
1669        };
1670        trace!(
1671            in_flight = self.path.in_flight.bytes,
1672            count = self.pto_count,
1673            ?space,
1674            "PTO fired"
1675        );
1676
1677        let count = match self.path.in_flight.ack_eliciting {
1678            // A PTO when we're not expecting any ACKs must be due to handshake anti-amplification
1679            // deadlock preventions
1680            0 => {
1681                debug_assert!(!self.peer_completed_address_validation());
1682                1
1683            }
1684            // Conventional loss probe
1685            _ => 2,
1686        };
1687        self.spaces[space].loss_probes = self.spaces[space].loss_probes.saturating_add(count);
1688        self.pto_count = self.pto_count.saturating_add(1);
1689        self.set_loss_detection_timer(now);
1690    }
1691
1692    fn detect_lost_packets(&mut self, now: Instant, pn_space: SpaceId, due_to_ack: bool) {
1693        let mut lost_packets = Vec::<u64>::new();
1694        let mut lost_mtu_probe = None;
1695        let in_flight_mtu_probe = self.path.mtud.in_flight_mtu_probe();
1696        let rtt = self.path.rtt.conservative();
1697        let loss_delay = cmp::max(rtt.mul_f32(self.config.time_threshold), TIMER_GRANULARITY);
1698
1699        let largest_acked_packet = self.spaces[pn_space].largest_acked_packet.unwrap();
1700        let packet_threshold = self.config.packet_threshold as u64;
1701        let mut size_of_lost_packets = 0u64;
1702
1703        // InPersistentCongestion: Determine if all packets in the time period before the newest
1704        // lost packet, including the edges, are marked lost. PTO computation must always
1705        // include max ACK delay, i.e. operate as if in Data space (see RFC9001 §7.6.1).
1706        let congestion_period =
1707            self.pto(SpaceId::Data) * self.config.persistent_congestion_threshold;
1708        let mut persistent_congestion_start: Option<Instant> = None;
1709        let mut prev_packet = None;
1710        let mut in_persistent_congestion = false;
1711
1712        let space = &mut self.spaces[pn_space];
1713        space.loss_time = None;
1714
1715        for (&packet, info) in space.sent_packets.range(0..largest_acked_packet) {
1716            if prev_packet != Some(packet.wrapping_sub(1)) {
1717                // An intervening packet was acknowledged
1718                persistent_congestion_start = None;
1719            }
1720
1721            // Packets sent before now - loss_delay are deemed lost.
1722            // However, we avoid this subtraction as it can panic and there's no
1723            // saturating equivalent of this substraction operation with a Duration.
1724            let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay;
1725            if packet_too_old || largest_acked_packet >= packet + packet_threshold {
1726                if Some(packet) == in_flight_mtu_probe {
1727                    // Lost MTU probes are not included in `lost_packets`, because they should not
1728                    // trigger a congestion control response
1729                    lost_mtu_probe = in_flight_mtu_probe;
1730                } else {
1731                    lost_packets.push(packet);
1732                    size_of_lost_packets += info.size as u64;
1733                    if info.ack_eliciting && due_to_ack {
1734                        match persistent_congestion_start {
1735                            // Two ACK-eliciting packets lost more than congestion_period apart, with no
1736                            // ACKed packets in between
1737                            Some(start) if info.time_sent - start > congestion_period => {
1738                                in_persistent_congestion = true;
1739                            }
1740                            // Persistent congestion must start after the first RTT sample
1741                            None if self
1742                                .path
1743                                .first_packet_after_rtt_sample
1744                                .is_some_and(|x| x < (pn_space, packet)) =>
1745                            {
1746                                persistent_congestion_start = Some(info.time_sent);
1747                            }
1748                            _ => {}
1749                        }
1750                    }
1751                }
1752            } else {
1753                let next_loss_time = info.time_sent + loss_delay;
1754                space.loss_time = Some(
1755                    space
1756                        .loss_time
1757                        .map_or(next_loss_time, |x| cmp::min(x, next_loss_time)),
1758                );
1759                persistent_congestion_start = None;
1760            }
1761
1762            prev_packet = Some(packet);
1763        }
1764
1765        // OnPacketsLost
1766        if let Some(largest_lost) = lost_packets.last().cloned() {
1767            let old_bytes_in_flight = self.path.in_flight.bytes;
1768            let largest_lost_sent = self.spaces[pn_space].sent_packets[&largest_lost].time_sent;
1769            self.stats.path.lost_packets += lost_packets.len() as u64;
1770            self.stats.path.lost_bytes += size_of_lost_packets;
1771            trace!(
1772                "packets lost: {:?}, bytes lost: {}",
1773                lost_packets, size_of_lost_packets
1774            );
1775
1776            for &packet in &lost_packets {
1777                let info = self.spaces[pn_space].take(packet).unwrap(); // safe: lost_packets is populated just above
1778                self.config.qlog_sink.emit_packet_lost(
1779                    packet,
1780                    &info,
1781                    loss_delay,
1782                    pn_space,
1783                    now,
1784                    self.orig_rem_cid,
1785                );
1786                self.remove_in_flight(&info);
1787                for frame in info.stream_frames {
1788                    self.streams.retransmit(frame);
1789                }
1790                self.spaces[pn_space].pending |= info.retransmits;
1791                self.path.mtud.on_non_probe_lost(packet, info.size);
1792            }
1793
1794            if self.path.mtud.black_hole_detected(now) {
1795                self.stats.path.black_holes_detected += 1;
1796                self.path
1797                    .congestion
1798                    .on_mtu_update(self.path.mtud.current_mtu());
1799                self.datagrams().drop_oversized();
1800            }
1801
1802            // Don't apply congestion penalty for lost ack-only packets
1803            let lost_ack_eliciting = old_bytes_in_flight != self.path.in_flight.bytes;
1804
1805            if lost_ack_eliciting {
1806                self.stats.path.congestion_events += 1;
1807                self.path.congestion.on_congestion_event(
1808                    now,
1809                    largest_lost_sent,
1810                    in_persistent_congestion,
1811                    size_of_lost_packets,
1812                );
1813            }
1814        }
1815
1816        // Handle a lost MTU probe
1817        if let Some(packet) = lost_mtu_probe {
1818            let info = self.spaces[SpaceId::Data].take(packet).unwrap(); // safe: lost_mtu_probe is omitted from lost_packets, and therefore must not have been removed yet
1819            self.remove_in_flight(&info);
1820            self.path.mtud.on_probe_lost();
1821            self.stats.path.lost_plpmtud_probes += 1;
1822        }
1823    }
1824
1825    fn loss_time_and_space(&self) -> Option<(Instant, SpaceId)> {
1826        SpaceId::iter()
1827            .filter_map(|id| Some((self.spaces[id].loss_time?, id)))
1828            .min_by_key(|&(time, _)| time)
1829    }
1830
1831    fn pto_time_and_space(&self, now: Instant) -> Option<(Instant, SpaceId)> {
1832        let backoff = 2u32.pow(self.pto_count.min(MAX_BACKOFF_EXPONENT));
1833        let mut duration = self.path.rtt.pto_base() * backoff;
1834
1835        if self.path.in_flight.ack_eliciting == 0 {
1836            debug_assert!(!self.peer_completed_address_validation());
1837            let space = match self.highest_space {
1838                SpaceId::Handshake => SpaceId::Handshake,
1839                _ => SpaceId::Initial,
1840            };
1841            return Some((now + duration, space));
1842        }
1843
1844        let mut result = None;
1845        for space in SpaceId::iter() {
1846            if !self.spaces[space].has_in_flight() {
1847                continue;
1848            }
1849            if space == SpaceId::Data {
1850                // Skip ApplicationData until handshake completes.
1851                if self.is_handshaking() {
1852                    return result;
1853                }
1854                // Include max_ack_delay and backoff for ApplicationData.
1855                duration += self.ack_frequency.max_ack_delay_for_pto() * backoff;
1856            }
1857            let last_ack_eliciting = match self.spaces[space].time_of_last_ack_eliciting_packet {
1858                Some(time) => time,
1859                None => continue,
1860            };
1861            let pto = last_ack_eliciting + duration;
1862            if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) {
1863                result = Some((pto, space));
1864            }
1865        }
1866        result
1867    }
1868
1869    fn peer_completed_address_validation(&self) -> bool {
1870        if self.side.is_server() || self.state.is_closed() {
1871            return true;
1872        }
1873        // The server is guaranteed to have validated our address if any of our handshake or 1-RTT
1874        // packets are acknowledged or we've seen HANDSHAKE_DONE and discarded handshake keys.
1875        self.spaces[SpaceId::Handshake]
1876            .largest_acked_packet
1877            .is_some()
1878            || self.spaces[SpaceId::Data].largest_acked_packet.is_some()
1879            || (self.spaces[SpaceId::Data].crypto.is_some()
1880                && self.spaces[SpaceId::Handshake].crypto.is_none())
1881    }
1882
1883    fn set_loss_detection_timer(&mut self, now: Instant) {
1884        if self.state.is_closed() {
1885            // No loss detection takes place on closed connections, and `close_common` already
1886            // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a
1887            // reordered packet being handled by state-insensitive code.
1888            return;
1889        }
1890
1891        if let Some((loss_time, _)) = self.loss_time_and_space() {
1892            // Time threshold loss detection.
1893            self.timers.set(Timer::LossDetection, loss_time);
1894            return;
1895        }
1896
1897        if self.path.anti_amplification_blocked(1) {
1898            // We wouldn't be able to send anything, so don't bother.
1899            self.timers.stop(Timer::LossDetection);
1900            return;
1901        }
1902
1903        if self.path.in_flight.ack_eliciting == 0 && self.peer_completed_address_validation() {
1904            // There is nothing to detect lost, so no timer is set. However, the client needs to arm
1905            // the timer if the server might be blocked by the anti-amplification limit.
1906            self.timers.stop(Timer::LossDetection);
1907            return;
1908        }
1909
1910        // Determine which PN space to arm PTO for.
1911        // Calculate PTO duration
1912        if let Some((timeout, _)) = self.pto_time_and_space(now) {
1913            self.timers.set(Timer::LossDetection, timeout);
1914        } else {
1915            self.timers.stop(Timer::LossDetection);
1916        }
1917    }
1918
1919    /// Probe Timeout
1920    fn pto(&self, space: SpaceId) -> Duration {
1921        let max_ack_delay = match space {
1922            SpaceId::Initial | SpaceId::Handshake => Duration::ZERO,
1923            SpaceId::Data => self.ack_frequency.max_ack_delay_for_pto(),
1924        };
1925        self.path.rtt.pto_base() + max_ack_delay
1926    }
1927
1928    fn on_packet_authenticated(
1929        &mut self,
1930        now: Instant,
1931        space_id: SpaceId,
1932        ecn: Option<EcnCodepoint>,
1933        packet: Option<u64>,
1934        spin: bool,
1935        is_1rtt: bool,
1936    ) {
1937        self.total_authed_packets += 1;
1938        self.reset_keep_alive(now);
1939        self.reset_idle_timeout(now, space_id);
1940        self.permit_idle_reset = true;
1941        self.receiving_ecn |= ecn.is_some();
1942        if let Some(x) = ecn {
1943            let space = &mut self.spaces[space_id];
1944            space.ecn_counters += x;
1945
1946            if x.is_ce() {
1947                space.pending_acks.set_immediate_ack_required();
1948            }
1949        }
1950
1951        let packet = match packet {
1952            Some(x) => x,
1953            None => return,
1954        };
1955        if self.side.is_server() {
1956            if self.spaces[SpaceId::Initial].crypto.is_some() && space_id == SpaceId::Handshake {
1957                // A server stops sending and processing Initial packets when it receives its first Handshake packet.
1958                self.discard_space(now, SpaceId::Initial);
1959            }
1960            if self.zero_rtt_crypto.is_some() && is_1rtt {
1961                // Discard 0-RTT keys soon after receiving a 1-RTT packet
1962                self.set_key_discard_timer(now, space_id)
1963            }
1964        }
1965        let space = &mut self.spaces[space_id];
1966        space.pending_acks.insert_one(packet, now);
1967        if packet >= space.rx_packet {
1968            space.rx_packet = packet;
1969            // Update outgoing spin bit, inverting iff we're the client
1970            self.spin = self.side.is_client() ^ spin;
1971        }
1972
1973        self.config.qlog_sink.emit_packet_received(
1974            packet,
1975            space_id,
1976            !is_1rtt,
1977            now,
1978            self.orig_rem_cid,
1979        );
1980    }
1981
1982    fn reset_idle_timeout(&mut self, now: Instant, space: SpaceId) {
1983        let timeout = match self.idle_timeout {
1984            None => return,
1985            Some(dur) => dur,
1986        };
1987        if self.state.is_closed() {
1988            self.timers.stop(Timer::Idle);
1989            return;
1990        }
1991        let dt = cmp::max(timeout, 3 * self.pto(space));
1992        self.timers.set(Timer::Idle, now + dt);
1993    }
1994
1995    fn reset_keep_alive(&mut self, now: Instant) {
1996        let interval = match self.config.keep_alive_interval {
1997            Some(x) if self.state.is_established() => x,
1998            _ => return,
1999        };
2000        self.timers.set(Timer::KeepAlive, now + interval);
2001    }
2002
2003    fn reset_cid_retirement(&mut self) {
2004        if let Some(t) = self.local_cid_state.next_timeout() {
2005            self.timers.set(Timer::PushNewCid, t);
2006        }
2007    }
2008
2009    /// Handle the already-decrypted first packet from the client
2010    ///
2011    /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more
2012    /// efficient.
2013    pub(crate) fn handle_first_packet(
2014        &mut self,
2015        now: Instant,
2016        remote: SocketAddr,
2017        ecn: Option<EcnCodepoint>,
2018        packet_number: u64,
2019        packet: InitialPacket,
2020        remaining: Option<BytesMut>,
2021    ) -> Result<(), ConnectionError> {
2022        let span = trace_span!("first recv");
2023        let _guard = span.enter();
2024        debug_assert!(self.side.is_server());
2025        let len = packet.header_data.len() + packet.payload.len();
2026        self.path.total_recvd = len as u64;
2027
2028        match self.state {
2029            State::Handshake(ref mut state) => {
2030                state.expected_token = packet.header.token.clone();
2031            }
2032            _ => unreachable!("first packet must be delivered in Handshake state"),
2033        }
2034
2035        self.on_packet_authenticated(
2036            now,
2037            SpaceId::Initial,
2038            ecn,
2039            Some(packet_number),
2040            false,
2041            false,
2042        );
2043
2044        self.process_decrypted_packet(now, remote, Some(packet_number), packet.into())?;
2045        if let Some(data) = remaining {
2046            self.handle_coalesced(now, remote, ecn, data);
2047        }
2048
2049        self.config.qlog_sink.emit_recovery_metrics(
2050            self.pto_count,
2051            &mut self.path,
2052            now,
2053            self.orig_rem_cid,
2054        );
2055
2056        Ok(())
2057    }
2058
2059    fn init_0rtt(&mut self) {
2060        let (header, packet) = match self.crypto.early_crypto() {
2061            Some(x) => x,
2062            None => return,
2063        };
2064        if self.side.is_client() {
2065            match self.crypto.transport_parameters() {
2066                Ok(params) => {
2067                    let params = params
2068                        .expect("crypto layer didn't supply transport parameters with ticket");
2069                    // Certain values must not be cached
2070                    let params = TransportParameters {
2071                        initial_src_cid: None,
2072                        original_dst_cid: None,
2073                        preferred_address: None,
2074                        retry_src_cid: None,
2075                        stateless_reset_token: None,
2076                        min_ack_delay: None,
2077                        ack_delay_exponent: TransportParameters::default().ack_delay_exponent,
2078                        max_ack_delay: TransportParameters::default().max_ack_delay,
2079                        ..params
2080                    };
2081                    self.set_peer_params(params);
2082                }
2083                Err(e) => {
2084                    error!("session ticket has malformed transport parameters: {}", e);
2085                    return;
2086                }
2087            }
2088        }
2089        trace!("0-RTT enabled");
2090        self.zero_rtt_enabled = true;
2091        self.zero_rtt_crypto = Some(ZeroRttCrypto { header, packet });
2092    }
2093
2094    fn read_crypto(
2095        &mut self,
2096        space: SpaceId,
2097        crypto: &frame::Crypto,
2098        payload_len: usize,
2099    ) -> Result<(), TransportError> {
2100        let expected = if !self.state.is_handshake() {
2101            SpaceId::Data
2102        } else if self.highest_space == SpaceId::Initial {
2103            SpaceId::Initial
2104        } else {
2105            // On the server, self.highest_space can be Data after receiving the client's first
2106            // flight, but we expect Handshake CRYPTO until the handshake is complete.
2107            SpaceId::Handshake
2108        };
2109        // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT
2110        // packets are illegal, and we don't process 1-RTT packets until the handshake is
2111        // complete. Therefore, we will never see CRYPTO data from a later-than-expected space.
2112        debug_assert!(space <= expected, "received out-of-order CRYPTO data");
2113
2114        let end = crypto.offset + crypto.data.len() as u64;
2115        if space < expected && end > self.spaces[space].crypto_stream.bytes_read() {
2116            warn!(
2117                "received new {:?} CRYPTO data when expecting {:?}",
2118                space, expected
2119            );
2120            return Err(TransportError::PROTOCOL_VIOLATION(
2121                "new data at unexpected encryption level",
2122            ));
2123        }
2124
2125        let space = &mut self.spaces[space];
2126        let max = end.saturating_sub(space.crypto_stream.bytes_read());
2127        if max > self.config.crypto_buffer_size as u64 {
2128            return Err(TransportError::CRYPTO_BUFFER_EXCEEDED(""));
2129        }
2130
2131        space
2132            .crypto_stream
2133            .insert(crypto.offset, crypto.data.clone(), payload_len)
2134            .map_err(|_| TransportError::INTERNAL_ERROR("too many gaps in crypto stream buffer"))?;
2135
2136        while let Some(chunk) = space.crypto_stream.read(usize::MAX, true) {
2137            trace!("consumed {} CRYPTO bytes", chunk.bytes.len());
2138            if self.crypto.read_handshake(&chunk.bytes)? {
2139                self.events.push_back(Event::HandshakeDataReady);
2140            }
2141        }
2142
2143        Ok(())
2144    }
2145
2146    fn write_crypto(&mut self) {
2147        loop {
2148            let space = self.highest_space;
2149            let mut outgoing = Vec::new();
2150            if let Some(crypto) = self.crypto.write_handshake(&mut outgoing) {
2151                match space {
2152                    SpaceId::Initial => {
2153                        self.upgrade_crypto(SpaceId::Handshake, crypto);
2154                    }
2155                    SpaceId::Handshake => {
2156                        self.upgrade_crypto(SpaceId::Data, crypto);
2157                    }
2158                    _ => unreachable!("got updated secrets during 1-RTT"),
2159                }
2160            }
2161            if outgoing.is_empty() {
2162                if space == self.highest_space {
2163                    break;
2164                } else {
2165                    // Keys updated, check for more data to send
2166                    continue;
2167                }
2168            }
2169            let offset = self.spaces[space].crypto_offset;
2170            let outgoing = Bytes::from(outgoing);
2171            if let State::Handshake(ref mut state) = self.state {
2172                if space == SpaceId::Initial && offset == 0 && self.side.is_client() {
2173                    state.client_hello = Some(outgoing.clone());
2174                }
2175            }
2176            self.spaces[space].crypto_offset += outgoing.len() as u64;
2177            trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space);
2178            self.spaces[space].pending.crypto.push_back(frame::Crypto {
2179                offset,
2180                data: outgoing,
2181            });
2182        }
2183    }
2184
2185    /// Switch to stronger cryptography during handshake
2186    fn upgrade_crypto(&mut self, space: SpaceId, crypto: Keys) {
2187        debug_assert!(
2188            self.spaces[space].crypto.is_none(),
2189            "already reached packet space {space:?}"
2190        );
2191        trace!("{:?} keys ready", space);
2192        if space == SpaceId::Data {
2193            // Precompute the first key update
2194            self.next_crypto = Some(
2195                self.crypto
2196                    .next_1rtt_keys()
2197                    .expect("handshake should be complete"),
2198            );
2199        }
2200
2201        self.spaces[space].crypto = Some(crypto);
2202        debug_assert!(space as usize > self.highest_space as usize);
2203        self.highest_space = space;
2204        if space == SpaceId::Data && self.side.is_client() {
2205            // Discard 0-RTT keys because 1-RTT keys are available.
2206            self.zero_rtt_crypto = None;
2207        }
2208    }
2209
2210    fn discard_space(&mut self, now: Instant, space_id: SpaceId) {
2211        debug_assert!(space_id != SpaceId::Data);
2212        trace!("discarding {:?} keys", space_id);
2213        if space_id == SpaceId::Initial {
2214            // No longer needed
2215            if let ConnectionSide::Client { token, .. } = &mut self.side {
2216                *token = Bytes::new();
2217            }
2218        }
2219        let space = &mut self.spaces[space_id];
2220        space.crypto = None;
2221        space.time_of_last_ack_eliciting_packet = None;
2222        space.loss_time = None;
2223        let sent_packets = mem::take(&mut space.sent_packets);
2224        for packet in sent_packets.into_values() {
2225            self.remove_in_flight(&packet);
2226        }
2227        self.set_loss_detection_timer(now)
2228    }
2229
2230    fn handle_coalesced(
2231        &mut self,
2232        now: Instant,
2233        remote: SocketAddr,
2234        ecn: Option<EcnCodepoint>,
2235        data: BytesMut,
2236    ) {
2237        self.path.total_recvd = self.path.total_recvd.saturating_add(data.len() as u64);
2238        let mut remaining = Some(data);
2239        while let Some(data) = remaining {
2240            match PartialDecode::new(
2241                data,
2242                &FixedLengthConnectionIdParser::new(self.local_cid_state.cid_len()),
2243                &[self.version],
2244                self.endpoint_config.grease_quic_bit,
2245            ) {
2246                Ok((partial_decode, rest)) => {
2247                    remaining = rest;
2248                    self.handle_decode(now, remote, ecn, partial_decode);
2249                }
2250                Err(e) => {
2251                    trace!("malformed header: {}", e);
2252                    return;
2253                }
2254            }
2255        }
2256    }
2257
2258    fn handle_decode(
2259        &mut self,
2260        now: Instant,
2261        remote: SocketAddr,
2262        ecn: Option<EcnCodepoint>,
2263        partial_decode: PartialDecode,
2264    ) {
2265        if let Some(decoded) = packet_crypto::unprotect_header(
2266            partial_decode,
2267            &self.spaces,
2268            self.zero_rtt_crypto.as_ref(),
2269            self.peer_params.stateless_reset_token,
2270        ) {
2271            self.handle_packet(now, remote, ecn, decoded.packet, decoded.stateless_reset);
2272        }
2273    }
2274
2275    fn handle_packet(
2276        &mut self,
2277        now: Instant,
2278        remote: SocketAddr,
2279        ecn: Option<EcnCodepoint>,
2280        packet: Option<Packet>,
2281        stateless_reset: bool,
2282    ) {
2283        self.stats.udp_rx.ios += 1;
2284        if let Some(ref packet) = packet {
2285            trace!(
2286                "got {:?} packet ({} bytes) from {} using id {}",
2287                packet.header.space(),
2288                packet.payload.len() + packet.header_data.len(),
2289                remote,
2290                packet.header.dst_cid(),
2291            );
2292        }
2293
2294        if self.is_handshaking() && remote != self.path.remote {
2295            debug!("discarding packet with unexpected remote during handshake");
2296            return;
2297        }
2298
2299        let was_closed = self.state.is_closed();
2300        let was_drained = self.state.is_drained();
2301
2302        let decrypted = match packet {
2303            None => Err(None),
2304            Some(mut packet) => self
2305                .decrypt_packet(now, &mut packet)
2306                .map(move |number| (packet, number)),
2307        };
2308        let result = match decrypted {
2309            _ if stateless_reset => {
2310                debug!("got stateless reset");
2311                Err(ConnectionError::Reset)
2312            }
2313            Err(Some(e)) => {
2314                warn!("illegal packet: {}", e);
2315                Err(e.into())
2316            }
2317            Err(None) => {
2318                debug!("failed to authenticate packet");
2319                self.authentication_failures += 1;
2320                let integrity_limit = self.spaces[self.highest_space]
2321                    .crypto
2322                    .as_ref()
2323                    .unwrap()
2324                    .packet
2325                    .local
2326                    .integrity_limit();
2327                if self.authentication_failures > integrity_limit {
2328                    Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into())
2329                } else {
2330                    return;
2331                }
2332            }
2333            Ok((packet, number)) => {
2334                let span = match number {
2335                    Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn),
2336                    None => trace_span!("recv", space = ?packet.header.space()),
2337                };
2338                let _guard = span.enter();
2339
2340                let is_duplicate = |n| self.spaces[packet.header.space()].dedup.insert(n);
2341                if number.is_some_and(is_duplicate) {
2342                    debug!("discarding possible duplicate packet");
2343                    return;
2344                } else if self.state.is_handshake() && packet.header.is_short() {
2345                    // TODO: SHOULD buffer these to improve reordering tolerance.
2346                    trace!("dropping short packet during handshake");
2347                    return;
2348                } else {
2349                    if let Header::Initial(InitialHeader { ref token, .. }) = packet.header {
2350                        if let State::Handshake(ref hs) = self.state {
2351                            if self.side.is_server() && token != &hs.expected_token {
2352                                // Clients must send the same retry token in every Initial. Initial
2353                                // packets can be spoofed, so we discard rather than killing the
2354                                // connection.
2355                                warn!("discarding Initial with invalid retry token");
2356                                return;
2357                            }
2358                        }
2359                    }
2360
2361                    if !self.state.is_closed() {
2362                        let spin = match packet.header {
2363                            Header::Short { spin, .. } => spin,
2364                            _ => false,
2365                        };
2366                        self.on_packet_authenticated(
2367                            now,
2368                            packet.header.space(),
2369                            ecn,
2370                            number,
2371                            spin,
2372                            packet.header.is_1rtt(),
2373                        );
2374                    }
2375
2376                    self.process_decrypted_packet(now, remote, number, packet)
2377                }
2378            }
2379        };
2380
2381        // State transitions for error cases
2382        if let Err(conn_err) = result {
2383            self.error = Some(conn_err.clone());
2384            self.state = match conn_err {
2385                ConnectionError::ApplicationClosed(reason) => State::closed(reason),
2386                ConnectionError::ConnectionClosed(reason) => State::closed(reason),
2387                ConnectionError::Reset
2388                | ConnectionError::TransportError(TransportError {
2389                    code: TransportErrorCode::AEAD_LIMIT_REACHED,
2390                    ..
2391                }) => State::Drained,
2392                ConnectionError::TimedOut => {
2393                    unreachable!("timeouts aren't generated by packet processing");
2394                }
2395                ConnectionError::TransportError(err) => {
2396                    debug!("closing connection due to transport error: {}", err);
2397                    State::closed(err)
2398                }
2399                ConnectionError::VersionMismatch => State::Draining,
2400                ConnectionError::LocallyClosed => {
2401                    unreachable!("LocallyClosed isn't generated by packet processing");
2402                }
2403                ConnectionError::CidsExhausted => {
2404                    unreachable!("CidsExhausted isn't generated by packet processing");
2405                }
2406            };
2407        }
2408
2409        if !was_closed && self.state.is_closed() {
2410            self.close_common();
2411            if !self.state.is_drained() {
2412                self.set_close_timer(now);
2413            }
2414        }
2415        if !was_drained && self.state.is_drained() {
2416            self.endpoint_events.push_back(EndpointEventInner::Drained);
2417            // Close timer may have been started previously, e.g. if we sent a close and got a
2418            // stateless reset in response
2419            self.timers.stop(Timer::Close);
2420        }
2421
2422        // Transmit CONNECTION_CLOSE if necessary
2423        if let State::Closed(_) = self.state {
2424            self.close = remote == self.path.remote;
2425        }
2426    }
2427
2428    fn process_decrypted_packet(
2429        &mut self,
2430        now: Instant,
2431        remote: SocketAddr,
2432        number: Option<u64>,
2433        packet: Packet,
2434    ) -> Result<(), ConnectionError> {
2435        let state = match self.state {
2436            State::Established => {
2437                match packet.header.space() {
2438                    SpaceId::Data => self.process_payload(now, remote, number.unwrap(), packet)?,
2439                    _ if packet.header.has_frames() => self.process_early_payload(now, packet)?,
2440                    _ => {
2441                        trace!("discarding unexpected pre-handshake packet");
2442                    }
2443                }
2444                return Ok(());
2445            }
2446            State::Closed(_) => {
2447                for result in frame::Iter::new(packet.payload.freeze())? {
2448                    let frame = match result {
2449                        Ok(frame) => frame,
2450                        Err(err) => {
2451                            debug!("frame decoding error: {err:?}");
2452                            continue;
2453                        }
2454                    };
2455
2456                    if let Frame::Padding = frame {
2457                        continue;
2458                    };
2459
2460                    self.stats.frame_rx.record(&frame);
2461
2462                    if let Frame::Close(_) = frame {
2463                        trace!("draining");
2464                        self.state = State::Draining;
2465                        break;
2466                    }
2467                }
2468                return Ok(());
2469            }
2470            State::Draining | State::Drained => return Ok(()),
2471            State::Handshake(ref mut state) => state,
2472        };
2473
2474        match packet.header {
2475            Header::Retry {
2476                src_cid: rem_cid, ..
2477            } => {
2478                if self.side.is_server() {
2479                    return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into());
2480                }
2481
2482                if self.total_authed_packets > 1
2483                            || packet.payload.len() <= 16 // token + 16 byte tag
2484                            || !self.crypto.is_valid_retry(
2485                                &self.rem_cids.active(),
2486                                &packet.header_data,
2487                                &packet.payload,
2488                            )
2489                {
2490                    trace!("discarding invalid Retry");
2491                    // - After the client has received and processed an Initial or Retry
2492                    //   packet from the server, it MUST discard any subsequent Retry
2493                    //   packets that it receives.
2494                    // - A client MUST discard a Retry packet with a zero-length Retry Token
2495                    //   field.
2496                    // - Clients MUST discard Retry packets that have a Retry Integrity Tag
2497                    //   that cannot be validated
2498                    return Ok(());
2499                }
2500
2501                trace!("retrying with CID {}", rem_cid);
2502                let client_hello = state.client_hello.take().unwrap();
2503                self.retry_src_cid = Some(rem_cid);
2504                self.rem_cids.update_initial_cid(rem_cid);
2505                self.rem_handshake_cid = rem_cid;
2506
2507                let space = &mut self.spaces[SpaceId::Initial];
2508                if let Some(info) = space.take(0) {
2509                    self.on_packet_acked(now, info);
2510                };
2511
2512                self.discard_space(now, SpaceId::Initial); // Make sure we clean up after any retransmitted Initials
2513                self.spaces[SpaceId::Initial] = PacketSpace {
2514                    crypto: Some(self.crypto.initial_keys(&rem_cid, self.side.side())),
2515                    next_packet_number: self.spaces[SpaceId::Initial].next_packet_number,
2516                    crypto_offset: client_hello.len() as u64,
2517                    ..PacketSpace::new(now)
2518                };
2519                self.spaces[SpaceId::Initial]
2520                    .pending
2521                    .crypto
2522                    .push_back(frame::Crypto {
2523                        offset: 0,
2524                        data: client_hello,
2525                    });
2526
2527                // Retransmit all 0-RTT data
2528                let zero_rtt = mem::take(&mut self.spaces[SpaceId::Data].sent_packets);
2529                for info in zero_rtt.into_values() {
2530                    self.remove_in_flight(&info);
2531                    self.spaces[SpaceId::Data].pending |= info.retransmits;
2532                }
2533                self.streams.retransmit_all_for_0rtt();
2534
2535                let token_len = packet.payload.len() - 16;
2536                let ConnectionSide::Client { ref mut token, .. } = self.side else {
2537                    unreachable!("we already short-circuited if we're server");
2538                };
2539                *token = packet.payload.freeze().split_to(token_len);
2540                self.state = State::Handshake(state::Handshake {
2541                    expected_token: Bytes::new(),
2542                    rem_cid_set: false,
2543                    client_hello: None,
2544                });
2545                Ok(())
2546            }
2547            Header::Long {
2548                ty: LongType::Handshake,
2549                src_cid: rem_cid,
2550                ..
2551            } => {
2552                if rem_cid != self.rem_handshake_cid {
2553                    debug!(
2554                        "discarding packet with mismatched remote CID: {} != {}",
2555                        self.rem_handshake_cid, rem_cid
2556                    );
2557                    return Ok(());
2558                }
2559                self.on_path_validated();
2560
2561                self.process_early_payload(now, packet)?;
2562                if self.state.is_closed() {
2563                    return Ok(());
2564                }
2565
2566                if self.crypto.is_handshaking() {
2567                    trace!("handshake ongoing");
2568                    return Ok(());
2569                }
2570
2571                if self.side.is_client() {
2572                    // Client-only because server params were set from the client's Initial
2573                    let params =
2574                        self.crypto
2575                            .transport_parameters()?
2576                            .ok_or_else(|| TransportError {
2577                                code: TransportErrorCode::crypto(0x6d),
2578                                frame: None,
2579                                reason: "transport parameters missing".into(),
2580                            })?;
2581
2582                    if self.has_0rtt() {
2583                        if !self.crypto.early_data_accepted().unwrap() {
2584                            debug_assert!(self.side.is_client());
2585                            debug!("0-RTT rejected");
2586                            self.accepted_0rtt = false;
2587                            self.streams.zero_rtt_rejected();
2588
2589                            // Discard already-queued frames
2590                            self.spaces[SpaceId::Data].pending = Retransmits::default();
2591
2592                            // Discard 0-RTT packets
2593                            let sent_packets =
2594                                mem::take(&mut self.spaces[SpaceId::Data].sent_packets);
2595                            for packet in sent_packets.into_values() {
2596                                self.remove_in_flight(&packet);
2597                            }
2598                        } else {
2599                            self.accepted_0rtt = true;
2600                            params.validate_resumption_from(&self.peer_params)?;
2601                        }
2602                    }
2603                    if let Some(token) = params.stateless_reset_token {
2604                        self.endpoint_events
2605                            .push_back(EndpointEventInner::ResetToken(self.path.remote, token));
2606                    }
2607                    self.handle_peer_params(params)?;
2608                    self.issue_first_cids(now);
2609                } else {
2610                    // Server-only
2611                    self.spaces[SpaceId::Data].pending.handshake_done = true;
2612                    self.discard_space(now, SpaceId::Handshake);
2613                }
2614
2615                self.events.push_back(Event::Connected);
2616                self.state = State::Established;
2617                trace!("established");
2618                Ok(())
2619            }
2620            Header::Initial(InitialHeader {
2621                src_cid: rem_cid, ..
2622            }) => {
2623                if !state.rem_cid_set {
2624                    trace!("switching remote CID to {}", rem_cid);
2625                    let mut state = state.clone();
2626                    self.rem_cids.update_initial_cid(rem_cid);
2627                    self.rem_handshake_cid = rem_cid;
2628                    self.orig_rem_cid = rem_cid;
2629                    state.rem_cid_set = true;
2630                    self.state = State::Handshake(state);
2631                } else if rem_cid != self.rem_handshake_cid {
2632                    debug!(
2633                        "discarding packet with mismatched remote CID: {} != {}",
2634                        self.rem_handshake_cid, rem_cid
2635                    );
2636                    return Ok(());
2637                }
2638
2639                let starting_space = self.highest_space;
2640                self.process_early_payload(now, packet)?;
2641
2642                if self.side.is_server()
2643                    && starting_space == SpaceId::Initial
2644                    && self.highest_space != SpaceId::Initial
2645                {
2646                    let params =
2647                        self.crypto
2648                            .transport_parameters()?
2649                            .ok_or_else(|| TransportError {
2650                                code: TransportErrorCode::crypto(0x6d),
2651                                frame: None,
2652                                reason: "transport parameters missing".into(),
2653                            })?;
2654                    self.handle_peer_params(params)?;
2655                    self.issue_first_cids(now);
2656                    self.init_0rtt();
2657                }
2658                Ok(())
2659            }
2660            Header::Long {
2661                ty: LongType::ZeroRtt,
2662                ..
2663            } => {
2664                self.process_payload(now, remote, number.unwrap(), packet)?;
2665                Ok(())
2666            }
2667            Header::VersionNegotiate { .. } => {
2668                if self.total_authed_packets > 1 {
2669                    return Ok(());
2670                }
2671                let supported = packet
2672                    .payload
2673                    .chunks(4)
2674                    .any(|x| match <[u8; 4]>::try_from(x) {
2675                        Ok(version) => self.version == u32::from_be_bytes(version),
2676                        Err(_) => false,
2677                    });
2678                if supported {
2679                    return Ok(());
2680                }
2681                debug!("remote doesn't support our version");
2682                Err(ConnectionError::VersionMismatch)
2683            }
2684            Header::Short { .. } => unreachable!(
2685                "short packets received during handshake are discarded in handle_packet"
2686            ),
2687        }
2688    }
2689
2690    /// Process an Initial or Handshake packet payload
2691    fn process_early_payload(
2692        &mut self,
2693        now: Instant,
2694        packet: Packet,
2695    ) -> Result<(), TransportError> {
2696        debug_assert_ne!(packet.header.space(), SpaceId::Data);
2697        let payload_len = packet.payload.len();
2698        let mut ack_eliciting = false;
2699        for result in frame::Iter::new(packet.payload.freeze())? {
2700            let frame = result?;
2701            let span = match frame {
2702                Frame::Padding => continue,
2703                _ => Some(trace_span!("frame", ty = %frame.ty())),
2704            };
2705
2706            self.stats.frame_rx.record(&frame);
2707
2708            let _guard = span.as_ref().map(|x| x.enter());
2709            ack_eliciting |= frame.is_ack_eliciting();
2710
2711            // Process frames
2712            match frame {
2713                Frame::Padding | Frame::Ping => {}
2714                Frame::Crypto(frame) => {
2715                    self.read_crypto(packet.header.space(), &frame, payload_len)?;
2716                }
2717                Frame::Ack(ack) => {
2718                    self.on_ack_received(now, packet.header.space(), ack)?;
2719                }
2720                Frame::Close(reason) => {
2721                    self.error = Some(reason.into());
2722                    self.state = State::Draining;
2723                    return Ok(());
2724                }
2725                _ => {
2726                    let mut err =
2727                        TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake");
2728                    err.frame = Some(frame.ty());
2729                    return Err(err);
2730                }
2731            }
2732        }
2733
2734        if ack_eliciting {
2735            // In the initial and handshake spaces, ACKs must be sent immediately
2736            self.spaces[packet.header.space()]
2737                .pending_acks
2738                .set_immediate_ack_required();
2739        }
2740
2741        self.write_crypto();
2742        Ok(())
2743    }
2744
2745    fn process_payload(
2746        &mut self,
2747        now: Instant,
2748        remote: SocketAddr,
2749        number: u64,
2750        packet: Packet,
2751    ) -> Result<(), TransportError> {
2752        let payload = packet.payload.freeze();
2753        let mut is_probing_packet = true;
2754        let mut close = None;
2755        let payload_len = payload.len();
2756        let mut ack_eliciting = false;
2757        for result in frame::Iter::new(payload)? {
2758            let frame = result?;
2759            let span = match frame {
2760                Frame::Padding => continue,
2761                _ => Some(trace_span!("frame", ty = %frame.ty())),
2762            };
2763
2764            self.stats.frame_rx.record(&frame);
2765            // Crypto, Stream and Datagram frames are special cased in order no pollute
2766            // the log with payload data
2767            match &frame {
2768                Frame::Crypto(f) => {
2769                    trace!(offset = f.offset, len = f.data.len(), "got crypto frame");
2770                }
2771                Frame::Stream(f) => {
2772                    trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got stream frame");
2773                }
2774                Frame::Datagram(f) => {
2775                    trace!(len = f.data.len(), "got datagram frame");
2776                }
2777                f => {
2778                    trace!("got frame {:?}", f);
2779                }
2780            }
2781
2782            let _guard = span.as_ref().map(|x| x.enter());
2783            if packet.header.is_0rtt() {
2784                match frame {
2785                    Frame::Crypto(_) | Frame::Close(Close::Application(_)) => {
2786                        return Err(TransportError::PROTOCOL_VIOLATION(
2787                            "illegal frame type in 0-RTT",
2788                        ));
2789                    }
2790                    _ => {}
2791                }
2792            }
2793            ack_eliciting |= frame.is_ack_eliciting();
2794
2795            // Check whether this could be a probing packet
2796            match frame {
2797                Frame::Padding
2798                | Frame::PathChallenge(_)
2799                | Frame::PathResponse(_)
2800                | Frame::NewConnectionId(_) => {}
2801                _ => {
2802                    is_probing_packet = false;
2803                }
2804            }
2805            match frame {
2806                Frame::Crypto(frame) => {
2807                    self.read_crypto(SpaceId::Data, &frame, payload_len)?;
2808                }
2809                Frame::Stream(frame) => {
2810                    if self.streams.received(frame, payload_len)?.should_transmit() {
2811                        self.spaces[SpaceId::Data].pending.max_data = true;
2812                    }
2813                }
2814                Frame::Ack(ack) => {
2815                    self.on_ack_received(now, SpaceId::Data, ack)?;
2816                }
2817                Frame::Padding | Frame::Ping => {}
2818                Frame::Close(reason) => {
2819                    close = Some(reason);
2820                }
2821                Frame::PathChallenge(token) => {
2822                    self.path_responses.push(number, token, remote);
2823                    if remote == self.path.remote {
2824                        // PATH_CHALLENGE on active path, possible off-path packet forwarding
2825                        // attack. Send a non-probing packet to recover the active path.
2826                        match self.peer_supports_ack_frequency() {
2827                            true => self.immediate_ack(),
2828                            false => self.ping(),
2829                        }
2830                    }
2831                }
2832                Frame::PathResponse(token) => {
2833                    if self.path.challenge == Some(token) && remote == self.path.remote {
2834                        trace!("new path validated");
2835                        self.timers.stop(Timer::PathValidation);
2836                        self.path.challenge = None;
2837                        self.path.validated = true;
2838                        if let Some((_, ref mut prev_path)) = self.prev_path {
2839                            prev_path.challenge = None;
2840                            prev_path.challenge_pending = false;
2841                        }
2842                    } else {
2843                        debug!(token, "ignoring invalid PATH_RESPONSE");
2844                    }
2845                }
2846                Frame::MaxData(bytes) => {
2847                    self.streams.received_max_data(bytes);
2848                }
2849                Frame::MaxStreamData { id, offset } => {
2850                    self.streams.received_max_stream_data(id, offset)?;
2851                }
2852                Frame::MaxStreams { dir, count } => {
2853                    self.streams.received_max_streams(dir, count)?;
2854                }
2855                Frame::ResetStream(frame) => {
2856                    if self.streams.received_reset(frame)?.should_transmit() {
2857                        self.spaces[SpaceId::Data].pending.max_data = true;
2858                    }
2859                }
2860                Frame::DataBlocked { offset } => {
2861                    debug!(offset, "peer claims to be blocked at connection level");
2862                }
2863                Frame::StreamDataBlocked { id, offset } => {
2864                    if id.initiator() == self.side.side() && id.dir() == Dir::Uni {
2865                        debug!("got STREAM_DATA_BLOCKED on send-only {}", id);
2866                        return Err(TransportError::STREAM_STATE_ERROR(
2867                            "STREAM_DATA_BLOCKED on send-only stream",
2868                        ));
2869                    }
2870                    debug!(
2871                        stream = %id,
2872                        offset, "peer claims to be blocked at stream level"
2873                    );
2874                }
2875                Frame::StreamsBlocked { dir, limit } => {
2876                    if limit > MAX_STREAM_COUNT {
2877                        return Err(TransportError::FRAME_ENCODING_ERROR(
2878                            "unrepresentable stream limit",
2879                        ));
2880                    }
2881                    debug!(
2882                        "peer claims to be blocked opening more than {} {} streams",
2883                        limit, dir
2884                    );
2885                }
2886                Frame::StopSending(frame::StopSending { id, error_code }) => {
2887                    if id.initiator() != self.side.side() {
2888                        if id.dir() == Dir::Uni {
2889                            debug!("got STOP_SENDING on recv-only {}", id);
2890                            return Err(TransportError::STREAM_STATE_ERROR(
2891                                "STOP_SENDING on recv-only stream",
2892                            ));
2893                        }
2894                    } else if self.streams.is_local_unopened(id) {
2895                        return Err(TransportError::STREAM_STATE_ERROR(
2896                            "STOP_SENDING on unopened stream",
2897                        ));
2898                    }
2899                    self.streams.received_stop_sending(id, error_code);
2900                }
2901                Frame::RetireConnectionId { sequence } => {
2902                    let allow_more_cids = self
2903                        .local_cid_state
2904                        .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?;
2905                    self.endpoint_events
2906                        .push_back(EndpointEventInner::RetireConnectionId(
2907                            now,
2908                            sequence,
2909                            allow_more_cids,
2910                        ));
2911                }
2912                Frame::NewConnectionId(frame) => {
2913                    trace!(
2914                        sequence = frame.sequence,
2915                        id = %frame.id,
2916                        retire_prior_to = frame.retire_prior_to,
2917                    );
2918                    if self.rem_cids.active().is_empty() {
2919                        return Err(TransportError::PROTOCOL_VIOLATION(
2920                            "NEW_CONNECTION_ID when CIDs aren't in use",
2921                        ));
2922                    }
2923                    if frame.retire_prior_to > frame.sequence {
2924                        return Err(TransportError::PROTOCOL_VIOLATION(
2925                            "NEW_CONNECTION_ID retiring unissued CIDs",
2926                        ));
2927                    }
2928
2929                    use crate::cid_queue::InsertError;
2930                    match self.rem_cids.insert(frame) {
2931                        Ok(None) => {}
2932                        Ok(Some((retired, reset_token))) => {
2933                            self.spaces[SpaceId::Data].pending.retire_cids(retired)?;
2934                            self.set_reset_token(reset_token);
2935                        }
2936                        Err(InsertError::ExceedsLimit) => {
2937                            return Err(TransportError::CONNECTION_ID_LIMIT_ERROR(""));
2938                        }
2939                        Err(InsertError::Retired) => {
2940                            trace!("discarding already-retired");
2941                            // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a
2942                            // range of connection IDs larger than the active connection ID limit
2943                            // was retired all at once via retire_prior_to.
2944                            self.spaces[SpaceId::Data]
2945                                .pending
2946                                .retire_cids(frame.sequence..frame.sequence.saturating_add(1))?;
2947                            continue;
2948                        }
2949                    };
2950
2951                    if self.side.is_server() && self.rem_cids.active_seq() == 0 {
2952                        // We're a server still using the initial remote CID for the client, so
2953                        // let's switch immediately to enable clientside stateless resets.
2954                        self.update_rem_cid();
2955                    }
2956                }
2957                Frame::NewToken(NewToken { token }) => {
2958                    let ConnectionSide::Client {
2959                        token_store,
2960                        server_name,
2961                        ..
2962                    } = &self.side
2963                    else {
2964                        return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN"));
2965                    };
2966                    if token.is_empty() {
2967                        return Err(TransportError::FRAME_ENCODING_ERROR("empty token"));
2968                    }
2969                    trace!("got new token");
2970                    token_store.insert(server_name, token);
2971                }
2972                Frame::Datagram(datagram) => {
2973                    if self
2974                        .datagrams
2975                        .received(datagram, &self.config.datagram_receive_buffer_size)?
2976                    {
2977                        self.events.push_back(Event::DatagramReceived);
2978                    }
2979                }
2980                Frame::AckFrequency(ack_frequency) => {
2981                    // This frame can only be sent in the Data space
2982                    let space = &mut self.spaces[SpaceId::Data];
2983
2984                    if !self
2985                        .ack_frequency
2986                        .ack_frequency_received(&ack_frequency, &mut space.pending_acks)?
2987                    {
2988                        // The AckFrequency frame is stale (we have already received a more recent one)
2989                        continue;
2990                    }
2991
2992                    // Our `max_ack_delay` has been updated, so we may need to adjust its associated
2993                    // timeout
2994                    if let Some(timeout) = space
2995                        .pending_acks
2996                        .max_ack_delay_timeout(self.ack_frequency.max_ack_delay)
2997                    {
2998                        self.timers.set(Timer::MaxAckDelay, timeout);
2999                    }
3000                }
3001                Frame::ImmediateAck => {
3002                    // This frame can only be sent in the Data space
3003                    self.spaces[SpaceId::Data]
3004                        .pending_acks
3005                        .set_immediate_ack_required();
3006                }
3007                Frame::HandshakeDone => {
3008                    if self.side.is_server() {
3009                        return Err(TransportError::PROTOCOL_VIOLATION(
3010                            "client sent HANDSHAKE_DONE",
3011                        ));
3012                    }
3013                    if self.spaces[SpaceId::Handshake].crypto.is_some() {
3014                        self.discard_space(now, SpaceId::Handshake);
3015                    }
3016                }
3017            }
3018        }
3019
3020        let space = &mut self.spaces[SpaceId::Data];
3021        if space
3022            .pending_acks
3023            .packet_received(now, number, ack_eliciting, &space.dedup)
3024        {
3025            self.timers
3026                .set(Timer::MaxAckDelay, now + self.ack_frequency.max_ack_delay);
3027            self.next_bundled_ack_time = Some(now);
3028        }
3029
3030        // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets
3031        // on stopped streams. Incoming finishes/resets on open streams are not handled here as they
3032        // are only freed, and hence only issue credit, once the application has been notified
3033        // during a read on the stream.
3034        let pending = &mut self.spaces[SpaceId::Data].pending;
3035        self.streams.queue_max_stream_id(pending);
3036
3037        if let Some(reason) = close {
3038            self.error = Some(reason.into());
3039            self.state = State::Draining;
3040            self.close = true;
3041        }
3042
3043        if remote != self.path.remote
3044            && !is_probing_packet
3045            && number == self.spaces[SpaceId::Data].rx_packet
3046        {
3047            let ConnectionSide::Server { ref server_config } = self.side else {
3048                panic!("packets from unknown remote should be dropped by clients");
3049            };
3050            debug_assert!(
3051                server_config.migration,
3052                "migration-initiating packets should have been dropped immediately"
3053            );
3054            self.migrate(now, remote);
3055            // Break linkability, if possible
3056            self.update_rem_cid();
3057            self.spin = false;
3058        }
3059
3060        Ok(())
3061    }
3062
3063    fn migrate(&mut self, now: Instant, remote: SocketAddr) {
3064        trace!(%remote, "migration initiated");
3065        self.path_counter = self.path_counter.wrapping_add(1);
3066        // Reset rtt/congestion state for new path unless it looks like a NAT rebinding.
3067        // Note that the congestion window will not grow until validation terminates. Helps mitigate
3068        // amplification attacks performed by spoofing source addresses.
3069        let mut new_path = if remote.is_ipv4() && remote.ip() == self.path.remote.ip() {
3070            PathData::from_previous(remote, &self.path, self.path_counter, now)
3071        } else {
3072            let peer_max_udp_payload_size =
3073                u16::try_from(self.peer_params.max_udp_payload_size.into_inner())
3074                    .unwrap_or(u16::MAX);
3075            PathData::new(
3076                remote,
3077                self.allow_mtud,
3078                Some(peer_max_udp_payload_size),
3079                self.path_counter,
3080                now,
3081                &self.config,
3082            )
3083        };
3084        new_path.challenge = Some(self.rng.random());
3085        new_path.challenge_pending = true;
3086        let prev_pto = self.pto(SpaceId::Data);
3087
3088        let mut prev = mem::replace(&mut self.path, new_path);
3089        self.datagrams().drop_oversized();
3090        // Don't clobber the original path if the previous one hasn't been validated yet
3091        if prev.challenge.is_none() {
3092            prev.challenge = Some(self.rng.random());
3093            prev.challenge_pending = true;
3094            // We haven't updated the remote CID yet, this captures the remote CID we were using on
3095            // the previous path.
3096            self.prev_path = Some((self.rem_cids.active(), prev));
3097        }
3098
3099        self.timers.set(
3100            Timer::PathValidation,
3101            now + 3 * cmp::max(self.pto(SpaceId::Data), prev_pto),
3102        );
3103    }
3104
3105    /// Handle a change in the local address, i.e. an active migration
3106    pub fn local_address_changed(&mut self) {
3107        self.update_rem_cid();
3108        self.ping();
3109    }
3110
3111    /// Switch to a previously unused remote connection ID, if possible
3112    fn update_rem_cid(&mut self) {
3113        let (reset_token, retired) = match self.rem_cids.next() {
3114            Some(x) => x,
3115            None => return,
3116        };
3117
3118        // Retire the current remote CID and any CIDs we had to skip.
3119        self.spaces[SpaceId::Data]
3120            .pending
3121            .retire_cids
3122            .extend(retired);
3123        self.set_reset_token(reset_token);
3124    }
3125
3126    fn set_reset_token(&mut self, reset_token: ResetToken) {
3127        self.endpoint_events
3128            .push_back(EndpointEventInner::ResetToken(
3129                self.path.remote,
3130                reset_token,
3131            ));
3132        self.peer_params.stateless_reset_token = Some(reset_token);
3133    }
3134
3135    /// Issue an initial set of connection IDs to the peer upon connection
3136    fn issue_first_cids(&mut self, now: Instant) {
3137        if self.local_cid_state.cid_len() == 0 {
3138            return;
3139        }
3140
3141        // Subtract 1 to account for the CID we supplied while handshaking
3142        let mut n = self.peer_params.issue_cids_limit() - 1;
3143        if let ConnectionSide::Server { server_config } = &self.side {
3144            if server_config.has_preferred_address() {
3145                // We also sent a CID in the transport parameters
3146                n -= 1;
3147            }
3148        }
3149        self.endpoint_events
3150            .push_back(EndpointEventInner::NeedIdentifiers(now, n));
3151    }
3152
3153    fn populate_packet(
3154        &mut self,
3155        now: Instant,
3156        space_id: SpaceId,
3157        buf: &mut Vec<u8>,
3158        max_size: usize,
3159        pn: u64,
3160    ) -> SentFrames {
3161        let mut sent = SentFrames::default();
3162        let space = &mut self.spaces[space_id];
3163        let is_0rtt = space_id == SpaceId::Data && space.crypto.is_none();
3164        space.pending_acks.maybe_ack_non_eliciting();
3165
3166        let pre_payload_len = buf.len();
3167
3168        // HANDSHAKE_DONE
3169        if !is_0rtt && mem::replace(&mut space.pending.handshake_done, false) {
3170            buf.write(frame::FrameType::HANDSHAKE_DONE);
3171            sent.retransmits.get_or_create().handshake_done = true;
3172            // This is just a u8 counter and the frame is typically just sent once
3173            self.stats.frame_tx.handshake_done =
3174                self.stats.frame_tx.handshake_done.saturating_add(1);
3175        }
3176
3177        // PING
3178        if mem::replace(&mut space.ping_pending, false) {
3179            trace!("PING");
3180            buf.write(frame::FrameType::PING);
3181            sent.non_retransmits = true;
3182            self.stats.frame_tx.ping += 1;
3183        }
3184
3185        // IMMEDIATE_ACK
3186        if mem::replace(&mut space.immediate_ack_pending, false) {
3187            trace!("IMMEDIATE_ACK");
3188            buf.write(frame::FrameType::IMMEDIATE_ACK);
3189            sent.non_retransmits = true;
3190            self.stats.frame_tx.immediate_ack += 1;
3191        }
3192
3193        // ACK
3194        if space.pending_acks.can_send() {
3195            Self::try_populate_acks(
3196                now,
3197                self.receiving_ecn,
3198                &mut sent,
3199                space,
3200                buf,
3201                &mut self.stats,
3202                max_size,
3203            );
3204        }
3205
3206        // ACK_FREQUENCY
3207        if mem::replace(&mut space.pending.ack_frequency, false) {
3208            let sequence_number = self.ack_frequency.next_sequence_number();
3209
3210            // Safe to unwrap because this is always provided when ACK frequency is enabled
3211            let config = self.config.ack_frequency_config.as_ref().unwrap();
3212
3213            // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error
3214            let max_ack_delay = self.ack_frequency.candidate_max_ack_delay(
3215                self.path.rtt.get(),
3216                config,
3217                &self.peer_params,
3218            );
3219
3220            trace!(?max_ack_delay, "ACK_FREQUENCY");
3221
3222            frame::AckFrequency {
3223                sequence: sequence_number,
3224                ack_eliciting_threshold: config.ack_eliciting_threshold,
3225                request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX),
3226                reordering_threshold: config.reordering_threshold,
3227            }
3228            .encode(buf);
3229
3230            sent.retransmits.get_or_create().ack_frequency = true;
3231
3232            self.ack_frequency.ack_frequency_sent(pn, max_ack_delay);
3233            self.stats.frame_tx.ack_frequency += 1;
3234        }
3235
3236        // PATH_CHALLENGE
3237        if buf.len() + 9 < max_size && space_id == SpaceId::Data {
3238            // Transmit challenges with every outgoing frame on an unvalidated path
3239            if let Some(token) = self.path.challenge {
3240                // But only send a packet solely for that purpose at most once
3241                self.path.challenge_pending = false;
3242                sent.non_retransmits = true;
3243                sent.requires_padding = true;
3244                trace!("PATH_CHALLENGE {:08x}", token);
3245                buf.write(frame::FrameType::PATH_CHALLENGE);
3246                buf.write(token);
3247                self.stats.frame_tx.path_challenge += 1;
3248            }
3249        }
3250
3251        // PATH_RESPONSE
3252        if buf.len() + 9 < max_size && space_id == SpaceId::Data {
3253            if let Some(token) = self.path_responses.pop_on_path(self.path.remote) {
3254                sent.non_retransmits = true;
3255                sent.requires_padding = true;
3256                trace!("PATH_RESPONSE {:08x}", token);
3257                buf.write(frame::FrameType::PATH_RESPONSE);
3258                buf.write(token);
3259                self.stats.frame_tx.path_response += 1;
3260            }
3261        }
3262
3263        // CRYPTO
3264        while buf.len() + frame::Crypto::SIZE_BOUND < max_size && !is_0rtt {
3265            let mut frame = match space.pending.crypto.pop_front() {
3266                Some(x) => x,
3267                None => break,
3268            };
3269
3270            // Calculate the maximum amount of crypto data we can store in the buffer.
3271            // Since the offset is known, we can reserve the exact size required to encode it.
3272            // For length we reserve 2bytes which allows to encode up to 2^14,
3273            // which is more than what fits into normally sized QUIC frames.
3274            let max_crypto_data_size = max_size
3275                - buf.len()
3276                - 1 // Frame Type
3277                - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) })
3278                - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes
3279
3280            let len = frame
3281                .data
3282                .len()
3283                .min(2usize.pow(14) - 1)
3284                .min(max_crypto_data_size);
3285
3286            let data = frame.data.split_to(len);
3287            let truncated = frame::Crypto {
3288                offset: frame.offset,
3289                data,
3290            };
3291            trace!(
3292                "CRYPTO: off {} len {}",
3293                truncated.offset,
3294                truncated.data.len()
3295            );
3296            truncated.encode(buf);
3297            self.stats.frame_tx.crypto += 1;
3298            sent.retransmits.get_or_create().crypto.push_back(truncated);
3299            if !frame.data.is_empty() {
3300                frame.offset += len as u64;
3301                space.pending.crypto.push_front(frame);
3302            }
3303        }
3304
3305        if space_id == SpaceId::Data {
3306            self.streams.write_control_frames(
3307                buf,
3308                &mut space.pending,
3309                &mut sent.retransmits,
3310                &mut self.stats.frame_tx,
3311                max_size,
3312            );
3313        }
3314
3315        // NEW_CONNECTION_ID
3316        while buf.len() + NewConnectionId::SIZE_BOUND < max_size {
3317            let issued = match space.pending.new_cids.pop() {
3318                Some(x) => x,
3319                None => break,
3320            };
3321            trace!(
3322                sequence = issued.sequence,
3323                id = %issued.id,
3324                "NEW_CONNECTION_ID"
3325            );
3326            frame::NewConnectionId {
3327                sequence: issued.sequence,
3328                retire_prior_to: self.local_cid_state.retire_prior_to(),
3329                id: issued.id,
3330                reset_token: issued.reset_token,
3331            }
3332            .encode(buf);
3333            sent.retransmits.get_or_create().new_cids.push(issued);
3334            self.stats.frame_tx.new_connection_id += 1;
3335        }
3336
3337        // RETIRE_CONNECTION_ID
3338        while buf.len() + frame::RETIRE_CONNECTION_ID_SIZE_BOUND < max_size {
3339            let seq = match space.pending.retire_cids.pop() {
3340                Some(x) => x,
3341                None => break,
3342            };
3343            trace!(sequence = seq, "RETIRE_CONNECTION_ID");
3344            buf.write(frame::FrameType::RETIRE_CONNECTION_ID);
3345            buf.write_var(seq);
3346            sent.retransmits.get_or_create().retire_cids.push(seq);
3347            self.stats.frame_tx.retire_connection_id += 1;
3348        }
3349
3350        // DATAGRAM
3351        let mut sent_datagrams = false;
3352        while buf.len() + Datagram::SIZE_BOUND < max_size && space_id == SpaceId::Data {
3353            match self.datagrams.write(buf, max_size) {
3354                true => {
3355                    sent_datagrams = true;
3356                    sent.non_retransmits = true;
3357                    self.stats.frame_tx.datagram += 1;
3358                }
3359                false => break,
3360            }
3361        }
3362        if self.datagrams.send_blocked && sent_datagrams {
3363            self.events.push_back(Event::DatagramsUnblocked);
3364            self.datagrams.send_blocked = false;
3365        }
3366
3367        // NEW_TOKEN
3368        while let Some(remote_addr) = space.pending.new_tokens.pop() {
3369            debug_assert_eq!(space_id, SpaceId::Data);
3370            let ConnectionSide::Server { server_config } = &self.side else {
3371                panic!("NEW_TOKEN frames should not be enqueued by clients");
3372            };
3373
3374            if remote_addr != self.path.remote {
3375                // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only
3376                // useful if used from the same IP address.  Thus, we abandon enqueued NEW_TOKEN
3377                // frames upon an path change. Instead, when the new path becomes validated,
3378                // NEW_TOKEN frames may be enqueued for the new path instead.
3379                continue;
3380            }
3381
3382            let token = Token::new(
3383                TokenPayload::Validation {
3384                    ip: remote_addr.ip(),
3385                    issued: server_config.time_source.now(),
3386                },
3387                &mut self.rng,
3388            );
3389            let new_token = NewToken {
3390                token: token.encode(&*server_config.token_key).into(),
3391            };
3392
3393            if buf.len() + new_token.size() >= max_size {
3394                space.pending.new_tokens.push(remote_addr);
3395                break;
3396            }
3397
3398            new_token.encode(buf);
3399            sent.retransmits
3400                .get_or_create()
3401                .new_tokens
3402                .push(remote_addr);
3403            self.stats.frame_tx.new_token += 1;
3404        }
3405
3406        // STREAM
3407        if space_id == SpaceId::Data {
3408            sent.stream_frames =
3409                self.streams
3410                    .write_stream_frames(buf, max_size, self.config.send_fairness);
3411            self.stats.frame_tx.stream += sent.stream_frames.len() as u64;
3412        }
3413
3414        // Bundle ACK with other frames when there is room for them.
3415        // We want to reuse encryption and underlying protocol overhead,
3416        // but sending multiple ACKs for a single incoming packet is a waste of peer's resources,
3417        // so we have next_bundled_ack_time to control when to send ACKs.
3418        let any_frames_sent = buf.len() > pre_payload_len;
3419        if any_frames_sent
3420            && sent.largest_acked.is_none()
3421            && self.next_bundled_ack_time.is_some_and(|time| time <= now)
3422            && space.pending_acks.can_send_with_other_frames()
3423        {
3424            Self::try_populate_acks(
3425                now,
3426                self.receiving_ecn,
3427                &mut sent,
3428                space,
3429                buf,
3430                &mut self.stats,
3431                max_size,
3432            );
3433        }
3434
3435        sent
3436    }
3437
3438    /// Tries to write pending ACKs into a buffer if there is enough space.
3439    ///
3440    /// If the ACK frame does not fit into the buffer, the ACK frame will not
3441    /// be sent at all.
3442    ///
3443    /// This method assumes ACKs are pending, and should only be called if
3444    /// `!PendingAcks::ranges().is_empty()` returns `true`.
3445    fn try_populate_acks(
3446        now: Instant,
3447        receiving_ecn: bool,
3448        sent: &mut SentFrames,
3449        space: &mut PacketSpace,
3450        buf: &mut Vec<u8>,
3451        stats: &mut ConnectionStats,
3452        max_size: usize,
3453    ) {
3454        debug_assert!(!space.pending_acks.ranges().is_empty());
3455
3456        // 0-RTT packets must never carry acks (which would have to be of handshake packets)
3457        debug_assert!(space.crypto.is_some(), "tried to send ACK in 0-RTT");
3458        let ecn = if receiving_ecn {
3459            Some(&space.ecn_counters)
3460        } else {
3461            None
3462        };
3463
3464        let delay_micros = space.pending_acks.ack_delay(now).as_micros() as u64;
3465
3466        // TODO: This should come from `TransportConfig` if that gets configurable.
3467        let ack_delay_exp = TransportParameters::default().ack_delay_exponent;
3468        let delay = delay_micros >> ack_delay_exp.into_inner();
3469
3470        trace!(
3471            "ACK {:?}, Delay = {}us",
3472            space.pending_acks.ranges(),
3473            delay_micros
3474        );
3475
3476        let no_acks_len = buf.len();
3477        frame::Ack::encode(delay as _, space.pending_acks.ranges(), ecn, buf);
3478        if buf.len() > max_size {
3479            // The ACK frame is too large. Remove it.
3480            buf.truncate(no_acks_len);
3481            return;
3482        }
3483        sent.largest_acked = space.pending_acks.ranges().max();
3484        stats.frame_tx.acks += 1;
3485    }
3486
3487    fn close_common(&mut self) {
3488        trace!("connection closed");
3489        for &timer in &Timer::VALUES {
3490            self.timers.stop(timer);
3491        }
3492    }
3493
3494    fn set_close_timer(&mut self, now: Instant) {
3495        self.timers
3496            .set(Timer::Close, now + 3 * self.pto(self.highest_space));
3497    }
3498
3499    /// Handle transport parameters received from the peer
3500    fn handle_peer_params(&mut self, params: TransportParameters) -> Result<(), TransportError> {
3501        if Some(self.orig_rem_cid) != params.initial_src_cid
3502            || (self.side.is_client()
3503                && (Some(self.initial_dst_cid) != params.original_dst_cid
3504                    || self.retry_src_cid != params.retry_src_cid))
3505        {
3506            return Err(TransportError::TRANSPORT_PARAMETER_ERROR(
3507                "CID authentication failure",
3508            ));
3509        }
3510
3511        self.set_peer_params(params);
3512
3513        Ok(())
3514    }
3515
3516    fn set_peer_params(&mut self, params: TransportParameters) {
3517        self.streams.set_params(&params);
3518        self.idle_timeout =
3519            negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout));
3520        trace!("negotiated max idle timeout {:?}", self.idle_timeout);
3521        if let Some(ref info) = params.preferred_address {
3522            self.rem_cids.insert(frame::NewConnectionId {
3523                sequence: 1,
3524                id: info.connection_id,
3525                reset_token: info.stateless_reset_token,
3526                retire_prior_to: 0,
3527            }).expect("preferred address CID is the first received, and hence is guaranteed to be legal");
3528        }
3529        self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params);
3530        self.peer_params = params;
3531        self.path.mtud.on_peer_max_udp_payload_size_received(
3532            u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX),
3533        );
3534    }
3535
3536    fn decrypt_packet(
3537        &mut self,
3538        now: Instant,
3539        packet: &mut Packet,
3540    ) -> Result<Option<u64>, Option<TransportError>> {
3541        let result = packet_crypto::decrypt_packet_body(
3542            packet,
3543            &self.spaces,
3544            self.zero_rtt_crypto.as_ref(),
3545            self.key_phase,
3546            self.prev_crypto.as_ref(),
3547            self.next_crypto.as_ref(),
3548        )?;
3549
3550        let result = match result {
3551            Some(r) => r,
3552            None => return Ok(None),
3553        };
3554
3555        if result.outgoing_key_update_acked {
3556            if let Some(prev) = self.prev_crypto.as_mut() {
3557                prev.end_packet = Some((result.number, now));
3558                self.set_key_discard_timer(now, packet.header.space());
3559            }
3560        }
3561
3562        if result.incoming_key_update {
3563            trace!("key update authenticated");
3564            self.update_keys(Some((result.number, now)), true);
3565            self.set_key_discard_timer(now, packet.header.space());
3566        }
3567
3568        Ok(Some(result.number))
3569    }
3570
3571    fn update_keys(&mut self, end_packet: Option<(u64, Instant)>, remote: bool) {
3572        trace!("executing key update");
3573        // Generate keys for the key phase after the one we're switching to, store them in
3574        // `next_crypto`, make the contents of `next_crypto` current, and move the current keys into
3575        // `prev_crypto`.
3576        let new = self
3577            .crypto
3578            .next_1rtt_keys()
3579            .expect("only called for `Data` packets");
3580        self.key_phase_size = new
3581            .local
3582            .confidentiality_limit()
3583            .saturating_sub(KEY_UPDATE_MARGIN);
3584        let old = mem::replace(
3585            &mut self.spaces[SpaceId::Data]
3586                .crypto
3587                .as_mut()
3588                .unwrap() // safe because update_keys() can only be triggered by short packets
3589                .packet,
3590            mem::replace(self.next_crypto.as_mut().unwrap(), new),
3591        );
3592        self.spaces[SpaceId::Data].sent_with_keys = 0;
3593        self.prev_crypto = Some(PrevCrypto {
3594            crypto: old,
3595            end_packet,
3596            update_unacked: remote,
3597        });
3598        self.key_phase = !self.key_phase;
3599    }
3600
3601    fn peer_supports_ack_frequency(&self) -> bool {
3602        self.peer_params.min_ack_delay.is_some()
3603    }
3604
3605    /// Send an IMMEDIATE_ACK frame to the remote endpoint
3606    ///
3607    /// According to the spec, this will result in an error if the remote endpoint does not support
3608    /// the Acknowledgement Frequency extension
3609    pub(crate) fn immediate_ack(&mut self) {
3610        self.spaces[self.highest_space].immediate_ack_pending = true;
3611    }
3612
3613    /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests
3614    #[cfg(test)]
3615    pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> {
3616        let (first_decode, remaining) = match &event.0 {
3617            ConnectionEventInner::Datagram(DatagramConnectionEvent {
3618                first_decode,
3619                remaining,
3620                ..
3621            }) => (first_decode, remaining),
3622            _ => return None,
3623        };
3624
3625        if remaining.is_some() {
3626            panic!("Packets should never be coalesced in tests");
3627        }
3628
3629        let decrypted_header = packet_crypto::unprotect_header(
3630            first_decode.clone(),
3631            &self.spaces,
3632            self.zero_rtt_crypto.as_ref(),
3633            self.peer_params.stateless_reset_token,
3634        )?;
3635
3636        let mut packet = decrypted_header.packet?;
3637        packet_crypto::decrypt_packet_body(
3638            &mut packet,
3639            &self.spaces,
3640            self.zero_rtt_crypto.as_ref(),
3641            self.key_phase,
3642            self.prev_crypto.as_ref(),
3643            self.next_crypto.as_ref(),
3644        )
3645        .ok()?;
3646
3647        Some(packet.payload.to_vec())
3648    }
3649
3650    /// The number of bytes of packets containing retransmittable frames that have not been
3651    /// acknowledged or declared lost.
3652    #[cfg(test)]
3653    pub(crate) fn bytes_in_flight(&self) -> u64 {
3654        self.path.in_flight.bytes
3655    }
3656
3657    /// Number of bytes worth of non-ack-only packets that may be sent
3658    #[cfg(test)]
3659    pub(crate) fn congestion_window(&self) -> u64 {
3660        self.path
3661            .congestion
3662            .window()
3663            .saturating_sub(self.path.in_flight.bytes)
3664    }
3665
3666    /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running
3667    #[cfg(test)]
3668    pub(crate) fn is_idle(&self) -> bool {
3669        Timer::VALUES
3670            .iter()
3671            .filter(|&&t| !matches!(t, Timer::KeepAlive | Timer::PushNewCid | Timer::KeyDiscard))
3672            .filter_map(|&t| Some((t, self.timers.get(t)?)))
3673            .min_by_key(|&(_, time)| time)
3674            .is_none_or(|(timer, _)| timer == Timer::Idle)
3675    }
3676
3677    /// Whether explicit congestion notification is in use on outgoing packets.
3678    #[cfg(test)]
3679    pub(crate) fn using_ecn(&self) -> bool {
3680        self.path.sending_ecn
3681    }
3682
3683    /// The number of received bytes in the current path
3684    #[cfg(test)]
3685    pub(crate) fn total_recvd(&self) -> u64 {
3686        self.path.total_recvd
3687    }
3688
3689    #[cfg(test)]
3690    pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) {
3691        self.local_cid_state.active_seq()
3692    }
3693
3694    /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame
3695    /// with updated `retire_prior_to` field set to `v`
3696    #[cfg(test)]
3697    pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) {
3698        let n = self.local_cid_state.assign_retire_seq(v);
3699        self.endpoint_events
3700            .push_back(EndpointEventInner::NeedIdentifiers(now, n));
3701    }
3702
3703    /// Check the current active remote CID sequence
3704    #[cfg(test)]
3705    pub(crate) fn active_rem_cid_seq(&self) -> u64 {
3706        self.rem_cids.active_seq()
3707    }
3708
3709    /// Returns the detected maximum udp payload size for the current path
3710    #[cfg(test)]
3711    pub(crate) fn path_mtu(&self) -> u16 {
3712        self.path.current_mtu()
3713    }
3714
3715    /// Whether we have 1-RTT data to send
3716    ///
3717    /// See also `self.space(SpaceId::Data).can_send()`
3718    fn can_send_1rtt(&self, max_size: usize) -> bool {
3719        self.streams.can_send_stream_data()
3720            || self.path.challenge_pending
3721            || self
3722                .prev_path
3723                .as_ref()
3724                .is_some_and(|(_, x)| x.challenge_pending)
3725            || !self.path_responses.is_empty()
3726            || self.datagrams.outgoing.can_send_1rtt(max_size)
3727    }
3728
3729    /// Update counters to account for a packet becoming acknowledged, lost, or abandoned
3730    fn remove_in_flight(&mut self, packet: &SentPacket) {
3731        // Visit known paths from newest to oldest to find the one `packet` was sent on
3732        for path in [&mut self.path]
3733            .into_iter()
3734            .chain(self.prev_path.as_mut().map(|(_, data)| data))
3735        {
3736            if path.remove_in_flight(packet) {
3737                return;
3738            }
3739        }
3740    }
3741
3742    /// Terminate the connection instantly, without sending a close packet
3743    fn kill(&mut self, reason: ConnectionError) {
3744        self.close_common();
3745        self.error = Some(reason);
3746        self.state = State::Drained;
3747        self.endpoint_events.push_back(EndpointEventInner::Drained);
3748    }
3749
3750    /// Storage size required for the largest packet known to be supported by the current path
3751    ///
3752    /// Buffers passed to [`Connection::poll_transmit`] should be at least this large.
3753    pub fn current_mtu(&self) -> u16 {
3754        self.path.current_mtu()
3755    }
3756
3757    /// Size of non-frame data for a 1-RTT packet
3758    ///
3759    /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are
3760    /// frames. Changes if the length of the remote connection ID changes, which is expected to be
3761    /// rare. If `pn` is specified, may additionally change unpredictably due to variations in
3762    /// latency and packet loss.
3763    fn predict_1rtt_overhead(&self, pn: Option<u64>) -> usize {
3764        let pn_len = match pn {
3765            Some(pn) => PacketNumber::new(
3766                pn,
3767                self.spaces[SpaceId::Data].largest_acked_packet.unwrap_or(0),
3768            )
3769            .len(),
3770            // Upper bound
3771            None => 4,
3772        };
3773
3774        // 1 byte for flags
3775        1 + self.rem_cids.active().len() + pn_len + self.tag_len_1rtt()
3776    }
3777
3778    fn tag_len_1rtt(&self) -> usize {
3779        let key = match self.spaces[SpaceId::Data].crypto.as_ref() {
3780            Some(crypto) => Some(&*crypto.packet.local),
3781            None => self.zero_rtt_crypto.as_ref().map(|x| &*x.packet),
3782        };
3783        // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of
3784        // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead,
3785        // but that would needlessly prevent sending datagrams during 0-RTT.
3786        key.map_or(16, |x| x.tag_len())
3787    }
3788
3789    /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate
3790    fn on_path_validated(&mut self) {
3791        self.path.validated = true;
3792        let ConnectionSide::Server { server_config } = &self.side else {
3793            return;
3794        };
3795        let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens;
3796        new_tokens.clear();
3797        for _ in 0..server_config.validation_token.sent {
3798            new_tokens.push(self.path.remote);
3799        }
3800    }
3801}
3802
3803impl fmt::Debug for Connection {
3804    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3805        f.debug_struct("Connection")
3806            .field("handshake_cid", &self.handshake_cid)
3807            .finish()
3808    }
3809}
3810
3811/// Fields of `Connection` specific to it being client-side or server-side
3812enum ConnectionSide {
3813    Client {
3814        /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded
3815        token: Bytes,
3816        token_store: Arc<dyn TokenStore>,
3817        server_name: String,
3818    },
3819    Server {
3820        server_config: Arc<ServerConfig>,
3821    },
3822}
3823
3824impl ConnectionSide {
3825    fn remote_may_migrate(&self) -> bool {
3826        match self {
3827            Self::Server { server_config } => server_config.migration,
3828            Self::Client { .. } => false,
3829        }
3830    }
3831
3832    fn is_client(&self) -> bool {
3833        self.side().is_client()
3834    }
3835
3836    fn is_server(&self) -> bool {
3837        self.side().is_server()
3838    }
3839
3840    fn side(&self) -> Side {
3841        match *self {
3842            Self::Client { .. } => Side::Client,
3843            Self::Server { .. } => Side::Server,
3844        }
3845    }
3846}
3847
3848impl From<SideArgs> for ConnectionSide {
3849    fn from(side: SideArgs) -> Self {
3850        match side {
3851            SideArgs::Client {
3852                token_store,
3853                server_name,
3854            } => Self::Client {
3855                token: token_store.take(&server_name).unwrap_or_default(),
3856                token_store,
3857                server_name,
3858            },
3859            SideArgs::Server {
3860                server_config,
3861                pref_addr_cid: _,
3862                path_validated: _,
3863            } => Self::Server { server_config },
3864        }
3865    }
3866}
3867
3868/// Parameters to `Connection::new` specific to it being client-side or server-side
3869pub(crate) enum SideArgs {
3870    Client {
3871        token_store: Arc<dyn TokenStore>,
3872        server_name: String,
3873    },
3874    Server {
3875        server_config: Arc<ServerConfig>,
3876        pref_addr_cid: Option<ConnectionId>,
3877        path_validated: bool,
3878    },
3879}
3880
3881impl SideArgs {
3882    pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> {
3883        match *self {
3884            Self::Client { .. } => None,
3885            Self::Server { pref_addr_cid, .. } => pref_addr_cid,
3886        }
3887    }
3888
3889    pub(crate) fn path_validated(&self) -> bool {
3890        match *self {
3891            Self::Client { .. } => true,
3892            Self::Server { path_validated, .. } => path_validated,
3893        }
3894    }
3895
3896    pub(crate) fn side(&self) -> Side {
3897        match *self {
3898            Self::Client { .. } => Side::Client,
3899            Self::Server { .. } => Side::Server,
3900        }
3901    }
3902}
3903
3904/// Reasons why a connection might be lost
3905#[derive(Debug, Error, Clone, PartialEq, Eq)]
3906pub enum ConnectionError {
3907    /// The peer doesn't implement any supported version
3908    #[error("peer doesn't implement any supported version")]
3909    VersionMismatch,
3910    /// The peer violated the QUIC specification as understood by this implementation
3911    #[error(transparent)]
3912    TransportError(#[from] TransportError),
3913    /// The peer's QUIC stack aborted the connection automatically
3914    #[error("aborted by peer: {0}")]
3915    ConnectionClosed(frame::ConnectionClose),
3916    /// The peer closed the connection
3917    #[error("closed by peer: {0}")]
3918    ApplicationClosed(frame::ApplicationClose),
3919    /// The peer is unable to continue processing this connection, usually due to having restarted
3920    #[error("reset by peer")]
3921    Reset,
3922    /// Communication with the peer has lapsed for longer than the negotiated idle timeout
3923    ///
3924    /// If neither side is sending keep-alives, a connection will time out after a long enough idle
3925    /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`]
3926    /// and [`TransportConfig::keep_alive_interval()`].
3927    #[error("timed out")]
3928    TimedOut,
3929    /// The local application closed the connection
3930    #[error("closed")]
3931    LocallyClosed,
3932    /// The connection could not be created because not enough of the CID space is available
3933    ///
3934    /// Try using longer connection IDs.
3935    #[error("CIDs exhausted")]
3936    CidsExhausted,
3937}
3938
3939impl From<Close> for ConnectionError {
3940    fn from(x: Close) -> Self {
3941        match x {
3942            Close::Connection(reason) => Self::ConnectionClosed(reason),
3943            Close::Application(reason) => Self::ApplicationClosed(reason),
3944        }
3945    }
3946}
3947
3948// For compatibility with API consumers
3949impl From<ConnectionError> for io::Error {
3950    fn from(x: ConnectionError) -> Self {
3951        use ConnectionError::*;
3952        let kind = match x {
3953            TimedOut => io::ErrorKind::TimedOut,
3954            Reset => io::ErrorKind::ConnectionReset,
3955            ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted,
3956            TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => {
3957                io::ErrorKind::Other
3958            }
3959        };
3960        Self::new(kind, x)
3961    }
3962}
3963
3964#[allow(unreachable_pub)] // fuzzing only
3965#[derive(Clone)]
3966pub enum State {
3967    Handshake(state::Handshake),
3968    Established,
3969    Closed(state::Closed),
3970    Draining,
3971    /// Waiting for application to call close so we can dispose of the resources
3972    Drained,
3973}
3974
3975impl State {
3976    fn closed<R: Into<Close>>(reason: R) -> Self {
3977        Self::Closed(state::Closed {
3978            reason: reason.into(),
3979        })
3980    }
3981
3982    fn is_handshake(&self) -> bool {
3983        matches!(*self, Self::Handshake(_))
3984    }
3985
3986    fn is_established(&self) -> bool {
3987        matches!(*self, Self::Established)
3988    }
3989
3990    fn is_closed(&self) -> bool {
3991        matches!(*self, Self::Closed(_) | Self::Draining | Self::Drained)
3992    }
3993
3994    fn is_drained(&self) -> bool {
3995        matches!(*self, Self::Drained)
3996    }
3997}
3998
3999mod state {
4000    use super::*;
4001
4002    #[allow(unreachable_pub)] // fuzzing only
4003    #[derive(Clone)]
4004    pub struct Handshake {
4005        /// Whether the remote CID has been set by the peer yet
4006        ///
4007        /// Always set for servers
4008        pub(super) rem_cid_set: bool,
4009        /// Stateless retry token received in the first Initial by a server.
4010        ///
4011        /// Must be present in every Initial. Always empty for clients.
4012        pub(super) expected_token: Bytes,
4013        /// First cryptographic message
4014        ///
4015        /// Only set for clients
4016        pub(super) client_hello: Option<Bytes>,
4017    }
4018
4019    #[allow(unreachable_pub)] // fuzzing only
4020    #[derive(Clone)]
4021    pub struct Closed {
4022        pub(super) reason: Close,
4023    }
4024}
4025
4026/// Events of interest to the application
4027#[derive(Debug)]
4028pub enum Event {
4029    /// The connection's handshake data is ready
4030    HandshakeDataReady,
4031    /// The connection was successfully established
4032    Connected,
4033    /// The connection was lost
4034    ///
4035    /// Emitted if the peer closes the connection or an error is encountered.
4036    ConnectionLost {
4037        /// Reason that the connection was closed
4038        reason: ConnectionError,
4039    },
4040    /// Stream events
4041    Stream(StreamEvent),
4042    /// One or more application datagrams have been received
4043    DatagramReceived,
4044    /// One or more application datagrams have been sent after blocking
4045    DatagramsUnblocked,
4046}
4047
4048fn get_max_ack_delay(params: &TransportParameters) -> Duration {
4049    Duration::from_micros(params.max_ack_delay.0 * 1000)
4050}
4051
4052// Prevents overflow and improves behavior in extreme circumstances
4053const MAX_BACKOFF_EXPONENT: u32 = 16;
4054
4055/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag
4056///
4057/// This must be at least as large as the header for a well-formed empty packet to be coalesced,
4058/// plus some space for frames. We only care about handshake headers because short header packets
4059/// necessarily have smaller headers, and initial packets are only ever the first packet in a
4060/// datagram (because we coalesce in ascending packet space order and the only reason to split a
4061/// packet is when packet space changes).
4062const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32;
4063
4064/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header
4065///
4066/// Excludes packet-type-specific fields such as packet number or Initial token
4067// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid +
4068// scid len + scid + length + pn
4069const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize =
4070    1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4;
4071
4072/// Perform key updates this many packets before the AEAD confidentiality limit.
4073///
4074/// Chosen arbitrarily, intended to be large enough to prevent spurious connection loss.
4075const KEY_UPDATE_MARGIN: u64 = 10_000;
4076
4077#[derive(Default)]
4078struct SentFrames {
4079    retransmits: ThinRetransmits,
4080    largest_acked: Option<u64>,
4081    stream_frames: StreamMetaVec,
4082    /// Whether the packet contains non-retransmittable frames (like datagrams)
4083    non_retransmits: bool,
4084    requires_padding: bool,
4085}
4086
4087impl SentFrames {
4088    /// Returns whether the packet contains only ACKs
4089    fn is_ack_only(&self, streams: &StreamsState) -> bool {
4090        self.largest_acked.is_some()
4091            && !self.non_retransmits
4092            && self.stream_frames.is_empty()
4093            && self.retransmits.is_empty(streams)
4094    }
4095}
4096
4097/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters.
4098///
4099/// According to the definition of max_idle_timeout, a value of `0` means the timeout is disabled; see <https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.4.1.>
4100///
4101/// According to the negotiation procedure, either the minimum of the timeouts or one specified is used as the negotiated value; see <https://www.rfc-editor.org/rfc/rfc9000#section-10.1-2.>
4102///
4103/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout.
4104fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> {
4105    match (x, y) {
4106        (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None,
4107        (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)),
4108        (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)),
4109        (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)),
4110    }
4111}
4112
4113#[cfg(test)]
4114mod tests {
4115    use super::*;
4116
4117    #[cfg(feature = "rustls-ring")]
4118    #[test]
4119    fn large_initial_token_leaves_room_for_close() {
4120        let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
4121        let mut roots = rustls::RootCertStore::empty();
4122        roots.add(cert.cert.der().clone()).unwrap();
4123        let config = crate::ClientConfig::with_root_certificates(Arc::new(roots)).unwrap();
4124        // With 40 bytes of header overhead, a 16-byte tag, and a 35-byte ACK,
4125        // a 1084-byte token leaves exactly ConnectionClose::SIZE_BOUND bytes.
4126        for (token_len, ack_fits) in [
4127            (1083, true),
4128            (1084, true),
4129            (1085, false),
4130            (1100, false),
4131            // Exactly enough frame space for CONNECTION_CLOSE alone.
4132            (1119, false),
4133        ] {
4134            config
4135                .token_store
4136                .insert("localhost", vec![0; token_len].into());
4137            let mut endpoint =
4138                crate::Endpoint::new(Arc::new(EndpointConfig::default()), None, true, None);
4139            let now = Instant::now();
4140            let (_, mut conn) = endpoint
4141                .connect(
4142                    now,
4143                    config.clone(),
4144                    "[::1]:4433".parse().unwrap(),
4145                    "localhost",
4146                )
4147                .unwrap();
4148            let keys = conn
4149                .crypto
4150                .initial_keys(&conn.initial_dst_cid, Side::Server);
4151            let space = &mut conn.spaces[SpaceId::Initial];
4152            for pn in (0..32).step_by(2) {
4153                space.pending_acks.insert_one(pn, now);
4154                space.dedup.insert(pn);
4155                space
4156                    .pending_acks
4157                    .packet_received(now, pn, true, &space.dedup);
4158            }
4159            conn.close(now, 0u32.into(), Bytes::new());
4160            let mut buf = Vec::new();
4161            assert!(conn.poll_transmit(now, 1, &mut buf).is_some());
4162            assert!(buf.len() <= 1200);
4163            assert!(!conn.close);
4164
4165            let (packet, rest) = PartialDecode::new(
4166                buf.as_slice().into(),
4167                &FixedLengthConnectionIdParser::new(0),
4168                crate::DEFAULT_SUPPORTED_VERSIONS,
4169                false,
4170            )
4171            .unwrap();
4172            assert!(rest.is_none());
4173            let mut packet = packet.finish(Some(&*keys.header.remote)).unwrap();
4174            assert_eq!(packet.header_data.len(), 40 + token_len);
4175            keys.packet
4176                .remote
4177                .decrypt(0, &packet.header_data, &mut packet.payload)
4178                .unwrap();
4179            let mut frames = frame::Iter::new(packet.payload.freeze())
4180                .unwrap()
4181                .map(Result::unwrap)
4182                .filter(|frame| !matches!(frame, Frame::Padding));
4183            if ack_fits {
4184                assert!(
4185                    matches!(frames.next(), Some(Frame::Ack(_))),
4186                    "token {token_len}"
4187                );
4188            }
4189            assert!(
4190                matches!(
4191                    frames.next(),
4192                    Some(Frame::Close(Close::Connection(frame::ConnectionClose {
4193                        error_code: TransportErrorCode::APPLICATION_ERROR,
4194                        ..
4195                    })))
4196                ),
4197                "token {token_len}"
4198            );
4199            assert!(frames.next().is_none());
4200        }
4201    }
4202
4203    #[test]
4204    fn negotiate_max_idle_timeout_commutative() {
4205        let test_params = [
4206            (None, None, None),
4207            (None, Some(VarInt(0)), None),
4208            (None, Some(VarInt(2)), Some(Duration::from_millis(2))),
4209            (Some(VarInt(0)), Some(VarInt(0)), None),
4210            (
4211                Some(VarInt(2)),
4212                Some(VarInt(0)),
4213                Some(Duration::from_millis(2)),
4214            ),
4215            (
4216                Some(VarInt(1)),
4217                Some(VarInt(4)),
4218                Some(Duration::from_millis(1)),
4219            ),
4220        ];
4221
4222        for (left, right, result) in test_params {
4223            assert_eq!(negotiate_max_idle_timeout(left, right), result);
4224            assert_eq!(negotiate_max_idle_timeout(right, left), result);
4225        }
4226    }
4227}