Wednesday, July 3, 2024
HomeData ModellingData Structure & AlgorithmProgram to find the final size of Congestion Window in TCP Reno

Program to find the final size of Congestion Window in TCP Reno

Given the initial congestion window size cwnd, threshold value ssthresh, connection time rtt and an array arr where arr[i] implies the time when a packet loss is detected. The task is to find the final congestion window size when all the packet drops are being encountered by the sender. 

The TCP Reno follows below conditions:

  • The initial value of cwnd is 1.
  • Before reaching ssthresh, double cwnd per unit of time. By doubling the value, cwnd can’t cross ssthresh value, it can almost go up to ssthresh value.
  • After reaching ssthresh, increase cwnd by 1 per unit of time.
  • When there is packet loss, reduce the cwnd and ssthresh to half of cwnd value (50%) and no other updation happens.
  • Connection will be active until rtt unit of time.

Examples:

Input arr[] = {16, 22}, ssthresh = 32, rtt = 26
Output: 17
Explanation:
Time = 0: cwnd = 1
Time = 1: cwnd = 2
Time = 2, 3, 4, 5: cwnd = 4, 8, 16, 32
cwnd=ssthresh at time=5, so now onwards cwnd increases by 1 per unit of time.
Time = 6-15: cwnd = 33-42
Time = 16: packet loss is detected, so ssthresh and cwnd will become half of current cwnd value.
cwnd = ssthresh = 21, Note: cwnd is not increased by 1 or doubled in this case. 
Time = 17-21: cwnd = 22-26
Time = 22: packet loss is detected, so ssthresh and cwnd will become half of current cwnd value.
cwnd = ssthresh = 13
Time = 23-26: cwnd = 14-17
Final cwnd is = 17

Input arr[] = {12, 25, 37, 42}, ssthresh = 30, rtt = 50
Output: The final cwnd value is= 16
Explanation:
Time = 0: cwnd = 1
Time = 1: cwnd = 2
Time = 2, 3, 4: cwnd = 4, 8, 16
Time = 5: cwnd = 30 {cwnd can’t get doubled because 32>30, it will cross the ssthresh. It can go max upto ssthresg}
Time = 6-11: cwnd = 31-36
Time = 12: cwnd = 36/2 and ssthresh = 18 {Packet loss}
Time = 13-24: cwnd = 19-30
Time = 25: cwnd = ssthresh = 30/2 = 15   {Packet loss}
Time = 26-36: cwnd = 16-26
Time = 37: cwnd = ssthresh = 26/2 = 13   {Packet loss}
Time = 38-41: cwnd = 14-17
Time = 42: cwnd = ssthresh = 17/2 = 8   {Packet loss}
Time = 43-50: cwnd = 9-16
The final cwnd value is= 16

 

Approach: The solution is based on the comparison of cwnd and ssthresh values.Follow below steps:

  • Traverse through all the time units when the connection is alive.
  • Store next packet loss time in variable timeout
  • Check if the current time is equal to timeout. If it is, then reduce the cwnd and ssthresh = cwnd/2
  • If cwnd is less than ssthresh, then double the cwnd value.
  • If double of cwnd is greater than ssthresh then set cwnd=ssthresh.
  • If cwnd is greater than ssthresh then increment cwnd by 1 per time.
  • Return final cwnd value after loop terminates.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// TCP Reno Utility function
int tcpRenoCongestionWindow(int cwnd,
                            int ssthresh, int rtt,
                            vector<int> time)
{
    int ind = 0, timeout = time[ind];
    for (int t = 1; t <= rtt; t++) {
 
        // Packet loss occurs.
        // Reduce cwnd and ssthresh to
        // half of current cwnd value
        if (t == timeout) {
            cwnd = cwnd / 2;
            ssthresh = cwnd;
            timeout = time[++ind];
            continue;
        }
 
        // Threshold is not reached.
        // keep doubling
        if (cwnd < ssthresh)
            cwnd = min(2 * cwnd, ssthresh);
 
        // Threshold is reached.
        // Increase additively.
        else
            cwnd += 1;
    }
 
    // Return final cwnd value.
    return cwnd;
}
 
// Driver code
int main()
{
    int cwnd = 1;
    int ssthresh = 30;
    int rtt = 50;
    vector<int> time{ 12, 25, 37, 42 };
    cwnd = tcpRenoCongestionWindow(cwnd, ssthresh, rtt,
                                   time);
    cout << "Final congestion window size = " << cwnd;
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
public class GFG {
 
  // TCP Reno Utility function
  static int tcpRenoCongestionWindow(int cwnd,
                                     int ssthresh,
                                     int rtt, int[] time)
  {
    int ind = 0, timeout = time[ind];
    for (int t = 1; t <= rtt; t++) {
 
      // Packet loss occurs.
      // Reduce cwnd and ssthresh to
      // half of current cwnd value
      if (t == timeout) {
        cwnd = cwnd / 2;
        ssthresh = cwnd;
        ind += 1;
        if (ind == time.length) {
          continue;
        }
        timeout = time[ind];
 
        continue;
      }
 
      // Threshold is not reached.
      // keep doubling
      if (cwnd < ssthresh)
        cwnd = Math.min(2 * cwnd, ssthresh);
 
      // Threshold is reached.
      // Increase additively.
      else
        cwnd += 1;
    }
 
    // Return final cwnd value.
    return cwnd;
  }
 
  // Driver code
  public static void main(String args[])
  {
    int cwnd = 1;
    int ssthresh = 30;
    int rtt = 50;
    int[] time = { 12, 25, 37, 42 };
    cwnd = tcpRenoCongestionWindow(cwnd, ssthresh, rtt,
                                   time);
    System.out.print("Final congestion window size = "
                     + cwnd);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python3




# Python 3 code to implement the approach
 
# TCP Reno Utility function
def tcpRenoCongestionWindow(cwnd,
                            ssthresh, rtt, time):
 
    ind = 0
    timeout = time[ind]
    for t in range(1, rtt + 1):
 
        # Packet loss occurs.
        # Reduce cwnd and ssthresh to
        # half of current cwnd value
        if (t == timeout):
            cwnd = cwnd // 2
            ssthresh = cwnd
            ind += 1
            if(ind == len(time)):
              continue
            timeout = time[ind]
 
            continue
 
        # Threshold is not reached.
        # keep doubling
        if (cwnd < ssthresh):
            cwnd = min(2 * cwnd, ssthresh)
 
        # Threshold is reached.
        # Increase additively.
        else:
            cwnd += 1
 
    # Return final cwnd value.
    return cwnd
 
# Driver code
if __name__ == "__main__":
 
    cwnd = 1
    ssthresh = 30
    rtt = 50
    time = [12, 25, 37, 42]
    cwnd = tcpRenoCongestionWindow(cwnd, ssthresh, rtt,
                                   time)
    print("Final congestion window size = ", cwnd)
 
    # This code is contributed by ukasp.


C#




// C# code to implement the approach
using System;
class GFG {
 
  // TCP Reno Utility function
  static int tcpRenoCongestionWindow(int cwnd,
                                     int ssthresh,
                                     int rtt, int[] time)
  {
    int ind = 0, timeout = time[ind];
    for (int t = 1; t <= rtt; t++) {
 
      // Packet loss occurs.
      // Reduce cwnd and ssthresh to
      // half of current cwnd value
      if (t == timeout) {
        cwnd = cwnd / 2;
        ssthresh = cwnd;
        ind += 1;
        if (ind == time.Length) {
          continue;
        }
        timeout = time[ind];
 
        continue;
      }
 
      // Threshold is not reached.
      // keep doubling
      if (cwnd < ssthresh)
        cwnd = Math.Min(2 * cwnd, ssthresh);
 
      // Threshold is reached.
      // Increase additively.
      else
        cwnd += 1;
    }
 
    // Return final cwnd value.
    return cwnd;
  }
 
  // Driver code
  public static void Main()
  {
    int cwnd = 1;
    int ssthresh = 30;
    int rtt = 50;
    int[] time = { 12, 25, 37, 42 };
    cwnd = tcpRenoCongestionWindow(cwnd, ssthresh, rtt,
                                   time);
    Console.Write("Final congestion window size = "
                  + cwnd);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
       // JavaScript code for the above approach
 
 
       // TCP Reno Utility function
       function tcpRenoCongestionWindow(cwnd,
           ssthresh, rtt, time) {
           let ind = 0, timeout = time[ind];
           for (let t = 1; t <= rtt; t++) {
 
               // Packet loss occurs.
               // Reduce cwnd and ssthresh to
               // half of current cwnd value
               if (t == timeout) {
                   cwnd = Math.floor(cwnd / 2);
                   ssthresh = cwnd;
                   timeout = time[++ind];
                   continue;
               }
 
               // Threshold is not reached.
               // keep doubling
               if (cwnd < ssthresh)
                   cwnd = Math.min(2 * cwnd, ssthresh);
 
               // Threshold is reached.
               // Increase additively.
               else
                   cwnd += 1;
           }
 
           // Return final cwnd value.
           return cwnd;
       }
 
       // Driver code
       let cwnd = 1;
       let ssthresh = 30;
       let rtt = 50;
       let time = [12, 25, 37, 42];
       cwnd = tcpRenoCongestionWindow(cwnd, ssthresh, rtt,
           time);
       document.write("Final congestion window size = " + cwnd);
 
    // This code is contributed by Potta Lokesh
   </script>


 
 

Output

Final congestion window size = 16

 

Time Complexity: O(N), N is the time of connection activeness.
Auxiliary Space: O(1)

 

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

Nokonwaba Nkukhwana
Experience as a skilled Java developer and proven expertise in using tools and technical developments to drive improvements throughout a entire software development life cycle. I have extensive industry and full life cycle experience in a java based environment, along with exceptional analytical, design and problem solving capabilities combined with excellent communication skills and ability to work alongside teams to define and refine new functionality. Currently working in springboot projects(microservices). Considering the fact that change is good, I am always keen to new challenges and growth to sharpen my skills.
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments