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

            
7
use crate::Result;
8

            
9
use 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)]
18
pub(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

            
25
impl 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
400
    pub(crate) fn new(initial_window: u16) -> Self {
30
400
        Self {
31
400
            recvwindow: sendme::CircRecvWindow::new(sendme::CircParams::start()),
32
400
            sendwindow: sendme::CircSendWindow::new(initial_window),
33
400
        }
34
400
    }
35
}
36

            
37
impl CongestionControlAlgorithm for FixedWindow {
38
80
    fn uses_stream_sendme(&self) -> bool {
39
80
        true
40
80
    }
41

            
42
2728
    fn is_next_cell_sendme(&self) -> bool {
43
2728
        self.sendwindow.should_record_tag()
44
2728
    }
45

            
46
9964
    fn can_send(&self) -> bool {
47
9964
        self.sendwindow.window() > 0
48
9964
    }
49

            
50
28
    fn cwnd(&self) -> Option<&CongestionWindow> {
51
28
        None
52
28
    }
53

            
54
4
    fn sendme_received(
55
4
        &mut self,
56
4
        _state: &mut State,
57
4
        _rtt: &mut RoundtripTimeEstimator,
58
4
        _signals: CongestionSignals,
59
4
    ) -> Result<()> {
60
4
        self.sendwindow.put()
61
4
    }
62

            
63
    fn sendme_sent(&mut self) -> Result<()> {
64
        self.recvwindow.put();
65
        Ok(())
66
    }
67

            
68
24
    fn data_received(&mut self) -> Result<bool> {
69
24
        self.recvwindow.take()
70
24
    }
71

            
72
2728
    fn data_sent(&mut self) -> Result<()> {
73
2728
        self.sendwindow.take()
74
2728
    }
75

            
76
    #[cfg(feature = "conflux")]
77
    fn inflight(&self) -> Option<u32> {
78
        None
79
    }
80

            
81
    #[cfg(test)]
82
8
    fn send_window(&self) -> u32 {
83
8
        u32::from(self.sendwindow.window())
84
8
    }
85
}