tor_proto/congestion/
fixed.rs

1//! Implementation of the Fixed Window congestion control algorithm.
2//!
3//! This is used by the circuit reactor in order to decide when to send data and SENDMEs.
4//!
5//! The vanilla flow control system of fixed window SENDMEs in the spec.
6
7use crate::Result;
8
9use super::{
10    params::{Algorithm, FixedWindowParams},
11    rtt::RoundtripTimeEstimator,
12    sendme::{self, WindowParams},
13    CongestionControlAlgorithm, CongestionSignals, CongestionWindow, State,
14};
15
16/// Fixed window algorithm which is essentially the SENDME v0 with fixed receive and send window
17/// size.
18#[derive(Clone, Debug)]
19pub(crate) struct FixedWindow {
20    /// Window used to say how many cells we can receive.
21    recvwindow: sendme::CircRecvWindow,
22    /// Window used to say how many cells we can send.
23    sendwindow: sendme::CircSendWindow,
24    /// The params from the consensus.
25    params: FixedWindowParams,
26}
27
28impl FixedWindow {
29    /// Create a new `FixedWindow` form a given initial sendwindow size.
30    ///
31    /// Note: the initial recvwindow size is given by [`sendme::CircParams::start`].
32    pub(crate) fn new(params: FixedWindowParams) -> Self {
33        let initial_window = params.circ_window_start();
34        Self {
35            recvwindow: sendme::CircRecvWindow::new(sendme::CircParams::start()),
36            sendwindow: sendme::CircSendWindow::new(initial_window),
37            params,
38        }
39    }
40}
41
42impl CongestionControlAlgorithm for FixedWindow {
43    fn uses_stream_sendme(&self) -> bool {
44        true
45    }
46
47    fn is_next_cell_sendme(&self) -> bool {
48        self.sendwindow.should_record_tag()
49    }
50
51    fn can_send(&self) -> bool {
52        self.sendwindow.window() > 0
53    }
54
55    fn cwnd(&self) -> Option<&CongestionWindow> {
56        None
57    }
58
59    fn sendme_received(
60        &mut self,
61        _state: &mut State,
62        _rtt: &mut RoundtripTimeEstimator,
63        _signals: CongestionSignals,
64    ) -> Result<()> {
65        self.sendwindow.put()
66    }
67
68    fn sendme_sent(&mut self) -> Result<()> {
69        self.recvwindow.put();
70        Ok(())
71    }
72
73    fn data_received(&mut self) -> Result<bool> {
74        self.recvwindow.take()
75    }
76
77    fn data_sent(&mut self) -> Result<()> {
78        self.sendwindow.take()
79    }
80
81    #[cfg(feature = "conflux")]
82    fn inflight(&self) -> Option<u32> {
83        None
84    }
85
86    #[cfg(test)]
87    fn send_window(&self) -> u32 {
88        u32::from(self.sendwindow.window())
89    }
90
91    fn algorithm(&self) -> Algorithm {
92        Algorithm::FixedWindow(self.params)
93    }
94}