Open In App

Slow Start Restart Algorithm For Congestion Control

Last Updated : 04 Feb, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Once a connection is established between client and server, the sender sends the data to the receiver in form of packets. If the network is congested then packets get dropped. This happens when the buffer of intermediaries devices such as Router is filled. TCP sender has to detect whether it has filled up ‘buffers at the intermediate devices’, and if so, slow down the transmission rate so that network can come out of the ‘congested state’. But there is one problem no one informs the TCP sender about the state of ‘buffers’ at the intermediate devices.

TCP sender ‘estimates’ the state of the buffers at the intermediate devices by itself and maintains a variable for itself, which is known as congestion window (cwnd). The sender never sends data worth more than its congestion window size. Let’s say cwnd = 15 packets then the sender can’t send 16 packets into the network. This ‘estimate’ which is done at the TCP sender accounts for the ‘entire path’ from TCP sender to TCP receiver. It is not an estimate of the buffer occupancy at ‘every intermediate device’ between the TCP sender and the TCP receiver. Because the sender can’t know the number of intermediary devices. Also, the route of the packet can change for the same connection. Different packets can choose different routes to reach from sender to receiver.

So, how does the ‘estimation process’ start at the TCP sender? What is the initial value of cwnd? The answer is a slow-start algorithm.

Slow Start Algorithm:

Purpose: Start the process of ‘estimating’ cwnd and quickly arrive at a ‘decent estimate’.

Algorithm

  • Starts with an initial value of cwnd (default is 10 segments in the Linux, it was 1 segment in 1980s)
  • Initial value of cwnd is stored in a separate variable called ‘initcwnd’ in the Linux kernel and it is fixed.
  • When the algorithm begins, cwnd = initcwnd
  • Another way to look at cwnd: ‘the maximum number of segments that a TCP sender can transmit without waiting for an Acknowledgment (ACK)’
  • One more important variable is used in TCP, which is called ‘inflight’ or ‘pipe’
  • inflight/pipe = the number of packets that have been sent but an ACK is not received for those packets i.e., they are ‘inflight’ or ‘in pipe’ between the sender and receiver
  • inflight ≤ cwnd, but it is preferred than inflight = cwnd to utilize the network bandwidth

Illustration

Initially, cwnd = initcwnd = 10 segments. The sender sends 10 segments into the flight without waiting for the single acknowledgment to arrive. 
On arrival of every ACK, sender increments the cwnd by 1 segment and send 2 new segments in the network.

cwnd = 10 + 1 = 11, new cwnd is 11 but now only 9 segments are in flight. Sender is allowed to send segments worth of cwnd value in flight. So sender sends 2 more segments in flight.

inflight = inflight – 1 + 2 // -1 because we received an ACK, +2 because we sent 2 new segments
inflight = 10 – 1 = 9 + 2 = 11

Thus, if all the segments are successfully ACKed, the cwnd will ‘eventually’ double in one RTT. All 10 ACK will arrive within one RTT of time to the sender and by that time cwnd will become 20. Now 20 segments are in flight.

Key takeaway

cwnd increases in a continuous manner, every time an ACK arrives. The sender does not double cwnd after one RTT instead it gradually increases it by 1 every time a new ACK arrives. TCP sender does not wait for ACKs of ‘all 10 segments’ to arrive to increase the cwnd. This behavior will waste the network bandwidth because no new segments are sent till all ACKs and bandwidth are not utilized.

Slow start restart:

When cwnd reaches its maximum value of ssthresh or when a packet loss is detected then slow start is terminated and another algorithm becomes active which handles thereafter. 

But when the TCP connection is idle for a certain period (equal to RTO) the sender invalidates its estimate of cwnd because it is not being updated for a while. When the sender sends more segments after that defined period of time after being idle, it restarts the slow start algorithm to decently estimate its congestion window size. 

AIMD (Additive Increase Multiplicative Decrease): 

When a packet drop occurs (i.e., the TCP sender does not get an ACK for a specific packet) or when the algorithm reaches ‘Slow Start Threshold’, Slow start terminates and AIMD begins. At the beginning of a TCP connection, ssthresh = ∞. ssthresh is updated when a packet drop occurs. It is updated as ssthresh = cwnd ÷ 2. AIMD decreases the cwnd by 50% when packet loss is detected and increases the cwnd by 1 per RTT (not per ACK unlike Slow Start).

What is the problem if the TCP connection is reset?

TCP sender has to obtain a ‘new estimate’ of cwnd which takes several RTTs. Example: Assume cwnd = 1024 segments when the TCP connection was reset due to an idle period. Now TCP sender initializes cwnd to 10 segments and uses a slow start algorithm to increase the cwnd. It would take 10 RTTs (1000ms if one RTT is 100ms) for the TCP sender to get its cwnd to 1024 segments!

Linux commands:

Playing around with SSR in the Linux Kernel with the help of the following commands:

Checking the default setting of SSR in the Linux Kernel

$ sysctl net.ipv4.tcp_slow_start_after_idle

Expected Output (it means that SSR is enabled):

$ net.ipv4.tcp_slow_start_after_idle = 1

Disable Slow Start Restart (important for Servers, not so much for Clients)

$ sudo sysctl -w net.ipv4.tcp_slow_start_after_idle=0

Expected Output:

$ net.ipv4.tcp_slow_start_after_idle = 0

Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads