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
94pub struct Connection {
134 endpoint_config: Arc<EndpointConfig>,
135 config: Arc<TransportConfig>,
136 rng: StdRng,
137 crypto: Box<dyn crypto::Session>,
138 handshake_cid: ConnectionId,
140 rem_handshake_cid: ConnectionId,
142 local_ip: Option<IpAddr>,
145 path: PathData,
146 path_counter: u64,
150 allow_mtud: bool,
152 prev_path: Option<(ConnectionId, PathData)>,
153 state: State,
154 side: ConnectionSide,
155 zero_rtt_enabled: bool,
157 zero_rtt_crypto: Option<ZeroRttCrypto>,
159 key_phase: bool,
160 key_phase_size: u64,
162 peer_params: TransportParameters,
164 orig_rem_cid: ConnectionId,
166 initial_dst_cid: ConnectionId,
168 retry_src_cid: Option<ConnectionId>,
171 events: VecDeque<Event>,
172 endpoint_events: VecDeque<EndpointEventInner>,
173 spin_enabled: bool,
175 spin: bool,
177 spaces: [PacketSpace; 3],
179 highest_space: SpaceId,
181 prev_crypto: Option<PrevCrypto>,
183 next_crypto: Option<KeyPair<Box<dyn PacketKey>>>,
188 accepted_0rtt: bool,
189 permit_idle_reset: bool,
191 idle_timeout: Option<Duration>,
193 next_bundled_ack_time: Option<Instant>,
200 timers: TimerTable,
201 authentication_failures: u64,
203 error: Option<ConnectionError>,
205 packet_number_filter: PacketNumberFilter,
207
208 path_responses: PathResponses,
213 close: bool,
214
215 ack_frequency: AckFrequencyState,
219
220 pto_count: u32,
225
226 receiving_ecn: bool,
231 total_authed_packets: u64,
233 app_limited: bool,
236
237 streams: StreamsState,
238 rem_cids: CidQueue,
240 local_cid_state: CidState,
242 datagrams: DatagramState,
244 stats: ConnectionStats,
246 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 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 this.write_crypto();
373 this.init_0rtt();
374 }
375 this
376 }
377
378 #[must_use]
386 pub fn poll_timeout(&mut self) -> Option<Instant> {
387 self.timers.next_timeout()
388 }
389
390 #[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 #[must_use]
414 pub fn poll_endpoint_events(&mut self) -> Option<EndpointEvent> {
415 self.endpoint_events.pop_front().map(EndpointEvent)
416 }
417
418 #[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 #[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 #[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 #[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 let mut datagram_start = 0;
476 let mut segment_size = usize::from(self.path.current_mtu());
477 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 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 let close = match self.state {
493 State::Drained => {
494 self.app_limited = true;
495 return None;
496 }
497 State::Draining | State::Closed(_) => {
498 if !self.close {
501 self.app_limited = true;
502 return None;
503 }
504 true
505 }
506 _ => false,
507 };
508
509 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 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 let mut space_idx = 0;
532 let spaces = [SpaceId::Initial, SpaceId::Handshake, SpaceId::Data];
533 while space_idx < spaces.len() {
536 let space_id = spaces[space_idx];
537 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 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 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 if num_datagrams >= max_datagrams {
586 break;
588 }
589
590 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 if ack_eliciting && self.spaces[space_id].loss_probes == 0 {
607 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 trace!("blocked by congestion control");
622 continue;
623 }
624
625 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 trace!("blocked by pacing");
639 break;
640 }
641 }
642
643 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 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 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 segment_size = buf.len();
693 buf_capacity = buf.len();
696
697 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 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 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 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 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 if self.spaces[SpaceId::Initial].crypto.is_some()
762 && space_id == SpaceId::Handshake
763 && self.side.is_client()
764 {
765 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 pad_datagram |=
792 space_id == SpaceId::Initial && (self.side.is_client() || ack_eliciting);
793
794 if close {
795 trace!("sending CONNECTION_CLOSE");
796 if !self.spaces[space_id].pending_acks.ranges().is_empty() {
801 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 self.close = false;
843 break;
845 } else {
846 space_idx += 1;
850 continue;
851 }
852 }
853
854 if space_id == SpaceId::Data && num_datagrams == 1 {
857 if let Some((token, remote)) = self.path_responses.pop_off_path(self.path.remote) {
858 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 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 sent_frames = Some(sent);
913
914 }
917
918 if let Some(mut builder) = builder_storage {
920 if pad_datagram {
921 builder.pad_to(min_mtu);
922 }
923
924 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 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 buf.write(frame::FrameType::PING);
973 self.stats.frame_tx.ping += 1;
974
975 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 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 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 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 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 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 fn next_bundled_ack_delay(&self) -> Duration {
1110 self.path.rtt.get() + self.ack_frequency.peer_max_ack_delay + TIMER_GRANULARITY
1111 }
1112
1113 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 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 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 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 if self.timers.get(Timer::PushNewCid).is_none_or(|x| x <= now) {
1175 self.reset_cid_retirement();
1176 }
1177 }
1178 }
1179 }
1180
1181 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 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 self.spaces[SpaceId::Data]
1248 .pending_acks
1249 .on_max_ack_delay_timeout()
1250 }
1251 }
1252 }
1253 }
1254
1255 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 pub fn datagrams(&mut self) -> Datagrams<'_> {
1285 Datagrams { conn: self }
1286 }
1287
1288 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 pub fn ping(&mut self) {
1303 self.spaces[self.highest_space].ping_pending = true;
1304 }
1305
1306 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 debug!("ignoring redundant forced key update");
1318 return;
1319 }
1320 self.update_keys(None, false);
1321 }
1322
1323 #[doc(hidden)]
1325 #[deprecated]
1326 pub fn initiate_key_update(&mut self) {
1327 self.force_key_update();
1328 }
1329
1330 pub fn crypto_session(&self) -> &dyn crypto::Session {
1332 &*self.crypto
1333 }
1334
1335 pub fn is_handshaking(&self) -> bool {
1340 self.state.is_handshake()
1341 }
1342
1343 pub fn is_closed(&self) -> bool {
1351 self.state.is_closed()
1352 }
1353
1354 pub fn is_drained(&self) -> bool {
1359 self.state.is_drained()
1360 }
1361
1362 pub fn accepted_0rtt(&self) -> bool {
1366 self.accepted_0rtt
1367 }
1368
1369 pub fn has_0rtt(&self) -> bool {
1371 self.zero_rtt_enabled
1372 }
1373
1374 pub fn has_pending_retransmits(&self) -> bool {
1376 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams)
1377 }
1378
1379 pub fn side(&self) -> Side {
1381 self.side.side()
1382 }
1383
1384 pub fn remote_address(&self) -> SocketAddr {
1386 self.path.remote
1387 }
1388
1389 pub fn local_ip(&self) -> Option<IpAddr> {
1399 self.local_ip
1400 }
1401
1402 pub fn rtt(&self) -> Duration {
1404 self.path.rtt.get()
1405 }
1406
1407 pub fn min_rtt(&self) -> Duration {
1409 self.path.rtt.min()
1410 }
1411
1412 pub fn congestion_state(&self) -> &dyn Controller {
1414 self.path.congestion.as_ref()
1415 }
1416
1417 pub fn path_changed(&mut self, now: Instant) {
1428 self.path.reset(now, &self.config);
1429 self.datagrams().drop_oversized();
1430 }
1431
1432 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) {
1437 self.streams.set_max_concurrent(dir, count);
1438 let pending = &mut self.spaces[SpaceId::Data].pending;
1441 self.streams.queue_max_stream_id(pending);
1442 }
1443
1444 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 {
1450 self.streams.max_concurrent(dir)
1451 }
1452
1453 pub fn set_send_window(&mut self, send_window: u64) {
1455 self.streams.set_send_window(send_window);
1456 }
1457
1458 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 space.largest_acked_packet_sent = info.time_sent;
1483 }
1484 true
1485 } else {
1486 false
1487 }
1488 };
1489
1490 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 self.spaces[space].pending_acks.subtract_below(acked);
1513 }
1514 ack_eliciting_acked |= info.ack_eliciting;
1515
1516 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 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 self.detect_lost_packets(now, space, true);
1557
1558 if self.peer_completed_address_validation() {
1559 self.pto_count = 0;
1560 }
1561
1562 if self.path.sending_ecn {
1564 if let Some(ecn) = ack.ecn {
1565 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 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 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 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 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 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 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 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 0 => {
1681 debug_assert!(!self.peer_completed_address_validation());
1682 1
1683 }
1684 _ => 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 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 persistent_congestion_start = None;
1719 }
1720
1721 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_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 Some(start) if info.time_sent - start > congestion_period => {
1738 in_persistent_congestion = true;
1739 }
1740 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 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(); 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 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 if let Some(packet) = lost_mtu_probe {
1818 let info = self.spaces[SpaceId::Data].take(packet).unwrap(); 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 if self.is_handshaking() {
1852 return result;
1853 }
1854 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 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 return;
1889 }
1890
1891 if let Some((loss_time, _)) = self.loss_time_and_space() {
1892 self.timers.set(Timer::LossDetection, loss_time);
1894 return;
1895 }
1896
1897 if self.path.anti_amplification_blocked(1) {
1898 self.timers.stop(Timer::LossDetection);
1900 return;
1901 }
1902
1903 if self.path.in_flight.ack_eliciting == 0 && self.peer_completed_address_validation() {
1904 self.timers.stop(Timer::LossDetection);
1907 return;
1908 }
1909
1910 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 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 self.discard_space(now, SpaceId::Initial);
1959 }
1960 if self.zero_rtt_crypto.is_some() && is_1rtt {
1961 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 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 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 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 SpaceId::Handshake
2108 };
2109 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 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 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 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 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 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 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 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 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 self.timers.stop(Timer::Close);
2420 }
2421
2422 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 || !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 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); 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 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 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 self.spaces[SpaceId::Data].pending = Retransmits::default();
2591
2592 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 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 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 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 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 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 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 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 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 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 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 continue;
2990 }
2991
2992 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 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 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 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 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 if prev.challenge.is_none() {
3092 prev.challenge = Some(self.rng.random());
3093 prev.challenge_pending = true;
3094 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 pub fn local_address_changed(&mut self) {
3107 self.update_rem_cid();
3108 self.ping();
3109 }
3110
3111 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 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 fn issue_first_cids(&mut self, now: Instant) {
3137 if self.local_cid_state.cid_len() == 0 {
3138 return;
3139 }
3140
3141 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 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 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 self.stats.frame_tx.handshake_done =
3174 self.stats.frame_tx.handshake_done.saturating_add(1);
3175 }
3176
3177 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 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 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 if mem::replace(&mut space.pending.ack_frequency, false) {
3208 let sequence_number = self.ack_frequency.next_sequence_number();
3209
3210 let config = self.config.ack_frequency_config.as_ref().unwrap();
3212
3213 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 if buf.len() + 9 < max_size && space_id == SpaceId::Data {
3238 if let Some(token) = self.path.challenge {
3240 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 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 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 let max_crypto_data_size = max_size
3275 - buf.len()
3276 - 1 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) })
3278 - 2; 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 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 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 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 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 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 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 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 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 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 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 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 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(¶ms);
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(¶ms);
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 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() .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 pub(crate) fn immediate_ack(&mut self) {
3610 self.spaces[self.highest_space].immediate_ack_pending = true;
3611 }
3612
3613 #[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 #[cfg(test)]
3653 pub(crate) fn bytes_in_flight(&self) -> u64 {
3654 self.path.in_flight.bytes
3655 }
3656
3657 #[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 #[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 #[cfg(test)]
3679 pub(crate) fn using_ecn(&self) -> bool {
3680 self.path.sending_ecn
3681 }
3682
3683 #[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 #[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 #[cfg(test)]
3705 pub(crate) fn active_rem_cid_seq(&self) -> u64 {
3706 self.rem_cids.active_seq()
3707 }
3708
3709 #[cfg(test)]
3711 pub(crate) fn path_mtu(&self) -> u16 {
3712 self.path.current_mtu()
3713 }
3714
3715 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 fn remove_in_flight(&mut self, packet: &SentPacket) {
3731 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 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 pub fn current_mtu(&self) -> u16 {
3754 self.path.current_mtu()
3755 }
3756
3757 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 None => 4,
3772 };
3773
3774 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 key.map_or(16, |x| x.tag_len())
3787 }
3788
3789 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
3811enum ConnectionSide {
3813 Client {
3814 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
3868pub(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#[derive(Debug, Error, Clone, PartialEq, Eq)]
3906pub enum ConnectionError {
3907 #[error("peer doesn't implement any supported version")]
3909 VersionMismatch,
3910 #[error(transparent)]
3912 TransportError(#[from] TransportError),
3913 #[error("aborted by peer: {0}")]
3915 ConnectionClosed(frame::ConnectionClose),
3916 #[error("closed by peer: {0}")]
3918 ApplicationClosed(frame::ApplicationClose),
3919 #[error("reset by peer")]
3921 Reset,
3922 #[error("timed out")]
3928 TimedOut,
3929 #[error("closed")]
3931 LocallyClosed,
3932 #[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
3948impl 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)] #[derive(Clone)]
3966pub enum State {
3967 Handshake(state::Handshake),
3968 Established,
3969 Closed(state::Closed),
3970 Draining,
3971 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)] #[derive(Clone)]
4004 pub struct Handshake {
4005 pub(super) rem_cid_set: bool,
4009 pub(super) expected_token: Bytes,
4013 pub(super) client_hello: Option<Bytes>,
4017 }
4018
4019 #[allow(unreachable_pub)] #[derive(Clone)]
4021 pub struct Closed {
4022 pub(super) reason: Close,
4023 }
4024}
4025
4026#[derive(Debug)]
4028pub enum Event {
4029 HandshakeDataReady,
4031 Connected,
4033 ConnectionLost {
4037 reason: ConnectionError,
4039 },
4040 Stream(StreamEvent),
4042 DatagramReceived,
4044 DatagramsUnblocked,
4046}
4047
4048fn get_max_ack_delay(params: &TransportParameters) -> Duration {
4049 Duration::from_micros(params.max_ack_delay.0 * 1000)
4050}
4051
4052const MAX_BACKOFF_EXPONENT: u32 = 16;
4054
4055const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32;
4063
4064const 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
4072const 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 non_retransmits: bool,
4084 requires_padding: bool,
4085}
4086
4087impl SentFrames {
4088 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
4097fn 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 for (token_len, ack_fits) in [
4127 (1083, true),
4128 (1084, true),
4129 (1085, false),
4130 (1100, false),
4131 (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}