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::{Rng, SeedableRng, rngs::StdRng};
14use thiserror::Error;
15use tracing::{debug, error, trace, trace_span, warn};
16
17use crate::{
18 Dir, Duration, EndpointConfig, Frame, INITIAL_MTU, 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 timers: TimerTable,
194 authentication_failures: u64,
196 error: Option<ConnectionError>,
198 packet_number_filter: PacketNumberFilter,
200
201 path_responses: PathResponses,
206 close: bool,
207
208 ack_frequency: AckFrequencyState,
212
213 pto_count: u32,
218
219 receiving_ecn: bool,
224 total_authed_packets: u64,
226 app_limited: bool,
229
230 streams: StreamsState,
231 rem_cids: CidQueue,
233 local_cid_state: CidState,
235 datagrams: DatagramState,
237 stats: ConnectionStats,
239 version: u32,
241}
242
243impl Connection {
244 pub(crate) fn new(
245 endpoint_config: Arc<EndpointConfig>,
246 config: Arc<TransportConfig>,
247 init_cid: ConnectionId,
248 loc_cid: ConnectionId,
249 rem_cid: ConnectionId,
250 remote: SocketAddr,
251 local_ip: Option<IpAddr>,
252 crypto: Box<dyn crypto::Session>,
253 cid_gen: &dyn ConnectionIdGenerator,
254 now: Instant,
255 version: u32,
256 allow_mtud: bool,
257 rng_seed: [u8; 32],
258 side_args: SideArgs,
259 ) -> Self {
260 let pref_addr_cid = side_args.pref_addr_cid();
261 let path_validated = side_args.path_validated();
262 let connection_side = ConnectionSide::from(side_args);
263 let side = connection_side.side();
264 let initial_space = PacketSpace {
265 crypto: Some(crypto.initial_keys(&init_cid, side)),
266 ..PacketSpace::new(now)
267 };
268 let state = State::Handshake(state::Handshake {
269 rem_cid_set: side.is_server(),
270 expected_token: Bytes::new(),
271 client_hello: None,
272 });
273 let mut rng = StdRng::from_seed(rng_seed);
274 let mut this = Self {
275 endpoint_config,
276 crypto,
277 handshake_cid: loc_cid,
278 rem_handshake_cid: rem_cid,
279 local_cid_state: CidState::new(
280 cid_gen.cid_len(),
281 cid_gen.cid_lifetime(),
282 now,
283 if pref_addr_cid.is_some() { 2 } else { 1 },
284 ),
285 path: PathData::new(remote, allow_mtud, None, 0, now, &config),
286 path_counter: 0,
287 allow_mtud,
288 local_ip,
289 prev_path: None,
290 state,
291 side: connection_side,
292 zero_rtt_enabled: false,
293 zero_rtt_crypto: None,
294 key_phase: false,
295 key_phase_size: rng.random_range(10..1000),
302 peer_params: TransportParameters::default(),
303 orig_rem_cid: rem_cid,
304 initial_dst_cid: init_cid,
305 retry_src_cid: None,
306 events: VecDeque::new(),
307 endpoint_events: VecDeque::new(),
308 spin_enabled: config.allow_spin && rng.random_ratio(7, 8),
309 spin: false,
310 spaces: [initial_space, PacketSpace::new(now), PacketSpace::new(now)],
311 highest_space: SpaceId::Initial,
312 prev_crypto: None,
313 next_crypto: None,
314 accepted_0rtt: false,
315 permit_idle_reset: true,
316 idle_timeout: match config.max_idle_timeout {
317 None | Some(VarInt(0)) => None,
318 Some(dur) => Some(Duration::from_millis(dur.0)),
319 },
320 timers: TimerTable::default(),
321 authentication_failures: 0,
322 error: None,
323 #[cfg(test)]
324 packet_number_filter: match config.deterministic_packet_numbers {
325 false => PacketNumberFilter::new(&mut rng),
326 true => PacketNumberFilter::disabled(),
327 },
328 #[cfg(not(test))]
329 packet_number_filter: PacketNumberFilter::new(&mut rng),
330
331 path_responses: PathResponses::default(),
332 close: false,
333
334 ack_frequency: AckFrequencyState::new(get_max_ack_delay(
335 &TransportParameters::default(),
336 )),
337
338 pto_count: 0,
339
340 app_limited: false,
341 receiving_ecn: false,
342 total_authed_packets: 0,
343
344 streams: StreamsState::new(
345 side,
346 config.max_concurrent_uni_streams,
347 config.max_concurrent_bidi_streams,
348 config.send_window,
349 config.receive_window,
350 config.stream_receive_window,
351 ),
352 datagrams: DatagramState::default(),
353 config,
354 rem_cids: CidQueue::new(rem_cid),
355 rng,
356 stats: ConnectionStats::default(),
357 version,
358 };
359 if path_validated {
360 this.on_path_validated();
361 }
362 if side.is_client() {
363 this.write_crypto();
365 this.init_0rtt();
366 }
367 this
368 }
369
370 #[must_use]
378 pub fn poll_timeout(&mut self) -> Option<Instant> {
379 self.timers.next_timeout()
380 }
381
382 #[must_use]
388 pub fn poll(&mut self) -> Option<Event> {
389 if let Some(x) = self.events.pop_front() {
390 return Some(x);
391 }
392
393 if let Some(event) = self.streams.poll() {
394 return Some(Event::Stream(event));
395 }
396
397 if let Some(err) = self.error.take() {
398 return Some(Event::ConnectionLost { reason: err });
399 }
400
401 None
402 }
403
404 #[must_use]
406 pub fn poll_endpoint_events(&mut self) -> Option<EndpointEvent> {
407 self.endpoint_events.pop_front().map(EndpointEvent)
408 }
409
410 #[must_use]
412 pub fn streams(&mut self) -> Streams<'_> {
413 Streams {
414 state: &mut self.streams,
415 conn_state: &self.state,
416 }
417 }
418
419 #[must_use]
421 pub fn recv_stream(&mut self, id: StreamId) -> RecvStream<'_> {
422 assert!(id.dir() == Dir::Bi || id.initiator() != self.side.side());
423 RecvStream {
424 id,
425 state: &mut self.streams,
426 pending: &mut self.spaces[SpaceId::Data].pending,
427 }
428 }
429
430 #[must_use]
432 pub fn send_stream(&mut self, id: StreamId) -> SendStream<'_> {
433 assert!(id.dir() == Dir::Bi || id.initiator() == self.side.side());
434 SendStream {
435 id,
436 state: &mut self.streams,
437 pending: &mut self.spaces[SpaceId::Data].pending,
438 conn_state: &self.state,
439 }
440 }
441
442 #[must_use]
452 pub fn poll_transmit(
453 &mut self,
454 now: Instant,
455 max_datagrams: usize,
456 buf: &mut Vec<u8>,
457 ) -> Option<Transmit> {
458 assert!(max_datagrams != 0);
459 let max_datagrams = match self.config.enable_segmentation_offload {
460 false => 1,
461 true => max_datagrams,
462 };
463
464 let mut num_datagrams = 0;
465 let mut datagram_start = 0;
468 let mut segment_size = usize::from(self.path.current_mtu());
469
470 if let Some(challenge) = self.send_path_challenge(now, buf) {
471 return Some(challenge);
472 }
473
474 for space in SpaceId::iter() {
476 let request_immediate_ack =
477 space == SpaceId::Data && self.peer_supports_ack_frequency();
478 self.spaces[space].maybe_queue_probe(request_immediate_ack, &self.streams);
479 }
480
481 let close = match self.state {
483 State::Drained => {
484 self.app_limited = true;
485 return None;
486 }
487 State::Draining | State::Closed(_) => {
488 if !self.close {
491 self.app_limited = true;
492 return None;
493 }
494 true
495 }
496 _ => false,
497 };
498
499 if let Some(config) = &self.config.ack_frequency_config {
501 self.spaces[SpaceId::Data].pending.ack_frequency = self
502 .ack_frequency
503 .should_send_ack_frequency(self.path.rtt.get(), config, &self.peer_params)
504 && self.highest_space == SpaceId::Data
505 && self.peer_supports_ack_frequency();
506 }
507
508 let mut buf_capacity = 0;
512
513 let mut coalesce = true;
514 let mut builder_storage: Option<PacketBuilder> = None;
515 let mut sent_frames = None;
516 let mut pad_datagram = false;
517 let mut pad_datagram_to_mtu = false;
518 let mut congestion_blocked = false;
519
520 let mut space_idx = 0;
522 let spaces = [SpaceId::Initial, SpaceId::Handshake, SpaceId::Data];
523 while space_idx < spaces.len() {
526 let space_id = spaces[space_idx];
527 let pn = self.packet_number_filter.peek(&self.spaces[SpaceId::Data]);
534 let frame_space_1rtt =
535 segment_size.saturating_sub(self.predict_1rtt_overhead(Some(pn)));
536
537 let can_send = self.space_can_send(space_id, frame_space_1rtt);
539 if can_send.is_empty() && (!close || self.spaces[space_id].crypto.is_none()) {
540 space_idx += 1;
541 continue;
542 }
543
544 let mut ack_eliciting = !self.spaces[space_id].pending.is_empty(&self.streams)
545 || self.spaces[space_id].ping_pending
546 || self.spaces[space_id].immediate_ack_pending;
547 if space_id == SpaceId::Data {
548 ack_eliciting |= self.can_send_1rtt(frame_space_1rtt);
549 }
550
551 pad_datagram_to_mtu |= space_id == SpaceId::Data && self.config.pad_to_mtu;
552
553 let buf_end = if let Some(builder) = &builder_storage {
557 buf.len().max(builder.min_size) + builder.tag_len
558 } else {
559 buf.len()
560 };
561
562 let tag_len = if let Some(ref crypto) = self.spaces[space_id].crypto {
563 crypto.packet.local.tag_len()
564 } else if space_id == SpaceId::Data {
565 self.zero_rtt_crypto.as_ref().expect(
566 "sending packets in the application data space requires known 0-RTT or 1-RTT keys",
567 ).packet.tag_len()
568 } else {
569 unreachable!("tried to send {:?} packet without keys", space_id)
570 };
571 if !coalesce || buf_capacity - buf_end < MIN_PACKET_SPACE + tag_len {
572 if num_datagrams >= max_datagrams {
576 break;
578 }
579
580 if self
587 .path
588 .anti_amplification_blocked(segment_size as u64 * (num_datagrams as u64) + 1)
589 {
590 trace!("blocked by anti-amplification");
591 break;
592 }
593
594 if ack_eliciting && self.spaces[space_id].loss_probes == 0 {
597 let untracked_bytes = if let Some(builder) = &builder_storage {
599 buf_capacity - builder.partial_encode.start
600 } else {
601 0
602 } as u64;
603 debug_assert!(untracked_bytes <= segment_size as u64);
604
605 let bytes_to_send = segment_size as u64 + untracked_bytes;
606 if self.path.in_flight.bytes + bytes_to_send >= self.path.congestion.window() {
607 space_idx += 1;
608 congestion_blocked = true;
609 trace!("blocked by congestion control");
612 continue;
613 }
614
615 let smoothed_rtt = self.path.rtt.get();
617 if let Some(delay) = self.path.pacing.delay(
618 smoothed_rtt,
619 bytes_to_send,
620 self.path.current_mtu(),
621 self.path.congestion.window(),
622 now,
623 ) {
624 self.timers.set(Timer::Pacing, delay);
625 congestion_blocked = true;
626 trace!("blocked by pacing");
629 break;
630 }
631 }
632
633 if let Some(mut builder) = builder_storage.take() {
635 if pad_datagram {
636 builder.pad_to(MIN_INITIAL_SIZE);
637 }
638
639 if num_datagrams > 1 || pad_datagram_to_mtu {
640 const MAX_PADDING: usize = 16;
653 let packet_len_unpadded = cmp::max(builder.min_size, buf.len())
654 - datagram_start
655 + builder.tag_len;
656 if (packet_len_unpadded + MAX_PADDING < segment_size
657 && !pad_datagram_to_mtu)
658 || datagram_start + segment_size > buf_capacity
659 {
660 trace!(
661 "GSO truncated by demand for {} padding bytes or loss probe",
662 segment_size - packet_len_unpadded
663 );
664 builder_storage = Some(builder);
665 break;
666 }
667
668 builder.pad_to(segment_size as u16);
671 }
672
673 builder.finish_and_track(now, self, sent_frames.take(), buf);
674
675 if num_datagrams == 1 {
676 segment_size = buf.len();
683 buf_capacity = buf.len();
686
687 if space_id == SpaceId::Data {
694 let frame_space_1rtt =
695 segment_size.saturating_sub(self.predict_1rtt_overhead(Some(pn)));
696 if self.space_can_send(space_id, frame_space_1rtt).is_empty() {
697 break;
698 }
699 }
700 }
701 }
702
703 let next_datagram_size_limit = match self.spaces[space_id].loss_probes {
705 0 => segment_size,
706 _ => {
707 self.spaces[space_id].loss_probes -= 1;
708 std::cmp::min(segment_size, usize::from(INITIAL_MTU))
712 }
713 };
714 buf_capacity += next_datagram_size_limit;
715 if buf.capacity() < buf_capacity {
716 buf.reserve(max_datagrams * segment_size);
725 }
726 num_datagrams += 1;
727 coalesce = true;
728 pad_datagram = false;
729 datagram_start = buf.len();
730
731 debug_assert_eq!(
732 datagram_start % segment_size,
733 0,
734 "datagrams in a GSO batch must be aligned to the segment size"
735 );
736 } else {
737 if let Some(builder) = builder_storage.take() {
741 builder.finish_and_track(now, self, sent_frames.take(), buf);
742 }
743 }
744
745 debug_assert!(buf_capacity - buf.len() >= MIN_PACKET_SPACE);
746
747 if self.spaces[SpaceId::Initial].crypto.is_some()
752 && space_id == SpaceId::Handshake
753 && self.side.is_client()
754 {
755 self.discard_space(now, SpaceId::Initial);
758 }
759 if let Some(ref mut prev) = self.prev_crypto {
760 prev.update_unacked = false;
761 }
762
763 debug_assert!(
764 builder_storage.is_none() && sent_frames.is_none(),
765 "Previous packet must have been finished"
766 );
767
768 let builder = builder_storage.insert(PacketBuilder::new(
769 now,
770 space_id,
771 self.rem_cids.active(),
772 buf,
773 buf_capacity,
774 datagram_start,
775 ack_eliciting,
776 self,
777 )?);
778 coalesce = coalesce && !builder.short_header;
779
780 pad_datagram |=
782 space_id == SpaceId::Initial && (self.side.is_client() || ack_eliciting);
783
784 if close {
785 trace!("sending CONNECTION_CLOSE");
786 if !self.spaces[space_id].pending_acks.ranges().is_empty() {
791 Self::populate_acks(
792 now,
793 self.receiving_ecn,
794 &mut SentFrames::default(),
795 &mut self.spaces[space_id],
796 buf,
797 &mut self.stats,
798 );
799 }
800
801 debug_assert!(
805 buf.len() + frame::ConnectionClose::SIZE_BOUND < builder.max_size,
806 "ACKs should leave space for ConnectionClose"
807 );
808 if buf.len() + frame::ConnectionClose::SIZE_BOUND < builder.max_size {
809 let max_frame_size = builder.max_size - buf.len();
810 match self.state {
811 State::Closed(state::Closed { ref reason }) => {
812 if space_id == SpaceId::Data || reason.is_transport_layer() {
813 reason.encode(buf, max_frame_size)
814 } else {
815 frame::ConnectionClose {
816 error_code: TransportErrorCode::APPLICATION_ERROR,
817 frame_type: None,
818 reason: Bytes::new(),
819 }
820 .encode(buf, max_frame_size)
821 }
822 }
823 State::Draining => frame::ConnectionClose {
824 error_code: TransportErrorCode::NO_ERROR,
825 frame_type: None,
826 reason: Bytes::new(),
827 }
828 .encode(buf, max_frame_size),
829 _ => unreachable!(
830 "tried to make a close packet when the connection wasn't closed"
831 ),
832 }
833 }
834 if space_id == self.highest_space {
835 self.close = false;
837 break;
839 } else {
840 space_idx += 1;
844 continue;
845 }
846 }
847
848 if space_id == SpaceId::Data && num_datagrams == 1 {
851 if let Some((token, remote)) = self.path_responses.pop_off_path(self.path.remote) {
852 let mut builder = builder_storage.take().unwrap();
855 trace!("PATH_RESPONSE {:08x} (off-path)", token);
856 buf.write(frame::FrameType::PATH_RESPONSE);
857 buf.write(token);
858 self.stats.frame_tx.path_response += 1;
859 builder.pad_to(MIN_INITIAL_SIZE);
860 builder.finish_and_track(
861 now,
862 self,
863 Some(SentFrames {
864 non_retransmits: true,
865 ..SentFrames::default()
866 }),
867 buf,
868 );
869 self.stats.udp_tx.on_sent(1, buf.len());
870 return Some(Transmit {
871 destination: remote,
872 size: buf.len(),
873 ecn: None,
874 segment_size: None,
875 src_ip: self.local_ip,
876 });
877 }
878 }
879
880 let sent =
881 self.populate_packet(now, space_id, buf, builder.max_size, builder.exact_number);
882
883 debug_assert!(
890 !(sent.is_ack_only(&self.streams)
891 && !can_send.acks
892 && can_send.other
893 && (buf_capacity - builder.datagram_start) == self.path.current_mtu() as usize
894 && self.datagrams.outgoing.is_empty()),
895 "SendableFrames was {can_send:?}, but only ACKs have been written"
896 );
897 pad_datagram |= sent.requires_padding;
898
899 if sent.largest_acked.is_some() {
900 self.spaces[space_id].pending_acks.acks_sent();
901 self.timers.stop(Timer::MaxAckDelay);
902 }
903
904 sent_frames = Some(sent);
906
907 }
910
911 if let Some(mut builder) = builder_storage {
913 if pad_datagram {
914 builder.pad_to(MIN_INITIAL_SIZE);
915 }
916
917 if pad_datagram_to_mtu && buf_capacity >= datagram_start + segment_size {
923 builder.pad_to(segment_size as u16);
924 }
925
926 let last_packet_number = builder.exact_number;
927 builder.finish_and_track(now, self, sent_frames, buf);
928 self.path
929 .congestion
930 .on_sent(now, buf.len() as u64, last_packet_number);
931
932 self.config.qlog_sink.emit_recovery_metrics(
933 self.pto_count,
934 &mut self.path,
935 now,
936 self.orig_rem_cid,
937 );
938 }
939
940 self.app_limited = buf.is_empty() && !congestion_blocked;
941
942 if buf.is_empty() && self.state.is_established() {
944 let space_id = SpaceId::Data;
945 let probe_size = self
946 .path
947 .mtud
948 .poll_transmit(now, self.packet_number_filter.peek(&self.spaces[space_id]))?;
949
950 let buf_capacity = probe_size as usize;
951 buf.reserve(buf_capacity);
952
953 let mut builder = PacketBuilder::new(
954 now,
955 space_id,
956 self.rem_cids.active(),
957 buf,
958 buf_capacity,
959 0,
960 true,
961 self,
962 )?;
963
964 buf.write(frame::FrameType::PING);
966 self.stats.frame_tx.ping += 1;
967
968 if self.peer_supports_ack_frequency() {
970 buf.write(frame::FrameType::IMMEDIATE_ACK);
971 self.stats.frame_tx.immediate_ack += 1;
972 }
973
974 builder.pad_to(probe_size);
975 let sent_frames = SentFrames {
976 non_retransmits: true,
977 ..Default::default()
978 };
979 builder.finish_and_track(now, self, Some(sent_frames), buf);
980
981 self.stats.path.sent_plpmtud_probes += 1;
982 num_datagrams = 1;
983
984 trace!(?probe_size, "writing MTUD probe");
985 }
986
987 if buf.is_empty() {
988 return None;
989 }
990
991 trace!("sending {} bytes in {} datagrams", buf.len(), num_datagrams);
992 self.path.total_sent = self.path.total_sent.saturating_add(buf.len() as u64);
993
994 self.stats.udp_tx.on_sent(num_datagrams as u64, buf.len());
995
996 Some(Transmit {
997 destination: self.path.remote,
998 size: buf.len(),
999 ecn: if self.path.sending_ecn {
1000 Some(EcnCodepoint::Ect0)
1001 } else {
1002 None
1003 },
1004 segment_size: match num_datagrams {
1005 1 => None,
1006 _ => Some(segment_size),
1007 },
1008 src_ip: self.local_ip,
1009 })
1010 }
1011
1012 fn send_path_challenge(&mut self, now: Instant, buf: &mut Vec<u8>) -> Option<Transmit> {
1014 let (prev_cid, prev_path) = self.prev_path.as_mut()?;
1015 if !prev_path.challenge_pending {
1016 return None;
1017 }
1018 prev_path.challenge_pending = false;
1019 let token = prev_path
1020 .challenge
1021 .expect("previous path challenge pending without token");
1022 let destination = prev_path.remote;
1023 debug_assert_eq!(
1024 self.highest_space,
1025 SpaceId::Data,
1026 "PATH_CHALLENGE queued without 1-RTT keys"
1027 );
1028 buf.reserve(MIN_INITIAL_SIZE as usize);
1029
1030 let buf_capacity = buf.capacity();
1031
1032 let mut builder = PacketBuilder::new(
1038 now,
1039 SpaceId::Data,
1040 *prev_cid,
1041 buf,
1042 buf_capacity,
1043 0,
1044 false,
1045 self,
1046 )?;
1047 trace!("validating previous path with PATH_CHALLENGE {:08x}", token);
1048 buf.write(frame::FrameType::PATH_CHALLENGE);
1049 buf.write(token);
1050 self.stats.frame_tx.path_challenge += 1;
1051
1052 builder.pad_to(MIN_INITIAL_SIZE);
1057
1058 builder.finish(self, now, buf);
1059 self.stats.udp_tx.on_sent(1, buf.len());
1060
1061 Some(Transmit {
1062 destination,
1063 size: buf.len(),
1064 ecn: None,
1065 segment_size: None,
1066 src_ip: self.local_ip,
1067 })
1068 }
1069
1070 fn space_can_send(&self, space_id: SpaceId, frame_space_1rtt: usize) -> SendableFrames {
1072 if self.spaces[space_id].crypto.is_none()
1073 && (space_id != SpaceId::Data
1074 || self.zero_rtt_crypto.is_none()
1075 || self.side.is_server())
1076 {
1077 return SendableFrames::empty();
1079 }
1080 let mut can_send = self.spaces[space_id].can_send(&self.streams);
1081 if space_id == SpaceId::Data {
1082 can_send.other |= self.can_send_1rtt(frame_space_1rtt);
1083 }
1084 can_send
1085 }
1086
1087 pub fn handle_event(&mut self, event: ConnectionEvent) {
1093 use ConnectionEventInner::*;
1094 match event.0 {
1095 Datagram(DatagramConnectionEvent {
1096 now,
1097 remote,
1098 ecn,
1099 first_decode,
1100 remaining,
1101 }) => {
1102 if remote != self.path.remote && !self.side.remote_may_migrate() {
1106 trace!("discarding packet from unrecognized peer {}", remote);
1107 return;
1108 }
1109
1110 let was_anti_amplification_blocked = self.path.anti_amplification_blocked(1);
1111
1112 self.stats.udp_rx.datagrams += 1;
1113 self.stats.udp_rx.bytes += first_decode.len() as u64;
1114 let data_len = first_decode.len();
1115
1116 self.handle_decode(now, remote, ecn, first_decode);
1117 self.path.total_recvd = self.path.total_recvd.saturating_add(data_len as u64);
1122
1123 if let Some(data) = remaining {
1124 self.stats.udp_rx.bytes += data.len() as u64;
1125 self.handle_coalesced(now, remote, ecn, data);
1126 }
1127
1128 self.config.qlog_sink.emit_recovery_metrics(
1129 self.pto_count,
1130 &mut self.path,
1131 now,
1132 self.orig_rem_cid,
1133 );
1134
1135 if was_anti_amplification_blocked {
1136 self.set_loss_detection_timer(now);
1140 }
1141 }
1142 NewIdentifiers(ids, now) => {
1143 self.local_cid_state.new_cids(&ids, now);
1144 ids.into_iter().rev().for_each(|frame| {
1145 self.spaces[SpaceId::Data].pending.new_cids.push(frame);
1146 });
1147 if self.timers.get(Timer::PushNewCid).is_none_or(|x| x <= now) {
1149 self.reset_cid_retirement();
1150 }
1151 }
1152 }
1153 }
1154
1155 pub fn handle_timeout(&mut self, now: Instant) {
1165 for &timer in &Timer::VALUES {
1166 if !self.timers.is_expired(timer, now) {
1167 continue;
1168 }
1169 self.timers.stop(timer);
1170 trace!(timer = ?timer, "timeout");
1171 match timer {
1172 Timer::Close => {
1173 self.state = State::Drained;
1174 self.endpoint_events.push_back(EndpointEventInner::Drained);
1175 }
1176 Timer::Idle => {
1177 self.kill(ConnectionError::TimedOut);
1178 }
1179 Timer::KeepAlive => {
1180 trace!("sending keep-alive");
1181 self.ping();
1182 }
1183 Timer::LossDetection => {
1184 self.on_loss_detection_timeout(now);
1185
1186 self.config.qlog_sink.emit_recovery_metrics(
1187 self.pto_count,
1188 &mut self.path,
1189 now,
1190 self.orig_rem_cid,
1191 );
1192 }
1193 Timer::KeyDiscard => {
1194 self.zero_rtt_crypto = None;
1195 self.prev_crypto = None;
1196 }
1197 Timer::PathValidation => {
1198 debug!("path validation failed");
1199 if let Some((_, prev)) = self.prev_path.take() {
1200 self.path = prev;
1201 }
1202 self.path.challenge = None;
1203 self.path.challenge_pending = false;
1204 }
1205 Timer::Pacing => trace!("pacing timer expired"),
1206 Timer::PushNewCid => {
1207 let num_new_cid = self.local_cid_state.on_cid_timeout().into();
1209 if !self.state.is_closed() {
1210 trace!(
1211 "push a new cid to peer RETIRE_PRIOR_TO field {}",
1212 self.local_cid_state.retire_prior_to()
1213 );
1214 self.endpoint_events
1215 .push_back(EndpointEventInner::NeedIdentifiers(now, num_new_cid));
1216 }
1217 }
1218 Timer::MaxAckDelay => {
1219 trace!("max ack delay reached");
1220 self.spaces[SpaceId::Data]
1222 .pending_acks
1223 .on_max_ack_delay_timeout()
1224 }
1225 }
1226 }
1227 }
1228
1229 pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) {
1241 self.close_inner(
1242 now,
1243 Close::Application(frame::ApplicationClose { error_code, reason }),
1244 )
1245 }
1246
1247 fn close_inner(&mut self, now: Instant, reason: Close) {
1248 let was_closed = self.state.is_closed();
1249 if !was_closed {
1250 self.close_common();
1251 self.set_close_timer(now);
1252 self.close = true;
1253 self.state = State::Closed(state::Closed { reason });
1254 }
1255 }
1256
1257 pub fn datagrams(&mut self) -> Datagrams<'_> {
1259 Datagrams { conn: self }
1260 }
1261
1262 pub fn stats(&self) -> ConnectionStats {
1264 let mut stats = self.stats;
1265 stats.path.rtt = self.path.rtt.get();
1266 stats.path.cwnd = self.path.congestion.window();
1267 stats.path.current_mtu = self.path.mtud.current_mtu();
1268
1269 stats
1270 }
1271
1272 pub fn ping(&mut self) {
1276 self.spaces[self.highest_space].ping_pending = true;
1277 }
1278
1279 pub fn force_key_update(&mut self) {
1283 if !self.state.is_established() {
1284 debug!("ignoring forced key update in illegal state");
1285 return;
1286 }
1287 if self.prev_crypto.is_some() {
1288 debug!("ignoring redundant forced key update");
1291 return;
1292 }
1293 self.update_keys(None, false);
1294 }
1295
1296 #[doc(hidden)]
1298 #[deprecated]
1299 pub fn initiate_key_update(&mut self) {
1300 self.force_key_update();
1301 }
1302
1303 pub fn crypto_session(&self) -> &dyn crypto::Session {
1305 &*self.crypto
1306 }
1307
1308 pub fn is_handshaking(&self) -> bool {
1313 self.state.is_handshake()
1314 }
1315
1316 pub fn is_closed(&self) -> bool {
1324 self.state.is_closed()
1325 }
1326
1327 pub fn is_drained(&self) -> bool {
1332 self.state.is_drained()
1333 }
1334
1335 pub fn accepted_0rtt(&self) -> bool {
1339 self.accepted_0rtt
1340 }
1341
1342 pub fn has_0rtt(&self) -> bool {
1344 self.zero_rtt_enabled
1345 }
1346
1347 pub fn has_pending_retransmits(&self) -> bool {
1349 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams)
1350 }
1351
1352 pub fn side(&self) -> Side {
1354 self.side.side()
1355 }
1356
1357 pub fn remote_address(&self) -> SocketAddr {
1359 self.path.remote
1360 }
1361
1362 pub fn local_ip(&self) -> Option<IpAddr> {
1372 self.local_ip
1373 }
1374
1375 pub fn rtt(&self) -> Duration {
1377 self.path.rtt.get()
1378 }
1379
1380 pub fn congestion_state(&self) -> &dyn Controller {
1382 self.path.congestion.as_ref()
1383 }
1384
1385 pub fn path_changed(&mut self, now: Instant) {
1396 self.path.reset(now, &self.config);
1397 }
1398
1399 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) {
1404 self.streams.set_max_concurrent(dir, count);
1405 let pending = &mut self.spaces[SpaceId::Data].pending;
1408 self.streams.queue_max_stream_id(pending);
1409 }
1410
1411 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 {
1417 self.streams.max_concurrent(dir)
1418 }
1419
1420 pub fn set_send_window(&mut self, send_window: u64) {
1422 self.streams.set_send_window(send_window);
1423 }
1424
1425 pub fn set_receive_window(&mut self, receive_window: VarInt) {
1427 if self.streams.set_receive_window(receive_window) {
1428 self.spaces[SpaceId::Data].pending.max_data = true;
1429 }
1430 }
1431
1432 fn on_ack_received(
1433 &mut self,
1434 now: Instant,
1435 space: SpaceId,
1436 ack: frame::Ack,
1437 ) -> Result<(), TransportError> {
1438 if ack.largest >= self.spaces[space].next_packet_number {
1439 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked"));
1440 }
1441 let new_largest = {
1442 let space = &mut self.spaces[space];
1443 if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) {
1444 space.largest_acked_packet = Some(ack.largest);
1445 if let Some(info) = space.sent_packets.get(&ack.largest) {
1446 space.largest_acked_packet_sent = info.time_sent;
1450 }
1451 true
1452 } else {
1453 false
1454 }
1455 };
1456
1457 let mut newly_acked = ArrayRangeSet::new();
1459 for range in ack.iter() {
1460 self.packet_number_filter.check_ack(space, range.clone())?;
1461 for (&pn, _) in self.spaces[space].sent_packets.range(range) {
1462 newly_acked.insert_one(pn);
1463 }
1464 }
1465
1466 if newly_acked.is_empty() {
1467 return Ok(());
1468 }
1469
1470 let mut ack_eliciting_acked = false;
1471 for packet in newly_acked.elts() {
1472 if let Some(info) = self.spaces[space].take(packet) {
1473 if let Some(acked) = info.largest_acked {
1474 self.spaces[space].pending_acks.subtract_below(acked);
1480 }
1481 ack_eliciting_acked |= info.ack_eliciting;
1482
1483 let mtu_updated = self.path.mtud.on_acked(space, packet, info.size);
1485 if mtu_updated {
1486 self.path
1487 .congestion
1488 .on_mtu_update(self.path.mtud.current_mtu());
1489 }
1490
1491 self.ack_frequency.on_acked(packet);
1493
1494 self.on_packet_acked(now, info);
1495 }
1496 }
1497
1498 self.path.congestion.on_end_acks(
1499 now,
1500 self.path.in_flight.bytes,
1501 self.app_limited,
1502 self.spaces[space].largest_acked_packet,
1503 );
1504
1505 if new_largest && ack_eliciting_acked {
1506 let ack_delay = if space != SpaceId::Data {
1507 Duration::from_micros(0)
1508 } else {
1509 cmp::min(
1510 self.ack_frequency.peer_max_ack_delay,
1511 Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0),
1512 )
1513 };
1514 let rtt = now.saturating_duration_since(self.spaces[space].largest_acked_packet_sent);
1515 self.path.rtt.update(ack_delay, rtt);
1516 if self.path.first_packet_after_rtt_sample.is_none() {
1517 self.path.first_packet_after_rtt_sample =
1518 Some((space, self.spaces[space].next_packet_number));
1519 }
1520 }
1521
1522 self.detect_lost_packets(now, space, true);
1524
1525 if self.peer_completed_address_validation() {
1526 self.pto_count = 0;
1527 }
1528
1529 if self.path.sending_ecn {
1531 if let Some(ecn) = ack.ecn {
1532 if new_largest {
1537 let sent = self.spaces[space].largest_acked_packet_sent;
1538 self.process_ecn(now, space, newly_acked.len() as u64, ecn, sent);
1539 }
1540 } else {
1541 debug!("ECN not acknowledged by peer");
1543 self.path.sending_ecn = false;
1544 }
1545 }
1546
1547 self.set_loss_detection_timer(now);
1548 Ok(())
1549 }
1550
1551 fn process_ecn(
1553 &mut self,
1554 now: Instant,
1555 space: SpaceId,
1556 newly_acked: u64,
1557 ecn: frame::EcnCounts,
1558 largest_sent_time: Instant,
1559 ) {
1560 match self.spaces[space].detect_ecn(newly_acked, ecn) {
1561 Err(e) => {
1562 debug!("halting ECN due to verification failure: {}", e);
1563 self.path.sending_ecn = false;
1564 self.spaces[space].ecn_feedback = frame::EcnCounts::ZERO;
1567 }
1568 Ok(false) => {}
1569 Ok(true) => {
1570 self.stats.path.congestion_events += 1;
1571 self.path
1572 .congestion
1573 .on_congestion_event(now, largest_sent_time, false, 0);
1574 }
1575 }
1576 }
1577
1578 fn on_packet_acked(&mut self, now: Instant, info: SentPacket) {
1581 self.remove_in_flight(&info);
1582 if info.ack_eliciting && self.path.challenge.is_none() {
1583 self.path.congestion.on_ack(
1586 now,
1587 info.time_sent,
1588 info.size.into(),
1589 self.app_limited,
1590 &self.path.rtt,
1591 );
1592 }
1593
1594 if let Some(retransmits) = info.retransmits.get() {
1596 for (id, _) in retransmits.reset_stream.iter() {
1597 self.streams.reset_acked(*id);
1598 }
1599 }
1600
1601 for frame in info.stream_frames {
1602 self.streams.received_ack_of(frame);
1603 }
1604 }
1605
1606 fn set_key_discard_timer(&mut self, now: Instant, space: SpaceId) {
1607 let start = if self.zero_rtt_crypto.is_some() {
1608 now
1609 } else {
1610 self.prev_crypto
1611 .as_ref()
1612 .expect("no previous keys")
1613 .end_packet
1614 .as_ref()
1615 .expect("update not acknowledged yet")
1616 .1
1617 };
1618 self.timers
1619 .set(Timer::KeyDiscard, start + self.pto(space) * 3);
1620 }
1621
1622 fn on_loss_detection_timeout(&mut self, now: Instant) {
1623 if let Some((_, pn_space)) = self.loss_time_and_space() {
1624 self.detect_lost_packets(now, pn_space, false);
1626 self.set_loss_detection_timer(now);
1627 return;
1628 }
1629
1630 let (_, space) = match self.pto_time_and_space(now) {
1631 Some(x) => x,
1632 None => {
1633 error!("PTO expired while unset");
1634 return;
1635 }
1636 };
1637 trace!(
1638 in_flight = self.path.in_flight.bytes,
1639 count = self.pto_count,
1640 ?space,
1641 "PTO fired"
1642 );
1643
1644 let count = match self.path.in_flight.ack_eliciting {
1645 0 => {
1648 debug_assert!(!self.peer_completed_address_validation());
1649 1
1650 }
1651 _ => 2,
1653 };
1654 self.spaces[space].loss_probes = self.spaces[space].loss_probes.saturating_add(count);
1655 self.pto_count = self.pto_count.saturating_add(1);
1656 self.set_loss_detection_timer(now);
1657 }
1658
1659 fn detect_lost_packets(&mut self, now: Instant, pn_space: SpaceId, due_to_ack: bool) {
1660 let mut lost_packets = Vec::<u64>::new();
1661 let mut lost_mtu_probe = None;
1662 let in_flight_mtu_probe = self.path.mtud.in_flight_mtu_probe();
1663 let rtt = self.path.rtt.conservative();
1664 let loss_delay = cmp::max(rtt.mul_f32(self.config.time_threshold), TIMER_GRANULARITY);
1665
1666 let largest_acked_packet = self.spaces[pn_space].largest_acked_packet.unwrap();
1667 let packet_threshold = self.config.packet_threshold as u64;
1668 let mut size_of_lost_packets = 0u64;
1669
1670 let congestion_period =
1674 self.pto(SpaceId::Data) * self.config.persistent_congestion_threshold;
1675 let mut persistent_congestion_start: Option<Instant> = None;
1676 let mut prev_packet = None;
1677 let mut in_persistent_congestion = false;
1678
1679 let space = &mut self.spaces[pn_space];
1680 space.loss_time = None;
1681
1682 for (&packet, info) in space.sent_packets.range(0..largest_acked_packet) {
1683 if prev_packet != Some(packet.wrapping_sub(1)) {
1684 persistent_congestion_start = None;
1686 }
1687
1688 let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay;
1692 if packet_too_old || largest_acked_packet >= packet + packet_threshold {
1693 if Some(packet) == in_flight_mtu_probe {
1694 lost_mtu_probe = in_flight_mtu_probe;
1697 } else {
1698 lost_packets.push(packet);
1699 size_of_lost_packets += info.size as u64;
1700 if info.ack_eliciting && due_to_ack {
1701 match persistent_congestion_start {
1702 Some(start) if info.time_sent - start > congestion_period => {
1705 in_persistent_congestion = true;
1706 }
1707 None if self
1709 .path
1710 .first_packet_after_rtt_sample
1711 .is_some_and(|x| x < (pn_space, packet)) =>
1712 {
1713 persistent_congestion_start = Some(info.time_sent);
1714 }
1715 _ => {}
1716 }
1717 }
1718 }
1719 } else {
1720 let next_loss_time = info.time_sent + loss_delay;
1721 space.loss_time = Some(
1722 space
1723 .loss_time
1724 .map_or(next_loss_time, |x| cmp::min(x, next_loss_time)),
1725 );
1726 persistent_congestion_start = None;
1727 }
1728
1729 prev_packet = Some(packet);
1730 }
1731
1732 if let Some(largest_lost) = lost_packets.last().cloned() {
1734 let old_bytes_in_flight = self.path.in_flight.bytes;
1735 let largest_lost_sent = self.spaces[pn_space].sent_packets[&largest_lost].time_sent;
1736 self.stats.path.lost_packets += lost_packets.len() as u64;
1737 self.stats.path.lost_bytes += size_of_lost_packets;
1738 trace!(
1739 "packets lost: {:?}, bytes lost: {}",
1740 lost_packets, size_of_lost_packets
1741 );
1742
1743 for &packet in &lost_packets {
1744 let info = self.spaces[pn_space].take(packet).unwrap(); self.config.qlog_sink.emit_packet_lost(
1746 packet,
1747 &info,
1748 loss_delay,
1749 pn_space,
1750 now,
1751 self.orig_rem_cid,
1752 );
1753 self.remove_in_flight(&info);
1754 for frame in info.stream_frames {
1755 self.streams.retransmit(frame);
1756 }
1757 self.spaces[pn_space].pending |= info.retransmits;
1758 self.path.mtud.on_non_probe_lost(packet, info.size);
1759 }
1760
1761 if self.path.mtud.black_hole_detected(now) {
1762 self.stats.path.black_holes_detected += 1;
1763 self.path
1764 .congestion
1765 .on_mtu_update(self.path.mtud.current_mtu());
1766 if let Some(max_datagram_size) = self.datagrams().max_size() {
1767 self.datagrams.drop_oversized(max_datagram_size);
1768 }
1769 }
1770
1771 let lost_ack_eliciting = old_bytes_in_flight != self.path.in_flight.bytes;
1773
1774 if lost_ack_eliciting {
1775 self.stats.path.congestion_events += 1;
1776 self.path.congestion.on_congestion_event(
1777 now,
1778 largest_lost_sent,
1779 in_persistent_congestion,
1780 size_of_lost_packets,
1781 );
1782 }
1783 }
1784
1785 if let Some(packet) = lost_mtu_probe {
1787 let info = self.spaces[SpaceId::Data].take(packet).unwrap(); self.remove_in_flight(&info);
1789 self.path.mtud.on_probe_lost();
1790 self.stats.path.lost_plpmtud_probes += 1;
1791 }
1792 }
1793
1794 fn loss_time_and_space(&self) -> Option<(Instant, SpaceId)> {
1795 SpaceId::iter()
1796 .filter_map(|id| Some((self.spaces[id].loss_time?, id)))
1797 .min_by_key(|&(time, _)| time)
1798 }
1799
1800 fn pto_time_and_space(&self, now: Instant) -> Option<(Instant, SpaceId)> {
1801 let backoff = 2u32.pow(self.pto_count.min(MAX_BACKOFF_EXPONENT));
1802 let mut duration = self.path.rtt.pto_base() * backoff;
1803
1804 if self.path.in_flight.ack_eliciting == 0 {
1805 debug_assert!(!self.peer_completed_address_validation());
1806 let space = match self.highest_space {
1807 SpaceId::Handshake => SpaceId::Handshake,
1808 _ => SpaceId::Initial,
1809 };
1810 return Some((now + duration, space));
1811 }
1812
1813 let mut result = None;
1814 for space in SpaceId::iter() {
1815 if !self.spaces[space].has_in_flight() {
1816 continue;
1817 }
1818 if space == SpaceId::Data {
1819 if self.is_handshaking() {
1821 return result;
1822 }
1823 duration += self.ack_frequency.max_ack_delay_for_pto() * backoff;
1825 }
1826 let last_ack_eliciting = match self.spaces[space].time_of_last_ack_eliciting_packet {
1827 Some(time) => time,
1828 None => continue,
1829 };
1830 let pto = last_ack_eliciting + duration;
1831 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) {
1832 result = Some((pto, space));
1833 }
1834 }
1835 result
1836 }
1837
1838 fn peer_completed_address_validation(&self) -> bool {
1839 if self.side.is_server() || self.state.is_closed() {
1840 return true;
1841 }
1842 self.spaces[SpaceId::Handshake]
1845 .largest_acked_packet
1846 .is_some()
1847 || self.spaces[SpaceId::Data].largest_acked_packet.is_some()
1848 || (self.spaces[SpaceId::Data].crypto.is_some()
1849 && self.spaces[SpaceId::Handshake].crypto.is_none())
1850 }
1851
1852 fn set_loss_detection_timer(&mut self, now: Instant) {
1853 if self.state.is_closed() {
1854 return;
1858 }
1859
1860 if let Some((loss_time, _)) = self.loss_time_and_space() {
1861 self.timers.set(Timer::LossDetection, loss_time);
1863 return;
1864 }
1865
1866 if self.path.anti_amplification_blocked(1) {
1867 self.timers.stop(Timer::LossDetection);
1869 return;
1870 }
1871
1872 if self.path.in_flight.ack_eliciting == 0 && self.peer_completed_address_validation() {
1873 self.timers.stop(Timer::LossDetection);
1876 return;
1877 }
1878
1879 if let Some((timeout, _)) = self.pto_time_and_space(now) {
1882 self.timers.set(Timer::LossDetection, timeout);
1883 } else {
1884 self.timers.stop(Timer::LossDetection);
1885 }
1886 }
1887
1888 fn pto(&self, space: SpaceId) -> Duration {
1890 let max_ack_delay = match space {
1891 SpaceId::Initial | SpaceId::Handshake => Duration::ZERO,
1892 SpaceId::Data => self.ack_frequency.max_ack_delay_for_pto(),
1893 };
1894 self.path.rtt.pto_base() + max_ack_delay
1895 }
1896
1897 fn on_packet_authenticated(
1898 &mut self,
1899 now: Instant,
1900 space_id: SpaceId,
1901 ecn: Option<EcnCodepoint>,
1902 packet: Option<u64>,
1903 spin: bool,
1904 is_1rtt: bool,
1905 ) {
1906 self.total_authed_packets += 1;
1907 self.reset_keep_alive(now);
1908 self.reset_idle_timeout(now, space_id);
1909 self.permit_idle_reset = true;
1910 self.receiving_ecn |= ecn.is_some();
1911 if let Some(x) = ecn {
1912 let space = &mut self.spaces[space_id];
1913 space.ecn_counters += x;
1914
1915 if x.is_ce() {
1916 space.pending_acks.set_immediate_ack_required();
1917 }
1918 }
1919
1920 let packet = match packet {
1921 Some(x) => x,
1922 None => return,
1923 };
1924 if self.side.is_server() {
1925 if self.spaces[SpaceId::Initial].crypto.is_some() && space_id == SpaceId::Handshake {
1926 self.discard_space(now, SpaceId::Initial);
1928 }
1929 if self.zero_rtt_crypto.is_some() && is_1rtt {
1930 self.set_key_discard_timer(now, space_id)
1932 }
1933 }
1934 let space = &mut self.spaces[space_id];
1935 space.pending_acks.insert_one(packet, now);
1936 if packet >= space.rx_packet {
1937 space.rx_packet = packet;
1938 self.spin = self.side.is_client() ^ spin;
1940 }
1941
1942 self.config.qlog_sink.emit_packet_received(
1943 packet,
1944 space_id,
1945 !is_1rtt,
1946 now,
1947 self.orig_rem_cid,
1948 );
1949 }
1950
1951 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceId) {
1952 let timeout = match self.idle_timeout {
1953 None => return,
1954 Some(dur) => dur,
1955 };
1956 if self.state.is_closed() {
1957 self.timers.stop(Timer::Idle);
1958 return;
1959 }
1960 let dt = cmp::max(timeout, 3 * self.pto(space));
1961 self.timers.set(Timer::Idle, now + dt);
1962 }
1963
1964 fn reset_keep_alive(&mut self, now: Instant) {
1965 let interval = match self.config.keep_alive_interval {
1966 Some(x) if self.state.is_established() => x,
1967 _ => return,
1968 };
1969 self.timers.set(Timer::KeepAlive, now + interval);
1970 }
1971
1972 fn reset_cid_retirement(&mut self) {
1973 if let Some(t) = self.local_cid_state.next_timeout() {
1974 self.timers.set(Timer::PushNewCid, t);
1975 }
1976 }
1977
1978 pub(crate) fn handle_first_packet(
1983 &mut self,
1984 now: Instant,
1985 remote: SocketAddr,
1986 ecn: Option<EcnCodepoint>,
1987 packet_number: u64,
1988 packet: InitialPacket,
1989 remaining: Option<BytesMut>,
1990 ) -> Result<(), ConnectionError> {
1991 let span = trace_span!("first recv");
1992 let _guard = span.enter();
1993 debug_assert!(self.side.is_server());
1994 let len = packet.header_data.len() + packet.payload.len();
1995 self.path.total_recvd = len as u64;
1996
1997 match self.state {
1998 State::Handshake(ref mut state) => {
1999 state.expected_token = packet.header.token.clone();
2000 }
2001 _ => unreachable!("first packet must be delivered in Handshake state"),
2002 }
2003
2004 self.on_packet_authenticated(
2005 now,
2006 SpaceId::Initial,
2007 ecn,
2008 Some(packet_number),
2009 false,
2010 false,
2011 );
2012
2013 self.process_decrypted_packet(now, remote, Some(packet_number), packet.into())?;
2014 if let Some(data) = remaining {
2015 self.handle_coalesced(now, remote, ecn, data);
2016 }
2017
2018 self.config.qlog_sink.emit_recovery_metrics(
2019 self.pto_count,
2020 &mut self.path,
2021 now,
2022 self.orig_rem_cid,
2023 );
2024
2025 Ok(())
2026 }
2027
2028 fn init_0rtt(&mut self) {
2029 let (header, packet) = match self.crypto.early_crypto() {
2030 Some(x) => x,
2031 None => return,
2032 };
2033 if self.side.is_client() {
2034 match self.crypto.transport_parameters() {
2035 Ok(params) => {
2036 let params = params
2037 .expect("crypto layer didn't supply transport parameters with ticket");
2038 let params = TransportParameters {
2040 initial_src_cid: None,
2041 original_dst_cid: None,
2042 preferred_address: None,
2043 retry_src_cid: None,
2044 stateless_reset_token: None,
2045 min_ack_delay: None,
2046 ack_delay_exponent: TransportParameters::default().ack_delay_exponent,
2047 max_ack_delay: TransportParameters::default().max_ack_delay,
2048 ..params
2049 };
2050 self.set_peer_params(params);
2051 }
2052 Err(e) => {
2053 error!("session ticket has malformed transport parameters: {}", e);
2054 return;
2055 }
2056 }
2057 }
2058 trace!("0-RTT enabled");
2059 self.zero_rtt_enabled = true;
2060 self.zero_rtt_crypto = Some(ZeroRttCrypto { header, packet });
2061 }
2062
2063 fn read_crypto(
2064 &mut self,
2065 space: SpaceId,
2066 crypto: &frame::Crypto,
2067 payload_len: usize,
2068 ) -> Result<(), TransportError> {
2069 let expected = if !self.state.is_handshake() {
2070 SpaceId::Data
2071 } else if self.highest_space == SpaceId::Initial {
2072 SpaceId::Initial
2073 } else {
2074 SpaceId::Handshake
2077 };
2078 debug_assert!(space <= expected, "received out-of-order CRYPTO data");
2082
2083 let end = crypto.offset + crypto.data.len() as u64;
2084 if space < expected && end > self.spaces[space].crypto_stream.bytes_read() {
2085 warn!(
2086 "received new {:?} CRYPTO data when expecting {:?}",
2087 space, expected
2088 );
2089 return Err(TransportError::PROTOCOL_VIOLATION(
2090 "new data at unexpected encryption level",
2091 ));
2092 }
2093
2094 let space = &mut self.spaces[space];
2095 let max = end.saturating_sub(space.crypto_stream.bytes_read());
2096 if max > self.config.crypto_buffer_size as u64 {
2097 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED(""));
2098 }
2099
2100 space
2101 .crypto_stream
2102 .insert(crypto.offset, crypto.data.clone(), payload_len)
2103 .map_err(|_| TransportError::INTERNAL_ERROR("too many gaps in crypto stream buffer"))?;
2104
2105 while let Some(chunk) = space.crypto_stream.read(usize::MAX, true) {
2106 trace!("consumed {} CRYPTO bytes", chunk.bytes.len());
2107 if self.crypto.read_handshake(&chunk.bytes)? {
2108 self.events.push_back(Event::HandshakeDataReady);
2109 }
2110 }
2111
2112 Ok(())
2113 }
2114
2115 fn write_crypto(&mut self) {
2116 loop {
2117 let space = self.highest_space;
2118 let mut outgoing = Vec::new();
2119 if let Some(crypto) = self.crypto.write_handshake(&mut outgoing) {
2120 match space {
2121 SpaceId::Initial => {
2122 self.upgrade_crypto(SpaceId::Handshake, crypto);
2123 }
2124 SpaceId::Handshake => {
2125 self.upgrade_crypto(SpaceId::Data, crypto);
2126 }
2127 _ => unreachable!("got updated secrets during 1-RTT"),
2128 }
2129 }
2130 if outgoing.is_empty() {
2131 if space == self.highest_space {
2132 break;
2133 } else {
2134 continue;
2136 }
2137 }
2138 let offset = self.spaces[space].crypto_offset;
2139 let outgoing = Bytes::from(outgoing);
2140 if let State::Handshake(ref mut state) = self.state {
2141 if space == SpaceId::Initial && offset == 0 && self.side.is_client() {
2142 state.client_hello = Some(outgoing.clone());
2143 }
2144 }
2145 self.spaces[space].crypto_offset += outgoing.len() as u64;
2146 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space);
2147 self.spaces[space].pending.crypto.push_back(frame::Crypto {
2148 offset,
2149 data: outgoing,
2150 });
2151 }
2152 }
2153
2154 fn upgrade_crypto(&mut self, space: SpaceId, crypto: Keys) {
2156 debug_assert!(
2157 self.spaces[space].crypto.is_none(),
2158 "already reached packet space {space:?}"
2159 );
2160 trace!("{:?} keys ready", space);
2161 if space == SpaceId::Data {
2162 self.next_crypto = Some(
2164 self.crypto
2165 .next_1rtt_keys()
2166 .expect("handshake should be complete"),
2167 );
2168 }
2169
2170 self.spaces[space].crypto = Some(crypto);
2171 debug_assert!(space as usize > self.highest_space as usize);
2172 self.highest_space = space;
2173 if space == SpaceId::Data && self.side.is_client() {
2174 self.zero_rtt_crypto = None;
2176 }
2177 }
2178
2179 fn discard_space(&mut self, now: Instant, space_id: SpaceId) {
2180 debug_assert!(space_id != SpaceId::Data);
2181 trace!("discarding {:?} keys", space_id);
2182 if space_id == SpaceId::Initial {
2183 if let ConnectionSide::Client { token, .. } = &mut self.side {
2185 *token = Bytes::new();
2186 }
2187 }
2188 let space = &mut self.spaces[space_id];
2189 space.crypto = None;
2190 space.time_of_last_ack_eliciting_packet = None;
2191 space.loss_time = None;
2192 let sent_packets = mem::take(&mut space.sent_packets);
2193 for packet in sent_packets.into_values() {
2194 self.remove_in_flight(&packet);
2195 }
2196 self.set_loss_detection_timer(now)
2197 }
2198
2199 fn handle_coalesced(
2200 &mut self,
2201 now: Instant,
2202 remote: SocketAddr,
2203 ecn: Option<EcnCodepoint>,
2204 data: BytesMut,
2205 ) {
2206 self.path.total_recvd = self.path.total_recvd.saturating_add(data.len() as u64);
2207 let mut remaining = Some(data);
2208 while let Some(data) = remaining {
2209 match PartialDecode::new(
2210 data,
2211 &FixedLengthConnectionIdParser::new(self.local_cid_state.cid_len()),
2212 &[self.version],
2213 self.endpoint_config.grease_quic_bit,
2214 ) {
2215 Ok((partial_decode, rest)) => {
2216 remaining = rest;
2217 self.handle_decode(now, remote, ecn, partial_decode);
2218 }
2219 Err(e) => {
2220 trace!("malformed header: {}", e);
2221 return;
2222 }
2223 }
2224 }
2225 }
2226
2227 fn handle_decode(
2228 &mut self,
2229 now: Instant,
2230 remote: SocketAddr,
2231 ecn: Option<EcnCodepoint>,
2232 partial_decode: PartialDecode,
2233 ) {
2234 if let Some(decoded) = packet_crypto::unprotect_header(
2235 partial_decode,
2236 &self.spaces,
2237 self.zero_rtt_crypto.as_ref(),
2238 self.peer_params.stateless_reset_token,
2239 ) {
2240 self.handle_packet(now, remote, ecn, decoded.packet, decoded.stateless_reset);
2241 }
2242 }
2243
2244 fn handle_packet(
2245 &mut self,
2246 now: Instant,
2247 remote: SocketAddr,
2248 ecn: Option<EcnCodepoint>,
2249 packet: Option<Packet>,
2250 stateless_reset: bool,
2251 ) {
2252 self.stats.udp_rx.ios += 1;
2253 if let Some(ref packet) = packet {
2254 trace!(
2255 "got {:?} packet ({} bytes) from {} using id {}",
2256 packet.header.space(),
2257 packet.payload.len() + packet.header_data.len(),
2258 remote,
2259 packet.header.dst_cid(),
2260 );
2261 }
2262
2263 if self.is_handshaking() && remote != self.path.remote {
2264 debug!("discarding packet with unexpected remote during handshake");
2265 return;
2266 }
2267
2268 let was_closed = self.state.is_closed();
2269 let was_drained = self.state.is_drained();
2270
2271 let decrypted = match packet {
2272 None => Err(None),
2273 Some(mut packet) => self
2274 .decrypt_packet(now, &mut packet)
2275 .map(move |number| (packet, number)),
2276 };
2277 let result = match decrypted {
2278 _ if stateless_reset => {
2279 debug!("got stateless reset");
2280 Err(ConnectionError::Reset)
2281 }
2282 Err(Some(e)) => {
2283 warn!("illegal packet: {}", e);
2284 Err(e.into())
2285 }
2286 Err(None) => {
2287 debug!("failed to authenticate packet");
2288 self.authentication_failures += 1;
2289 let integrity_limit = self.spaces[self.highest_space]
2290 .crypto
2291 .as_ref()
2292 .unwrap()
2293 .packet
2294 .local
2295 .integrity_limit();
2296 if self.authentication_failures > integrity_limit {
2297 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into())
2298 } else {
2299 return;
2300 }
2301 }
2302 Ok((packet, number)) => {
2303 let span = match number {
2304 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn),
2305 None => trace_span!("recv", space = ?packet.header.space()),
2306 };
2307 let _guard = span.enter();
2308
2309 let is_duplicate = |n| self.spaces[packet.header.space()].dedup.insert(n);
2310 if number.is_some_and(is_duplicate) {
2311 debug!("discarding possible duplicate packet");
2312 return;
2313 } else if self.state.is_handshake() && packet.header.is_short() {
2314 trace!("dropping short packet during handshake");
2316 return;
2317 } else {
2318 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header {
2319 if let State::Handshake(ref hs) = self.state {
2320 if self.side.is_server() && token != &hs.expected_token {
2321 warn!("discarding Initial with invalid retry token");
2325 return;
2326 }
2327 }
2328 }
2329
2330 if !self.state.is_closed() {
2331 let spin = match packet.header {
2332 Header::Short { spin, .. } => spin,
2333 _ => false,
2334 };
2335 self.on_packet_authenticated(
2336 now,
2337 packet.header.space(),
2338 ecn,
2339 number,
2340 spin,
2341 packet.header.is_1rtt(),
2342 );
2343 }
2344
2345 self.process_decrypted_packet(now, remote, number, packet)
2346 }
2347 }
2348 };
2349
2350 if let Err(conn_err) = result {
2352 self.error = Some(conn_err.clone());
2353 self.state = match conn_err {
2354 ConnectionError::ApplicationClosed(reason) => State::closed(reason),
2355 ConnectionError::ConnectionClosed(reason) => State::closed(reason),
2356 ConnectionError::Reset
2357 | ConnectionError::TransportError(TransportError {
2358 code: TransportErrorCode::AEAD_LIMIT_REACHED,
2359 ..
2360 }) => State::Drained,
2361 ConnectionError::TimedOut => {
2362 unreachable!("timeouts aren't generated by packet processing");
2363 }
2364 ConnectionError::TransportError(err) => {
2365 debug!("closing connection due to transport error: {}", err);
2366 State::closed(err)
2367 }
2368 ConnectionError::VersionMismatch => State::Draining,
2369 ConnectionError::LocallyClosed => {
2370 unreachable!("LocallyClosed isn't generated by packet processing");
2371 }
2372 ConnectionError::CidsExhausted => {
2373 unreachable!("CidsExhausted isn't generated by packet processing");
2374 }
2375 };
2376 }
2377
2378 if !was_closed && self.state.is_closed() {
2379 self.close_common();
2380 if !self.state.is_drained() {
2381 self.set_close_timer(now);
2382 }
2383 }
2384 if !was_drained && self.state.is_drained() {
2385 self.endpoint_events.push_back(EndpointEventInner::Drained);
2386 self.timers.stop(Timer::Close);
2389 }
2390
2391 if let State::Closed(_) = self.state {
2393 self.close = remote == self.path.remote;
2394 }
2395 }
2396
2397 fn process_decrypted_packet(
2398 &mut self,
2399 now: Instant,
2400 remote: SocketAddr,
2401 number: Option<u64>,
2402 packet: Packet,
2403 ) -> Result<(), ConnectionError> {
2404 let state = match self.state {
2405 State::Established => {
2406 match packet.header.space() {
2407 SpaceId::Data => self.process_payload(now, remote, number.unwrap(), packet)?,
2408 _ if packet.header.has_frames() => self.process_early_payload(now, packet)?,
2409 _ => {
2410 trace!("discarding unexpected pre-handshake packet");
2411 }
2412 }
2413 return Ok(());
2414 }
2415 State::Closed(_) => {
2416 for result in frame::Iter::new(packet.payload.freeze())? {
2417 let frame = match result {
2418 Ok(frame) => frame,
2419 Err(err) => {
2420 debug!("frame decoding error: {err:?}");
2421 continue;
2422 }
2423 };
2424
2425 if let Frame::Padding = frame {
2426 continue;
2427 };
2428
2429 self.stats.frame_rx.record(&frame);
2430
2431 if let Frame::Close(_) = frame {
2432 trace!("draining");
2433 self.state = State::Draining;
2434 break;
2435 }
2436 }
2437 return Ok(());
2438 }
2439 State::Draining | State::Drained => return Ok(()),
2440 State::Handshake(ref mut state) => state,
2441 };
2442
2443 match packet.header {
2444 Header::Retry {
2445 src_cid: rem_cid, ..
2446 } => {
2447 if self.side.is_server() {
2448 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into());
2449 }
2450
2451 if self.total_authed_packets > 1
2452 || packet.payload.len() <= 16 || !self.crypto.is_valid_retry(
2454 &self.rem_cids.active(),
2455 &packet.header_data,
2456 &packet.payload,
2457 )
2458 {
2459 trace!("discarding invalid Retry");
2460 return Ok(());
2468 }
2469
2470 trace!("retrying with CID {}", rem_cid);
2471 let client_hello = state.client_hello.take().unwrap();
2472 self.retry_src_cid = Some(rem_cid);
2473 self.rem_cids.update_initial_cid(rem_cid);
2474 self.rem_handshake_cid = rem_cid;
2475
2476 let space = &mut self.spaces[SpaceId::Initial];
2477 if let Some(info) = space.take(0) {
2478 self.on_packet_acked(now, info);
2479 };
2480
2481 self.discard_space(now, SpaceId::Initial); self.spaces[SpaceId::Initial] = PacketSpace {
2483 crypto: Some(self.crypto.initial_keys(&rem_cid, self.side.side())),
2484 next_packet_number: self.spaces[SpaceId::Initial].next_packet_number,
2485 crypto_offset: client_hello.len() as u64,
2486 ..PacketSpace::new(now)
2487 };
2488 self.spaces[SpaceId::Initial]
2489 .pending
2490 .crypto
2491 .push_back(frame::Crypto {
2492 offset: 0,
2493 data: client_hello,
2494 });
2495
2496 let zero_rtt = mem::take(&mut self.spaces[SpaceId::Data].sent_packets);
2498 for info in zero_rtt.into_values() {
2499 self.remove_in_flight(&info);
2500 self.spaces[SpaceId::Data].pending |= info.retransmits;
2501 }
2502 self.streams.retransmit_all_for_0rtt();
2503
2504 let token_len = packet.payload.len() - 16;
2505 let ConnectionSide::Client { ref mut token, .. } = self.side else {
2506 unreachable!("we already short-circuited if we're server");
2507 };
2508 *token = packet.payload.freeze().split_to(token_len);
2509 self.state = State::Handshake(state::Handshake {
2510 expected_token: Bytes::new(),
2511 rem_cid_set: false,
2512 client_hello: None,
2513 });
2514 Ok(())
2515 }
2516 Header::Long {
2517 ty: LongType::Handshake,
2518 src_cid: rem_cid,
2519 ..
2520 } => {
2521 if rem_cid != self.rem_handshake_cid {
2522 debug!(
2523 "discarding packet with mismatched remote CID: {} != {}",
2524 self.rem_handshake_cid, rem_cid
2525 );
2526 return Ok(());
2527 }
2528 self.on_path_validated();
2529
2530 self.process_early_payload(now, packet)?;
2531 if self.state.is_closed() {
2532 return Ok(());
2533 }
2534
2535 if self.crypto.is_handshaking() {
2536 trace!("handshake ongoing");
2537 return Ok(());
2538 }
2539
2540 if self.side.is_client() {
2541 let params =
2543 self.crypto
2544 .transport_parameters()?
2545 .ok_or_else(|| TransportError {
2546 code: TransportErrorCode::crypto(0x6d),
2547 frame: None,
2548 reason: "transport parameters missing".into(),
2549 })?;
2550
2551 if self.has_0rtt() {
2552 if !self.crypto.early_data_accepted().unwrap() {
2553 debug_assert!(self.side.is_client());
2554 debug!("0-RTT rejected");
2555 self.accepted_0rtt = false;
2556 self.streams.zero_rtt_rejected();
2557
2558 self.spaces[SpaceId::Data].pending = Retransmits::default();
2560
2561 let sent_packets =
2563 mem::take(&mut self.spaces[SpaceId::Data].sent_packets);
2564 for packet in sent_packets.into_values() {
2565 self.remove_in_flight(&packet);
2566 }
2567 } else {
2568 self.accepted_0rtt = true;
2569 params.validate_resumption_from(&self.peer_params)?;
2570 }
2571 }
2572 if let Some(token) = params.stateless_reset_token {
2573 self.endpoint_events
2574 .push_back(EndpointEventInner::ResetToken(self.path.remote, token));
2575 }
2576 self.handle_peer_params(params)?;
2577 self.issue_first_cids(now);
2578 } else {
2579 self.spaces[SpaceId::Data].pending.handshake_done = true;
2581 self.discard_space(now, SpaceId::Handshake);
2582 }
2583
2584 self.events.push_back(Event::Connected);
2585 self.state = State::Established;
2586 trace!("established");
2587 Ok(())
2588 }
2589 Header::Initial(InitialHeader {
2590 src_cid: rem_cid, ..
2591 }) => {
2592 if !state.rem_cid_set {
2593 trace!("switching remote CID to {}", rem_cid);
2594 let mut state = state.clone();
2595 self.rem_cids.update_initial_cid(rem_cid);
2596 self.rem_handshake_cid = rem_cid;
2597 self.orig_rem_cid = rem_cid;
2598 state.rem_cid_set = true;
2599 self.state = State::Handshake(state);
2600 } else if rem_cid != self.rem_handshake_cid {
2601 debug!(
2602 "discarding packet with mismatched remote CID: {} != {}",
2603 self.rem_handshake_cid, rem_cid
2604 );
2605 return Ok(());
2606 }
2607
2608 let starting_space = self.highest_space;
2609 self.process_early_payload(now, packet)?;
2610
2611 if self.side.is_server()
2612 && starting_space == SpaceId::Initial
2613 && self.highest_space != SpaceId::Initial
2614 {
2615 let params =
2616 self.crypto
2617 .transport_parameters()?
2618 .ok_or_else(|| TransportError {
2619 code: TransportErrorCode::crypto(0x6d),
2620 frame: None,
2621 reason: "transport parameters missing".into(),
2622 })?;
2623 self.handle_peer_params(params)?;
2624 self.issue_first_cids(now);
2625 self.init_0rtt();
2626 }
2627 Ok(())
2628 }
2629 Header::Long {
2630 ty: LongType::ZeroRtt,
2631 ..
2632 } => {
2633 self.process_payload(now, remote, number.unwrap(), packet)?;
2634 Ok(())
2635 }
2636 Header::VersionNegotiate { .. } => {
2637 if self.total_authed_packets > 1 {
2638 return Ok(());
2639 }
2640 let supported = packet
2641 .payload
2642 .chunks(4)
2643 .any(|x| match <[u8; 4]>::try_from(x) {
2644 Ok(version) => self.version == u32::from_be_bytes(version),
2645 Err(_) => false,
2646 });
2647 if supported {
2648 return Ok(());
2649 }
2650 debug!("remote doesn't support our version");
2651 Err(ConnectionError::VersionMismatch)
2652 }
2653 Header::Short { .. } => unreachable!(
2654 "short packets received during handshake are discarded in handle_packet"
2655 ),
2656 }
2657 }
2658
2659 fn process_early_payload(
2661 &mut self,
2662 now: Instant,
2663 packet: Packet,
2664 ) -> Result<(), TransportError> {
2665 debug_assert_ne!(packet.header.space(), SpaceId::Data);
2666 let payload_len = packet.payload.len();
2667 let mut ack_eliciting = false;
2668 for result in frame::Iter::new(packet.payload.freeze())? {
2669 let frame = result?;
2670 let span = match frame {
2671 Frame::Padding => continue,
2672 _ => Some(trace_span!("frame", ty = %frame.ty())),
2673 };
2674
2675 self.stats.frame_rx.record(&frame);
2676
2677 let _guard = span.as_ref().map(|x| x.enter());
2678 ack_eliciting |= frame.is_ack_eliciting();
2679
2680 match frame {
2682 Frame::Padding | Frame::Ping => {}
2683 Frame::Crypto(frame) => {
2684 self.read_crypto(packet.header.space(), &frame, payload_len)?;
2685 }
2686 Frame::Ack(ack) => {
2687 self.on_ack_received(now, packet.header.space(), ack)?;
2688 }
2689 Frame::Close(reason) => {
2690 self.error = Some(reason.into());
2691 self.state = State::Draining;
2692 return Ok(());
2693 }
2694 _ => {
2695 let mut err =
2696 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake");
2697 err.frame = Some(frame.ty());
2698 return Err(err);
2699 }
2700 }
2701 }
2702
2703 if ack_eliciting {
2704 self.spaces[packet.header.space()]
2706 .pending_acks
2707 .set_immediate_ack_required();
2708 }
2709
2710 self.write_crypto();
2711 Ok(())
2712 }
2713
2714 fn process_payload(
2715 &mut self,
2716 now: Instant,
2717 remote: SocketAddr,
2718 number: u64,
2719 packet: Packet,
2720 ) -> Result<(), TransportError> {
2721 let payload = packet.payload.freeze();
2722 let mut is_probing_packet = true;
2723 let mut close = None;
2724 let payload_len = payload.len();
2725 let mut ack_eliciting = false;
2726 for result in frame::Iter::new(payload)? {
2727 let frame = result?;
2728 let span = match frame {
2729 Frame::Padding => continue,
2730 _ => Some(trace_span!("frame", ty = %frame.ty())),
2731 };
2732
2733 self.stats.frame_rx.record(&frame);
2734 match &frame {
2737 Frame::Crypto(f) => {
2738 trace!(offset = f.offset, len = f.data.len(), "got crypto frame");
2739 }
2740 Frame::Stream(f) => {
2741 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got stream frame");
2742 }
2743 Frame::Datagram(f) => {
2744 trace!(len = f.data.len(), "got datagram frame");
2745 }
2746 f => {
2747 trace!("got frame {:?}", f);
2748 }
2749 }
2750
2751 let _guard = span.as_ref().map(|x| x.enter());
2752 if packet.header.is_0rtt() {
2753 match frame {
2754 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => {
2755 return Err(TransportError::PROTOCOL_VIOLATION(
2756 "illegal frame type in 0-RTT",
2757 ));
2758 }
2759 _ => {}
2760 }
2761 }
2762 ack_eliciting |= frame.is_ack_eliciting();
2763
2764 match frame {
2766 Frame::Padding
2767 | Frame::PathChallenge(_)
2768 | Frame::PathResponse(_)
2769 | Frame::NewConnectionId(_) => {}
2770 _ => {
2771 is_probing_packet = false;
2772 }
2773 }
2774 match frame {
2775 Frame::Crypto(frame) => {
2776 self.read_crypto(SpaceId::Data, &frame, payload_len)?;
2777 }
2778 Frame::Stream(frame) => {
2779 if self.streams.received(frame, payload_len)?.should_transmit() {
2780 self.spaces[SpaceId::Data].pending.max_data = true;
2781 }
2782 }
2783 Frame::Ack(ack) => {
2784 self.on_ack_received(now, SpaceId::Data, ack)?;
2785 }
2786 Frame::Padding | Frame::Ping => {}
2787 Frame::Close(reason) => {
2788 close = Some(reason);
2789 }
2790 Frame::PathChallenge(token) => {
2791 self.path_responses.push(number, token, remote);
2792 if remote == self.path.remote {
2793 match self.peer_supports_ack_frequency() {
2796 true => self.immediate_ack(),
2797 false => self.ping(),
2798 }
2799 }
2800 }
2801 Frame::PathResponse(token) => {
2802 if self.path.challenge == Some(token) && remote == self.path.remote {
2803 trace!("new path validated");
2804 self.timers.stop(Timer::PathValidation);
2805 self.path.challenge = None;
2806 self.path.validated = true;
2807 if let Some((_, ref mut prev_path)) = self.prev_path {
2808 prev_path.challenge = None;
2809 prev_path.challenge_pending = false;
2810 }
2811 } else {
2812 debug!(token, "ignoring invalid PATH_RESPONSE");
2813 }
2814 }
2815 Frame::MaxData(bytes) => {
2816 self.streams.received_max_data(bytes);
2817 }
2818 Frame::MaxStreamData { id, offset } => {
2819 self.streams.received_max_stream_data(id, offset)?;
2820 }
2821 Frame::MaxStreams { dir, count } => {
2822 self.streams.received_max_streams(dir, count)?;
2823 }
2824 Frame::ResetStream(frame) => {
2825 if self.streams.received_reset(frame)?.should_transmit() {
2826 self.spaces[SpaceId::Data].pending.max_data = true;
2827 }
2828 }
2829 Frame::DataBlocked { offset } => {
2830 debug!(offset, "peer claims to be blocked at connection level");
2831 }
2832 Frame::StreamDataBlocked { id, offset } => {
2833 if id.initiator() == self.side.side() && id.dir() == Dir::Uni {
2834 debug!("got STREAM_DATA_BLOCKED on send-only {}", id);
2835 return Err(TransportError::STREAM_STATE_ERROR(
2836 "STREAM_DATA_BLOCKED on send-only stream",
2837 ));
2838 }
2839 debug!(
2840 stream = %id,
2841 offset, "peer claims to be blocked at stream level"
2842 );
2843 }
2844 Frame::StreamsBlocked { dir, limit } => {
2845 if limit > MAX_STREAM_COUNT {
2846 return Err(TransportError::FRAME_ENCODING_ERROR(
2847 "unrepresentable stream limit",
2848 ));
2849 }
2850 debug!(
2851 "peer claims to be blocked opening more than {} {} streams",
2852 limit, dir
2853 );
2854 }
2855 Frame::StopSending(frame::StopSending { id, error_code }) => {
2856 if id.initiator() != self.side.side() {
2857 if id.dir() == Dir::Uni {
2858 debug!("got STOP_SENDING on recv-only {}", id);
2859 return Err(TransportError::STREAM_STATE_ERROR(
2860 "STOP_SENDING on recv-only stream",
2861 ));
2862 }
2863 } else if self.streams.is_local_unopened(id) {
2864 return Err(TransportError::STREAM_STATE_ERROR(
2865 "STOP_SENDING on unopened stream",
2866 ));
2867 }
2868 self.streams.received_stop_sending(id, error_code);
2869 }
2870 Frame::RetireConnectionId { sequence } => {
2871 let allow_more_cids = self
2872 .local_cid_state
2873 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?;
2874 self.endpoint_events
2875 .push_back(EndpointEventInner::RetireConnectionId(
2876 now,
2877 sequence,
2878 allow_more_cids,
2879 ));
2880 }
2881 Frame::NewConnectionId(frame) => {
2882 trace!(
2883 sequence = frame.sequence,
2884 id = %frame.id,
2885 retire_prior_to = frame.retire_prior_to,
2886 );
2887 if self.rem_cids.active().is_empty() {
2888 return Err(TransportError::PROTOCOL_VIOLATION(
2889 "NEW_CONNECTION_ID when CIDs aren't in use",
2890 ));
2891 }
2892 if frame.retire_prior_to > frame.sequence {
2893 return Err(TransportError::PROTOCOL_VIOLATION(
2894 "NEW_CONNECTION_ID retiring unissued CIDs",
2895 ));
2896 }
2897
2898 use crate::cid_queue::InsertError;
2899 match self.rem_cids.insert(frame) {
2900 Ok(None) => {}
2901 Ok(Some((retired, reset_token))) => {
2902 let pending_retired =
2903 &mut self.spaces[SpaceId::Data].pending.retire_cids;
2904 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10;
2907 if (pending_retired.len() as u64)
2910 .saturating_add(retired.end.saturating_sub(retired.start))
2911 > MAX_PENDING_RETIRED_CIDS
2912 {
2913 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR(
2914 "queued too many retired CIDs",
2915 ));
2916 }
2917 pending_retired.extend(retired);
2918 self.set_reset_token(reset_token);
2919 }
2920 Err(InsertError::ExceedsLimit) => {
2921 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR(""));
2922 }
2923 Err(InsertError::Retired) => {
2924 trace!("discarding already-retired");
2925 self.spaces[SpaceId::Data]
2929 .pending
2930 .retire_cids
2931 .push(frame.sequence);
2932 continue;
2933 }
2934 };
2935
2936 if self.side.is_server() && self.rem_cids.active_seq() == 0 {
2937 self.update_rem_cid();
2940 }
2941 }
2942 Frame::NewToken(NewToken { token }) => {
2943 let ConnectionSide::Client {
2944 token_store,
2945 server_name,
2946 ..
2947 } = &self.side
2948 else {
2949 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN"));
2950 };
2951 if token.is_empty() {
2952 return Err(TransportError::FRAME_ENCODING_ERROR("empty token"));
2953 }
2954 trace!("got new token");
2955 token_store.insert(server_name, token);
2956 }
2957 Frame::Datagram(datagram) => {
2958 if self
2959 .datagrams
2960 .received(datagram, &self.config.datagram_receive_buffer_size)?
2961 {
2962 self.events.push_back(Event::DatagramReceived);
2963 }
2964 }
2965 Frame::AckFrequency(ack_frequency) => {
2966 let space = &mut self.spaces[SpaceId::Data];
2968
2969 if !self
2970 .ack_frequency
2971 .ack_frequency_received(&ack_frequency, &mut space.pending_acks)?
2972 {
2973 continue;
2975 }
2976
2977 if let Some(timeout) = space
2980 .pending_acks
2981 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay)
2982 {
2983 self.timers.set(Timer::MaxAckDelay, timeout);
2984 }
2985 }
2986 Frame::ImmediateAck => {
2987 self.spaces[SpaceId::Data]
2989 .pending_acks
2990 .set_immediate_ack_required();
2991 }
2992 Frame::HandshakeDone => {
2993 if self.side.is_server() {
2994 return Err(TransportError::PROTOCOL_VIOLATION(
2995 "client sent HANDSHAKE_DONE",
2996 ));
2997 }
2998 if self.spaces[SpaceId::Handshake].crypto.is_some() {
2999 self.discard_space(now, SpaceId::Handshake);
3000 }
3001 }
3002 }
3003 }
3004
3005 let space = &mut self.spaces[SpaceId::Data];
3006 if space
3007 .pending_acks
3008 .packet_received(now, number, ack_eliciting, &space.dedup)
3009 {
3010 self.timers
3011 .set(Timer::MaxAckDelay, now + self.ack_frequency.max_ack_delay);
3012 }
3013
3014 let pending = &mut self.spaces[SpaceId::Data].pending;
3019 self.streams.queue_max_stream_id(pending);
3020
3021 if let Some(reason) = close {
3022 self.error = Some(reason.into());
3023 self.state = State::Draining;
3024 self.close = true;
3025 }
3026
3027 if remote != self.path.remote
3028 && !is_probing_packet
3029 && number == self.spaces[SpaceId::Data].rx_packet
3030 {
3031 let ConnectionSide::Server { ref server_config } = self.side else {
3032 panic!("packets from unknown remote should be dropped by clients");
3033 };
3034 debug_assert!(
3035 server_config.migration,
3036 "migration-initiating packets should have been dropped immediately"
3037 );
3038 self.migrate(now, remote);
3039 self.update_rem_cid();
3041 self.spin = false;
3042 }
3043
3044 Ok(())
3045 }
3046
3047 fn migrate(&mut self, now: Instant, remote: SocketAddr) {
3048 trace!(%remote, "migration initiated");
3049 self.path_counter = self.path_counter.wrapping_add(1);
3050 let mut new_path = if remote.is_ipv4() && remote.ip() == self.path.remote.ip() {
3054 PathData::from_previous(remote, &self.path, self.path_counter, now)
3055 } else {
3056 let peer_max_udp_payload_size =
3057 u16::try_from(self.peer_params.max_udp_payload_size.into_inner())
3058 .unwrap_or(u16::MAX);
3059 PathData::new(
3060 remote,
3061 self.allow_mtud,
3062 Some(peer_max_udp_payload_size),
3063 self.path_counter,
3064 now,
3065 &self.config,
3066 )
3067 };
3068 new_path.challenge = Some(self.rng.random());
3069 new_path.challenge_pending = true;
3070 let prev_pto = self.pto(SpaceId::Data);
3071
3072 let mut prev = mem::replace(&mut self.path, new_path);
3073 if prev.challenge.is_none() {
3075 prev.challenge = Some(self.rng.random());
3076 prev.challenge_pending = true;
3077 self.prev_path = Some((self.rem_cids.active(), prev));
3080 }
3081
3082 self.timers.set(
3083 Timer::PathValidation,
3084 now + 3 * cmp::max(self.pto(SpaceId::Data), prev_pto),
3085 );
3086 }
3087
3088 pub fn local_address_changed(&mut self) {
3090 self.update_rem_cid();
3091 self.ping();
3092 }
3093
3094 fn update_rem_cid(&mut self) {
3096 let (reset_token, retired) = match self.rem_cids.next() {
3097 Some(x) => x,
3098 None => return,
3099 };
3100
3101 self.spaces[SpaceId::Data]
3103 .pending
3104 .retire_cids
3105 .extend(retired);
3106 self.set_reset_token(reset_token);
3107 }
3108
3109 fn set_reset_token(&mut self, reset_token: ResetToken) {
3110 self.endpoint_events
3111 .push_back(EndpointEventInner::ResetToken(
3112 self.path.remote,
3113 reset_token,
3114 ));
3115 self.peer_params.stateless_reset_token = Some(reset_token);
3116 }
3117
3118 fn issue_first_cids(&mut self, now: Instant) {
3120 if self.local_cid_state.cid_len() == 0 {
3121 return;
3122 }
3123
3124 let mut n = self.peer_params.issue_cids_limit() - 1;
3126 if let ConnectionSide::Server { server_config } = &self.side {
3127 if server_config.has_preferred_address() {
3128 n -= 1;
3130 }
3131 }
3132 self.endpoint_events
3133 .push_back(EndpointEventInner::NeedIdentifiers(now, n));
3134 }
3135
3136 fn populate_packet(
3137 &mut self,
3138 now: Instant,
3139 space_id: SpaceId,
3140 buf: &mut Vec<u8>,
3141 max_size: usize,
3142 pn: u64,
3143 ) -> SentFrames {
3144 let mut sent = SentFrames::default();
3145 let space = &mut self.spaces[space_id];
3146 let is_0rtt = space_id == SpaceId::Data && space.crypto.is_none();
3147 space.pending_acks.maybe_ack_non_eliciting();
3148
3149 if !is_0rtt && mem::replace(&mut space.pending.handshake_done, false) {
3151 buf.write(frame::FrameType::HANDSHAKE_DONE);
3152 sent.retransmits.get_or_create().handshake_done = true;
3153 self.stats.frame_tx.handshake_done =
3155 self.stats.frame_tx.handshake_done.saturating_add(1);
3156 }
3157
3158 if mem::replace(&mut space.ping_pending, false) {
3160 trace!("PING");
3161 buf.write(frame::FrameType::PING);
3162 sent.non_retransmits = true;
3163 self.stats.frame_tx.ping += 1;
3164 }
3165
3166 if mem::replace(&mut space.immediate_ack_pending, false) {
3168 trace!("IMMEDIATE_ACK");
3169 buf.write(frame::FrameType::IMMEDIATE_ACK);
3170 sent.non_retransmits = true;
3171 self.stats.frame_tx.immediate_ack += 1;
3172 }
3173
3174 if space.pending_acks.can_send() {
3176 Self::populate_acks(
3177 now,
3178 self.receiving_ecn,
3179 &mut sent,
3180 space,
3181 buf,
3182 &mut self.stats,
3183 );
3184 }
3185
3186 if mem::replace(&mut space.pending.ack_frequency, false) {
3188 let sequence_number = self.ack_frequency.next_sequence_number();
3189
3190 let config = self.config.ack_frequency_config.as_ref().unwrap();
3192
3193 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay(
3195 self.path.rtt.get(),
3196 config,
3197 &self.peer_params,
3198 );
3199
3200 trace!(?max_ack_delay, "ACK_FREQUENCY");
3201
3202 frame::AckFrequency {
3203 sequence: sequence_number,
3204 ack_eliciting_threshold: config.ack_eliciting_threshold,
3205 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX),
3206 reordering_threshold: config.reordering_threshold,
3207 }
3208 .encode(buf);
3209
3210 sent.retransmits.get_or_create().ack_frequency = true;
3211
3212 self.ack_frequency.ack_frequency_sent(pn, max_ack_delay);
3213 self.stats.frame_tx.ack_frequency += 1;
3214 }
3215
3216 if buf.len() + 9 < max_size && space_id == SpaceId::Data {
3218 if let Some(token) = self.path.challenge {
3220 self.path.challenge_pending = false;
3222 sent.non_retransmits = true;
3223 sent.requires_padding = true;
3224 trace!("PATH_CHALLENGE {:08x}", token);
3225 buf.write(frame::FrameType::PATH_CHALLENGE);
3226 buf.write(token);
3227 self.stats.frame_tx.path_challenge += 1;
3228 }
3229 }
3230
3231 if buf.len() + 9 < max_size && space_id == SpaceId::Data {
3233 if let Some(token) = self.path_responses.pop_on_path(self.path.remote) {
3234 sent.non_retransmits = true;
3235 sent.requires_padding = true;
3236 trace!("PATH_RESPONSE {:08x}", token);
3237 buf.write(frame::FrameType::PATH_RESPONSE);
3238 buf.write(token);
3239 self.stats.frame_tx.path_response += 1;
3240 }
3241 }
3242
3243 while buf.len() + frame::Crypto::SIZE_BOUND < max_size && !is_0rtt {
3245 let mut frame = match space.pending.crypto.pop_front() {
3246 Some(x) => x,
3247 None => break,
3248 };
3249
3250 let max_crypto_data_size = max_size
3255 - buf.len()
3256 - 1 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) })
3258 - 2; let len = frame
3261 .data
3262 .len()
3263 .min(2usize.pow(14) - 1)
3264 .min(max_crypto_data_size);
3265
3266 let data = frame.data.split_to(len);
3267 let truncated = frame::Crypto {
3268 offset: frame.offset,
3269 data,
3270 };
3271 trace!(
3272 "CRYPTO: off {} len {}",
3273 truncated.offset,
3274 truncated.data.len()
3275 );
3276 truncated.encode(buf);
3277 self.stats.frame_tx.crypto += 1;
3278 sent.retransmits.get_or_create().crypto.push_back(truncated);
3279 if !frame.data.is_empty() {
3280 frame.offset += len as u64;
3281 space.pending.crypto.push_front(frame);
3282 }
3283 }
3284
3285 if space_id == SpaceId::Data {
3286 self.streams.write_control_frames(
3287 buf,
3288 &mut space.pending,
3289 &mut sent.retransmits,
3290 &mut self.stats.frame_tx,
3291 max_size,
3292 );
3293 }
3294
3295 while buf.len() + NewConnectionId::SIZE_BOUND < max_size {
3297 let issued = match space.pending.new_cids.pop() {
3298 Some(x) => x,
3299 None => break,
3300 };
3301 trace!(
3302 sequence = issued.sequence,
3303 id = %issued.id,
3304 "NEW_CONNECTION_ID"
3305 );
3306 frame::NewConnectionId {
3307 sequence: issued.sequence,
3308 retire_prior_to: self.local_cid_state.retire_prior_to(),
3309 id: issued.id,
3310 reset_token: issued.reset_token,
3311 }
3312 .encode(buf);
3313 sent.retransmits.get_or_create().new_cids.push(issued);
3314 self.stats.frame_tx.new_connection_id += 1;
3315 }
3316
3317 while buf.len() + frame::RETIRE_CONNECTION_ID_SIZE_BOUND < max_size {
3319 let seq = match space.pending.retire_cids.pop() {
3320 Some(x) => x,
3321 None => break,
3322 };
3323 trace!(sequence = seq, "RETIRE_CONNECTION_ID");
3324 buf.write(frame::FrameType::RETIRE_CONNECTION_ID);
3325 buf.write_var(seq);
3326 sent.retransmits.get_or_create().retire_cids.push(seq);
3327 self.stats.frame_tx.retire_connection_id += 1;
3328 }
3329
3330 let mut sent_datagrams = false;
3332 while buf.len() + Datagram::SIZE_BOUND < max_size && space_id == SpaceId::Data {
3333 match self.datagrams.write(buf, max_size) {
3334 true => {
3335 sent_datagrams = true;
3336 sent.non_retransmits = true;
3337 self.stats.frame_tx.datagram += 1;
3338 }
3339 false => break,
3340 }
3341 }
3342 if self.datagrams.send_blocked && sent_datagrams {
3343 self.events.push_back(Event::DatagramsUnblocked);
3344 self.datagrams.send_blocked = false;
3345 }
3346
3347 while let Some(remote_addr) = space.pending.new_tokens.pop() {
3349 debug_assert_eq!(space_id, SpaceId::Data);
3350 let ConnectionSide::Server { server_config } = &self.side else {
3351 panic!("NEW_TOKEN frames should not be enqueued by clients");
3352 };
3353
3354 if remote_addr != self.path.remote {
3355 continue;
3360 }
3361
3362 let token = Token::new(
3363 TokenPayload::Validation {
3364 ip: remote_addr.ip(),
3365 issued: server_config.time_source.now(),
3366 },
3367 &mut self.rng,
3368 );
3369 let new_token = NewToken {
3370 token: token.encode(&*server_config.token_key).into(),
3371 };
3372
3373 if buf.len() + new_token.size() >= max_size {
3374 space.pending.new_tokens.push(remote_addr);
3375 break;
3376 }
3377
3378 new_token.encode(buf);
3379 sent.retransmits
3380 .get_or_create()
3381 .new_tokens
3382 .push(remote_addr);
3383 self.stats.frame_tx.new_token += 1;
3384 }
3385
3386 if space_id == SpaceId::Data {
3388 sent.stream_frames =
3389 self.streams
3390 .write_stream_frames(buf, max_size, self.config.send_fairness);
3391 self.stats.frame_tx.stream += sent.stream_frames.len() as u64;
3392 }
3393
3394 sent
3395 }
3396
3397 fn populate_acks(
3402 now: Instant,
3403 receiving_ecn: bool,
3404 sent: &mut SentFrames,
3405 space: &mut PacketSpace,
3406 buf: &mut Vec<u8>,
3407 stats: &mut ConnectionStats,
3408 ) {
3409 debug_assert!(!space.pending_acks.ranges().is_empty());
3410
3411 debug_assert!(space.crypto.is_some(), "tried to send ACK in 0-RTT");
3413 let ecn = if receiving_ecn {
3414 Some(&space.ecn_counters)
3415 } else {
3416 None
3417 };
3418 sent.largest_acked = space.pending_acks.ranges().max();
3419
3420 let delay_micros = space.pending_acks.ack_delay(now).as_micros() as u64;
3421
3422 let ack_delay_exp = TransportParameters::default().ack_delay_exponent;
3424 let delay = delay_micros >> ack_delay_exp.into_inner();
3425
3426 trace!(
3427 "ACK {:?}, Delay = {}us",
3428 space.pending_acks.ranges(),
3429 delay_micros
3430 );
3431
3432 frame::Ack::encode(delay as _, space.pending_acks.ranges(), ecn, buf);
3433 stats.frame_tx.acks += 1;
3434 }
3435
3436 fn close_common(&mut self) {
3437 trace!("connection closed");
3438 for &timer in &Timer::VALUES {
3439 self.timers.stop(timer);
3440 }
3441 }
3442
3443 fn set_close_timer(&mut self, now: Instant) {
3444 self.timers
3445 .set(Timer::Close, now + 3 * self.pto(self.highest_space));
3446 }
3447
3448 fn handle_peer_params(&mut self, params: TransportParameters) -> Result<(), TransportError> {
3450 if Some(self.orig_rem_cid) != params.initial_src_cid
3451 || (self.side.is_client()
3452 && (Some(self.initial_dst_cid) != params.original_dst_cid
3453 || self.retry_src_cid != params.retry_src_cid))
3454 {
3455 return Err(TransportError::TRANSPORT_PARAMETER_ERROR(
3456 "CID authentication failure",
3457 ));
3458 }
3459
3460 self.set_peer_params(params);
3461
3462 Ok(())
3463 }
3464
3465 fn set_peer_params(&mut self, params: TransportParameters) {
3466 self.streams.set_params(¶ms);
3467 self.idle_timeout =
3468 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout));
3469 trace!("negotiated max idle timeout {:?}", self.idle_timeout);
3470 if let Some(ref info) = params.preferred_address {
3471 self.rem_cids.insert(frame::NewConnectionId {
3472 sequence: 1,
3473 id: info.connection_id,
3474 reset_token: info.stateless_reset_token,
3475 retire_prior_to: 0,
3476 }).expect("preferred address CID is the first received, and hence is guaranteed to be legal");
3477 }
3478 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(¶ms);
3479 self.peer_params = params;
3480 self.path.mtud.on_peer_max_udp_payload_size_received(
3481 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX),
3482 );
3483 }
3484
3485 fn decrypt_packet(
3486 &mut self,
3487 now: Instant,
3488 packet: &mut Packet,
3489 ) -> Result<Option<u64>, Option<TransportError>> {
3490 let result = packet_crypto::decrypt_packet_body(
3491 packet,
3492 &self.spaces,
3493 self.zero_rtt_crypto.as_ref(),
3494 self.key_phase,
3495 self.prev_crypto.as_ref(),
3496 self.next_crypto.as_ref(),
3497 )?;
3498
3499 let result = match result {
3500 Some(r) => r,
3501 None => return Ok(None),
3502 };
3503
3504 if result.outgoing_key_update_acked {
3505 if let Some(prev) = self.prev_crypto.as_mut() {
3506 prev.end_packet = Some((result.number, now));
3507 self.set_key_discard_timer(now, packet.header.space());
3508 }
3509 }
3510
3511 if result.incoming_key_update {
3512 trace!("key update authenticated");
3513 self.update_keys(Some((result.number, now)), true);
3514 self.set_key_discard_timer(now, packet.header.space());
3515 }
3516
3517 Ok(Some(result.number))
3518 }
3519
3520 fn update_keys(&mut self, end_packet: Option<(u64, Instant)>, remote: bool) {
3521 trace!("executing key update");
3522 let new = self
3526 .crypto
3527 .next_1rtt_keys()
3528 .expect("only called for `Data` packets");
3529 self.key_phase_size = new
3530 .local
3531 .confidentiality_limit()
3532 .saturating_sub(KEY_UPDATE_MARGIN);
3533 let old = mem::replace(
3534 &mut self.spaces[SpaceId::Data]
3535 .crypto
3536 .as_mut()
3537 .unwrap() .packet,
3539 mem::replace(self.next_crypto.as_mut().unwrap(), new),
3540 );
3541 self.spaces[SpaceId::Data].sent_with_keys = 0;
3542 self.prev_crypto = Some(PrevCrypto {
3543 crypto: old,
3544 end_packet,
3545 update_unacked: remote,
3546 });
3547 self.key_phase = !self.key_phase;
3548 }
3549
3550 fn peer_supports_ack_frequency(&self) -> bool {
3551 self.peer_params.min_ack_delay.is_some()
3552 }
3553
3554 pub(crate) fn immediate_ack(&mut self) {
3559 self.spaces[self.highest_space].immediate_ack_pending = true;
3560 }
3561
3562 #[cfg(test)]
3564 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> {
3565 let (first_decode, remaining) = match &event.0 {
3566 ConnectionEventInner::Datagram(DatagramConnectionEvent {
3567 first_decode,
3568 remaining,
3569 ..
3570 }) => (first_decode, remaining),
3571 _ => return None,
3572 };
3573
3574 if remaining.is_some() {
3575 panic!("Packets should never be coalesced in tests");
3576 }
3577
3578 let decrypted_header = packet_crypto::unprotect_header(
3579 first_decode.clone(),
3580 &self.spaces,
3581 self.zero_rtt_crypto.as_ref(),
3582 self.peer_params.stateless_reset_token,
3583 )?;
3584
3585 let mut packet = decrypted_header.packet?;
3586 packet_crypto::decrypt_packet_body(
3587 &mut packet,
3588 &self.spaces,
3589 self.zero_rtt_crypto.as_ref(),
3590 self.key_phase,
3591 self.prev_crypto.as_ref(),
3592 self.next_crypto.as_ref(),
3593 )
3594 .ok()?;
3595
3596 Some(packet.payload.to_vec())
3597 }
3598
3599 #[cfg(test)]
3602 pub(crate) fn bytes_in_flight(&self) -> u64 {
3603 self.path.in_flight.bytes
3604 }
3605
3606 #[cfg(test)]
3608 pub(crate) fn congestion_window(&self) -> u64 {
3609 self.path
3610 .congestion
3611 .window()
3612 .saturating_sub(self.path.in_flight.bytes)
3613 }
3614
3615 #[cfg(test)]
3617 pub(crate) fn is_idle(&self) -> bool {
3618 Timer::VALUES
3619 .iter()
3620 .filter(|&&t| !matches!(t, Timer::KeepAlive | Timer::PushNewCid | Timer::KeyDiscard))
3621 .filter_map(|&t| Some((t, self.timers.get(t)?)))
3622 .min_by_key(|&(_, time)| time)
3623 .is_none_or(|(timer, _)| timer == Timer::Idle)
3624 }
3625
3626 #[cfg(test)]
3628 pub(crate) fn using_ecn(&self) -> bool {
3629 self.path.sending_ecn
3630 }
3631
3632 #[cfg(test)]
3634 pub(crate) fn total_recvd(&self) -> u64 {
3635 self.path.total_recvd
3636 }
3637
3638 #[cfg(test)]
3639 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) {
3640 self.local_cid_state.active_seq()
3641 }
3642
3643 #[cfg(test)]
3646 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) {
3647 let n = self.local_cid_state.assign_retire_seq(v);
3648 self.endpoint_events
3649 .push_back(EndpointEventInner::NeedIdentifiers(now, n));
3650 }
3651
3652 #[cfg(test)]
3654 pub(crate) fn active_rem_cid_seq(&self) -> u64 {
3655 self.rem_cids.active_seq()
3656 }
3657
3658 #[cfg(test)]
3660 pub(crate) fn path_mtu(&self) -> u16 {
3661 self.path.current_mtu()
3662 }
3663
3664 fn can_send_1rtt(&self, max_size: usize) -> bool {
3668 self.streams.can_send_stream_data()
3669 || self.path.challenge_pending
3670 || self
3671 .prev_path
3672 .as_ref()
3673 .is_some_and(|(_, x)| x.challenge_pending)
3674 || !self.path_responses.is_empty()
3675 || self
3676 .datagrams
3677 .outgoing
3678 .front()
3679 .is_some_and(|x| x.size(true) <= max_size)
3680 }
3681
3682 fn remove_in_flight(&mut self, packet: &SentPacket) {
3684 for path in [&mut self.path]
3686 .into_iter()
3687 .chain(self.prev_path.as_mut().map(|(_, data)| data))
3688 {
3689 if path.remove_in_flight(packet) {
3690 return;
3691 }
3692 }
3693 }
3694
3695 fn kill(&mut self, reason: ConnectionError) {
3697 self.close_common();
3698 self.error = Some(reason);
3699 self.state = State::Drained;
3700 self.endpoint_events.push_back(EndpointEventInner::Drained);
3701 }
3702
3703 pub fn current_mtu(&self) -> u16 {
3707 self.path.current_mtu()
3708 }
3709
3710 fn predict_1rtt_overhead(&self, pn: Option<u64>) -> usize {
3717 let pn_len = match pn {
3718 Some(pn) => PacketNumber::new(
3719 pn,
3720 self.spaces[SpaceId::Data].largest_acked_packet.unwrap_or(0),
3721 )
3722 .len(),
3723 None => 4,
3725 };
3726
3727 1 + self.rem_cids.active().len() + pn_len + self.tag_len_1rtt()
3729 }
3730
3731 fn tag_len_1rtt(&self) -> usize {
3732 let key = match self.spaces[SpaceId::Data].crypto.as_ref() {
3733 Some(crypto) => Some(&*crypto.packet.local),
3734 None => self.zero_rtt_crypto.as_ref().map(|x| &*x.packet),
3735 };
3736 key.map_or(16, |x| x.tag_len())
3740 }
3741
3742 fn on_path_validated(&mut self) {
3744 self.path.validated = true;
3745 let ConnectionSide::Server { server_config } = &self.side else {
3746 return;
3747 };
3748 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens;
3749 new_tokens.clear();
3750 for _ in 0..server_config.validation_token.sent {
3751 new_tokens.push(self.path.remote);
3752 }
3753 }
3754}
3755
3756impl fmt::Debug for Connection {
3757 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3758 f.debug_struct("Connection")
3759 .field("handshake_cid", &self.handshake_cid)
3760 .finish()
3761 }
3762}
3763
3764enum ConnectionSide {
3766 Client {
3767 token: Bytes,
3769 token_store: Arc<dyn TokenStore>,
3770 server_name: String,
3771 },
3772 Server {
3773 server_config: Arc<ServerConfig>,
3774 },
3775}
3776
3777impl ConnectionSide {
3778 fn remote_may_migrate(&self) -> bool {
3779 match self {
3780 Self::Server { server_config } => server_config.migration,
3781 Self::Client { .. } => false,
3782 }
3783 }
3784
3785 fn is_client(&self) -> bool {
3786 self.side().is_client()
3787 }
3788
3789 fn is_server(&self) -> bool {
3790 self.side().is_server()
3791 }
3792
3793 fn side(&self) -> Side {
3794 match *self {
3795 Self::Client { .. } => Side::Client,
3796 Self::Server { .. } => Side::Server,
3797 }
3798 }
3799}
3800
3801impl From<SideArgs> for ConnectionSide {
3802 fn from(side: SideArgs) -> Self {
3803 match side {
3804 SideArgs::Client {
3805 token_store,
3806 server_name,
3807 } => Self::Client {
3808 token: token_store.take(&server_name).unwrap_or_default(),
3809 token_store,
3810 server_name,
3811 },
3812 SideArgs::Server {
3813 server_config,
3814 pref_addr_cid: _,
3815 path_validated: _,
3816 } => Self::Server { server_config },
3817 }
3818 }
3819}
3820
3821pub(crate) enum SideArgs {
3823 Client {
3824 token_store: Arc<dyn TokenStore>,
3825 server_name: String,
3826 },
3827 Server {
3828 server_config: Arc<ServerConfig>,
3829 pref_addr_cid: Option<ConnectionId>,
3830 path_validated: bool,
3831 },
3832}
3833
3834impl SideArgs {
3835 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> {
3836 match *self {
3837 Self::Client { .. } => None,
3838 Self::Server { pref_addr_cid, .. } => pref_addr_cid,
3839 }
3840 }
3841
3842 pub(crate) fn path_validated(&self) -> bool {
3843 match *self {
3844 Self::Client { .. } => true,
3845 Self::Server { path_validated, .. } => path_validated,
3846 }
3847 }
3848
3849 pub(crate) fn side(&self) -> Side {
3850 match *self {
3851 Self::Client { .. } => Side::Client,
3852 Self::Server { .. } => Side::Server,
3853 }
3854 }
3855}
3856
3857#[derive(Debug, Error, Clone, PartialEq, Eq)]
3859pub enum ConnectionError {
3860 #[error("peer doesn't implement any supported version")]
3862 VersionMismatch,
3863 #[error(transparent)]
3865 TransportError(#[from] TransportError),
3866 #[error("aborted by peer: {0}")]
3868 ConnectionClosed(frame::ConnectionClose),
3869 #[error("closed by peer: {0}")]
3871 ApplicationClosed(frame::ApplicationClose),
3872 #[error("reset by peer")]
3874 Reset,
3875 #[error("timed out")]
3881 TimedOut,
3882 #[error("closed")]
3884 LocallyClosed,
3885 #[error("CIDs exhausted")]
3889 CidsExhausted,
3890}
3891
3892impl From<Close> for ConnectionError {
3893 fn from(x: Close) -> Self {
3894 match x {
3895 Close::Connection(reason) => Self::ConnectionClosed(reason),
3896 Close::Application(reason) => Self::ApplicationClosed(reason),
3897 }
3898 }
3899}
3900
3901impl From<ConnectionError> for io::Error {
3903 fn from(x: ConnectionError) -> Self {
3904 use ConnectionError::*;
3905 let kind = match x {
3906 TimedOut => io::ErrorKind::TimedOut,
3907 Reset => io::ErrorKind::ConnectionReset,
3908 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted,
3909 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => {
3910 io::ErrorKind::Other
3911 }
3912 };
3913 Self::new(kind, x)
3914 }
3915}
3916
3917#[allow(unreachable_pub)] #[derive(Clone)]
3919pub enum State {
3920 Handshake(state::Handshake),
3921 Established,
3922 Closed(state::Closed),
3923 Draining,
3924 Drained,
3926}
3927
3928impl State {
3929 fn closed<R: Into<Close>>(reason: R) -> Self {
3930 Self::Closed(state::Closed {
3931 reason: reason.into(),
3932 })
3933 }
3934
3935 fn is_handshake(&self) -> bool {
3936 matches!(*self, Self::Handshake(_))
3937 }
3938
3939 fn is_established(&self) -> bool {
3940 matches!(*self, Self::Established)
3941 }
3942
3943 fn is_closed(&self) -> bool {
3944 matches!(*self, Self::Closed(_) | Self::Draining | Self::Drained)
3945 }
3946
3947 fn is_drained(&self) -> bool {
3948 matches!(*self, Self::Drained)
3949 }
3950}
3951
3952mod state {
3953 use super::*;
3954
3955 #[allow(unreachable_pub)] #[derive(Clone)]
3957 pub struct Handshake {
3958 pub(super) rem_cid_set: bool,
3962 pub(super) expected_token: Bytes,
3966 pub(super) client_hello: Option<Bytes>,
3970 }
3971
3972 #[allow(unreachable_pub)] #[derive(Clone)]
3974 pub struct Closed {
3975 pub(super) reason: Close,
3976 }
3977}
3978
3979#[derive(Debug)]
3981pub enum Event {
3982 HandshakeDataReady,
3984 Connected,
3986 ConnectionLost {
3990 reason: ConnectionError,
3992 },
3993 Stream(StreamEvent),
3995 DatagramReceived,
3997 DatagramsUnblocked,
3999}
4000
4001fn get_max_ack_delay(params: &TransportParameters) -> Duration {
4002 Duration::from_micros(params.max_ack_delay.0 * 1000)
4003}
4004
4005const MAX_BACKOFF_EXPONENT: u32 = 16;
4007
4008const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32;
4016
4017const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize =
4023 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4;
4024
4025const KEY_UPDATE_MARGIN: u64 = 10_000;
4029
4030#[derive(Default)]
4031struct SentFrames {
4032 retransmits: ThinRetransmits,
4033 largest_acked: Option<u64>,
4034 stream_frames: StreamMetaVec,
4035 non_retransmits: bool,
4037 requires_padding: bool,
4038}
4039
4040impl SentFrames {
4041 fn is_ack_only(&self, streams: &StreamsState) -> bool {
4043 self.largest_acked.is_some()
4044 && !self.non_retransmits
4045 && self.stream_frames.is_empty()
4046 && self.retransmits.is_empty(streams)
4047 }
4048}
4049
4050fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> {
4058 match (x, y) {
4059 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None,
4060 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)),
4061 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)),
4062 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)),
4063 }
4064}
4065
4066#[cfg(test)]
4067mod tests {
4068 use super::*;
4069
4070 #[test]
4071 fn negotiate_max_idle_timeout_commutative() {
4072 let test_params = [
4073 (None, None, None),
4074 (None, Some(VarInt(0)), None),
4075 (None, Some(VarInt(2)), Some(Duration::from_millis(2))),
4076 (Some(VarInt(0)), Some(VarInt(0)), None),
4077 (
4078 Some(VarInt(2)),
4079 Some(VarInt(0)),
4080 Some(Duration::from_millis(2)),
4081 ),
4082 (
4083 Some(VarInt(1)),
4084 Some(VarInt(4)),
4085 Some(Duration::from_millis(1)),
4086 ),
4087 ];
4088
4089 for (left, right, result) in test_params {
4090 assert_eq!(negotiate_max_idle_timeout(left, right), result);
4091 assert_eq!(negotiate_max_idle_timeout(right, left), result);
4092 }
4093 }
4094}