TCP/IP Congestion Avoidance Algorithm

Lost packets is one of the biggest difficulties for any transport protocol.  Sending data across a variety of platforms, switches, hubs and routers is bound to end up with some lost data.  Every protocol therefore needs a way of dealing with these lost packets.   The congestion avoidance algorithm is one way of dealing with this issue.  The algorithm assumes that the packet loss is not caused by any damage to any of the hops in the journey, it therefore focuses on the idea that lost packets are a result of congestion instead. More specifically, congestion which is occurring between the source node and the destination node.

There are two main indicators that packet loss is occurring – timeouts and duplicate ACKS. There are also two primary algorithms in place to help alleviate these situations – Slow Start and Congestion Avoidance.   However both these two algorithms, which are completely independent, rely on specific variables to operate effectively.  Slow start requires a threshold size called ssthresh and the congestion algorithm needs a congestion window variable called cwnd.  As mentioned these are both independant but in practice when congestion is occurring we nned to both slow transmission rate and use slow start to get the packets flowing again, therefore they are normally implemented together.

The first step is to initialize the variables cwnd=1 segment and ssthresh to 65535 bytes.  It’s important to remember that the output routine of TCP never sends more than the minmum of cwnd and the receivers advertised windows.  All congestion avoidance does is to instigate from the senders side flow control to restrict the number of packets transmitted.   There is also flow control implemented by the receiver based on the advertised windows size.

Then when there is some sign of congestion – duplicate acks or timeouts, slow start is implemented and the sssthresh variable is updated.  CWND will rise and fall in reponse to network traffic, it will typically rise when the traffic is flowing freely.  So for instance if you’re sending data through a remote device like a France proxy for example, which is losing data or overloaded.  The transmission errors will be reflected in the relative sizes of these two variables. These help determine whether we will stay with congestion avoidance or move onto slow start to get traffic moving again.

Much of the time it won’t be an issue, however on congested networks or perhaps where lots of clients are streaming video or voice it can make quite a difference.  If you analyse the performance whilst streaming a video from YouTube like this, then you can see for yourself the growth of errors when multiple clients start streaming from a variety of sources.