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    rtt::RoundtripTimeEstimator,
11    sendme::{self, WindowParams},
12    CongestionControlAlgorithm, CongestionSignals, CongestionWindow, State,
13};
14
15/// Fixed window algorithm which is essentially the SENDME v0 with fixed receive and send window
16/// size.
17#[derive(Clone, Debug)]
18pub(crate) struct FixedWindow {
19    /// Window used to say how many cells we can receive.
20    recvwindow: sendme::CircRecvWindow,
21    /// Window used to say how many cells we can send.
22    sendwindow: sendme::CircSendWindow,
23}
24
25impl FixedWindow {
26    /// Create a new `FixedWindow` form a given initial sendwindow size.
27    ///
28    /// Note: the initial recvwindow size is given by [`sendme::CircParams::start`].
29    pub(crate) fn new(initial_window: u16) -> Self {
30        Self {
31            recvwindow: sendme::CircRecvWindow::new(sendme::CircParams::start()),
32            sendwindow: sendme::CircSendWindow::new(initial_window),
33        }
34    }
35}
36
37impl CongestionControlAlgorithm for FixedWindow {
38    fn uses_stream_sendme(&self) -> bool {
39        true
40    }
41
42    fn is_next_cell_sendme(&self) -> bool {
43        self.sendwindow.should_record_tag()
44    }
45
46    fn can_send(&self) -> bool {
47        self.sendwindow.window() > 0
48    }
49
50    fn cwnd(&self) -> Option<&CongestionWindow> {
51        None
52    }
53
54    fn sendme_received(
55        &mut self,
56        _state: &mut State,
57        _rtt: &mut RoundtripTimeEstimator,
58        _signals: CongestionSignals,
59    ) -> Result<()> {
60        self.sendwindow.put()
61    }
62
63    fn sendme_sent(&mut self) -> Result<()> {
64        self.recvwindow.put();
65        Ok(())
66    }
67
68    fn data_received(&mut self) -> Result<bool> {
69        self.recvwindow.take()
70    }
71
72    fn data_sent(&mut self) -> Result<()> {
73        self.sendwindow.take()
74    }
75
76    #[cfg(feature = "conflux")]
77    fn inflight(&self) -> Option<u32> {
78        None
79    }
80
81    #[cfg(test)]
82    fn send_window(&self) -> u32 {
83        u32::from(self.sendwindow.window())
84    }
85}