noq_proto/connection/
ack_frequency.rs1use crate::Duration;
2use crate::frame::AckFrequency;
3use crate::transport_parameters::TransportParameters;
4use crate::{AckFrequencyConfig, TIMER_GRANULARITY, TransportError, VarInt};
5
6use super::PathId;
7
8pub(super) struct AckFrequencyState {
10 in_flight_ack_frequency_frame: Option<(PathId, u64, Duration)>,
14 next_outgoing_sequence_number: VarInt,
15 pub(super) peer_max_ack_delay: Duration,
16
17 last_ack_frequency_frame: Option<u64>,
21 pub(super) max_ack_delay: Duration,
22}
23
24impl AckFrequencyState {
25 pub(super) fn new(default_max_ack_delay: Duration) -> Self {
26 Self {
27 in_flight_ack_frequency_frame: None,
28 next_outgoing_sequence_number: VarInt(0),
29 peer_max_ack_delay: default_max_ack_delay,
30
31 last_ack_frequency_frame: None,
32 max_ack_delay: default_max_ack_delay,
33 }
34 }
35
36 pub(super) fn candidate_max_ack_delay(
39 &self,
40 rtt: Duration,
41 config: &AckFrequencyConfig,
42 peer_params: &TransportParameters,
43 ) -> Duration {
44 let min_ack_delay =
46 Duration::from_micros(peer_params.min_ack_delay.map_or(0, |x| x.into()));
47 config
48 .max_ack_delay
49 .unwrap_or(self.peer_max_ack_delay)
50 .clamp(min_ack_delay, rtt.max(MIN_AUTOMATIC_ACK_DELAY))
51 }
52
53 pub(super) fn max_ack_delay_for_pto(&self) -> Duration {
59 if let Some((_, _, max_ack_delay)) = self.in_flight_ack_frequency_frame {
61 self.peer_max_ack_delay.max(max_ack_delay)
62 } else {
63 self.peer_max_ack_delay
64 }
65 }
66
67 pub(super) fn next_sequence_number(&mut self) -> VarInt {
69 assert!(self.next_outgoing_sequence_number <= VarInt::MAX);
70
71 let seq = self.next_outgoing_sequence_number;
72 self.next_outgoing_sequence_number.0 += 1;
73 seq
74 }
75
76 pub(super) fn should_send_ack_frequency(
78 &self,
79 rtt: Duration,
80 config: &AckFrequencyConfig,
81 peer_params: &TransportParameters,
82 ) -> bool {
83 if self.next_outgoing_sequence_number.0 == 0 {
84 return true;
86 }
87 let current = self
88 .in_flight_ack_frequency_frame
89 .map_or(self.peer_max_ack_delay, |(_, _, pending)| pending);
90 let desired = self.candidate_max_ack_delay(rtt, config, peer_params);
91 let error = (desired.as_secs_f32() / current.as_secs_f32()) - 1.0;
92 error.abs() > MAX_RTT_ERROR
93 }
94
95 pub(super) fn ack_frequency_sent(
97 &mut self,
98 path_id: PathId,
99 pn: u64,
100 requested_max_ack_delay: Duration,
101 ) {
102 self.in_flight_ack_frequency_frame = Some((path_id, pn, requested_max_ack_delay));
103 }
104
105 pub(super) fn on_acked(&mut self, path_id: PathId, pn: u64) {
107 match self.in_flight_ack_frequency_frame {
108 Some((path, number, requested_max_ack_delay)) if path == path_id && number == pn => {
109 self.in_flight_ack_frequency_frame = None;
110 self.peer_max_ack_delay = requested_max_ack_delay;
111 }
112 _ => {}
113 }
114 }
115
116 pub(super) fn ack_frequency_received(
124 &mut self,
125 frame: &AckFrequency,
126 ) -> Result<bool, TransportError> {
127 if self
128 .last_ack_frequency_frame
129 .is_some_and(|highest_sequence_nr| frame.sequence.into_inner() <= highest_sequence_nr)
130 {
131 return Ok(false);
132 }
133
134 self.last_ack_frequency_frame = Some(frame.sequence.into_inner());
135
136 let max_ack_delay = Duration::from_micros(frame.request_max_ack_delay.into_inner());
138 if max_ack_delay < TIMER_GRANULARITY {
139 return Err(TransportError::PROTOCOL_VIOLATION(
140 "Requested Max Ack Delay in ACK_FREQUENCY frame is less than min_ack_delay",
141 ));
142 }
143 self.max_ack_delay = max_ack_delay;
144
145 Ok(true)
146 }
147}
148
149const MAX_RTT_ERROR: f32 = 0.2;
153
154const MIN_AUTOMATIC_ACK_DELAY: Duration = Duration::from_millis(25);