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)>,
15 next_outgoing_sequence_number: VarInt,
16 pub(super) peer_max_ack_delay: Duration,
17
18 last_ack_frequency_frame: Option<u64>,
23 pub(super) max_ack_delay: Duration,
24}
25
26impl AckFrequencyState {
27 pub(super) fn new(default_max_ack_delay: Duration) -> Self {
28 Self {
29 in_flight_ack_frequency_frame: None,
30 next_outgoing_sequence_number: VarInt(0),
31 peer_max_ack_delay: default_max_ack_delay,
32
33 last_ack_frequency_frame: None,
34 max_ack_delay: default_max_ack_delay,
35 }
36 }
37
38 pub(super) fn candidate_max_ack_delay(
41 &self,
42 rtt: Duration,
43 config: &AckFrequencyConfig,
44 peer_params: &TransportParameters,
45 ) -> Duration {
46 let min_ack_delay =
48 Duration::from_micros(peer_params.min_ack_delay.map_or(0, |x| x.into()));
49 config
50 .max_ack_delay
51 .unwrap_or(self.peer_max_ack_delay)
52 .clamp(min_ack_delay, rtt.max(MIN_AUTOMATIC_ACK_DELAY))
53 }
54
55 pub(super) fn max_ack_delay_for_pto(&self) -> Duration {
61 if let Some((_, _, max_ack_delay)) = self.in_flight_ack_frequency_frame {
63 self.peer_max_ack_delay.max(max_ack_delay)
64 } else {
65 self.peer_max_ack_delay
66 }
67 }
68
69 pub(super) fn next_sequence_number(&mut self) -> VarInt {
71 assert!(self.next_outgoing_sequence_number <= VarInt::MAX);
72
73 let seq = self.next_outgoing_sequence_number;
74 self.next_outgoing_sequence_number.0 += 1;
75 seq
76 }
77
78 pub(super) fn should_send_ack_frequency(
80 &self,
81 rtt: Duration,
82 config: &AckFrequencyConfig,
83 peer_params: &TransportParameters,
84 ) -> bool {
85 if self.next_outgoing_sequence_number.0 == 0 {
86 return true;
88 }
89 let current = self
90 .in_flight_ack_frequency_frame
91 .map_or(self.peer_max_ack_delay, |(_, _, pending)| pending);
92 let desired = self.candidate_max_ack_delay(rtt, config, peer_params);
93 let error = (desired.as_secs_f32() / current.as_secs_f32()) - 1.0;
94 error.abs() > MAX_RTT_ERROR
95 }
96
97 pub(super) fn ack_frequency_sent(
99 &mut self,
100 path_id: PathId,
101 pn: u64,
102 requested_max_ack_delay: Duration,
103 ) {
104 self.in_flight_ack_frequency_frame = Some((path_id, pn, requested_max_ack_delay));
105 }
106
107 pub(super) fn on_acked(&mut self, path_id: PathId, pn: u64) {
109 match self.in_flight_ack_frequency_frame {
110 Some((path, number, requested_max_ack_delay)) if path == path_id && number == pn => {
111 self.in_flight_ack_frequency_frame = None;
112 self.peer_max_ack_delay = requested_max_ack_delay;
113 }
114 _ => {}
115 }
116 }
117
118 pub(super) fn ack_frequency_received(
126 &mut self,
127 frame: &AckFrequency,
128 ) -> Result<bool, TransportError> {
129 if self
130 .last_ack_frequency_frame
131 .is_some_and(|highest_sequence_nr| frame.sequence.into_inner() <= highest_sequence_nr)
132 {
133 return Ok(false);
134 }
135
136 self.last_ack_frequency_frame = Some(frame.sequence.into_inner());
137
138 let max_ack_delay = Duration::from_micros(frame.request_max_ack_delay.into_inner());
140 if max_ack_delay < TIMER_GRANULARITY {
141 return Err(TransportError::PROTOCOL_VIOLATION(
142 "Requested Max Ack Delay in ACK_FREQUENCY frame is less than min_ack_delay",
143 ));
144 }
145 self.max_ack_delay = max_ack_delay;
146
147 Ok(true)
148 }
149}
150
151const MAX_RTT_ERROR: f32 = 0.2;
155
156const MIN_AUTOMATIC_ACK_DELAY: Duration = Duration::from_millis(25);