The ONL NPR Tutorial

NPR Tutorial >> Examples TOC

New Window?

TCP With Delay

[[ 2tcp-flows-resize.png Figure ]]

We demonstrate the interaction of two TCP flows going through a 300 Mbps bottleneck link (port 4 of the left NPR). This is the same configuration used in the first example in Filters, Queues and Bandwidth. But unlike UDP, TCP periodically sends ACK packets back to the senders (e.g., from n2p2 to n1p2 through the 2.1-1.4 link). Example A demonstrates the simple case where there are no extra delays between iperf TCP senders and receivers. Example B demonstrates how to add an artificial delay using the delay plugin.

The new concepts demonstrated by this example include:

Preparation

This example assumes that you have gone through the Filters, Queues and Bandwidth example which showed how filters were used to direct UDP traffic to a bottleneck link. As before, we use two shell scripts to start TCP senders and receivers. You can get these by copying them from the directory /users/onl/export/Examples/ into the directory on the ONL user host where you store your executables and shell scripts. Follow the same procedure for getting the shell scripts described in Filters, Queues and Bandwidth replacing the script names with those shown below:

File Description
trcvrs-2npr Start iperf TCP servers (receivers) on hosts n2p2 and n2p3
tsndrs-2npr Start iperf TCP clients (senders) on hosts n1p2 and n1p3

The example has two parts:

  1. Two TCP flows share reserved queue 64 at port 1.4
    Packets from TCP flows contend for the bottleneck output link in a FIFO manner.
  2. Add a delay plugin to delay ACK packets
    Install a delay plugin at port 2.1 that delays ACK packets returning to the sending host. Bandwidth displays show the outlines of a standard TCP Reno behavior where TCP attempts to fill the transmission pipe during slow-start and repeatedly probes for bandwidth by linearly increasing its send window and backing off when it encounters packet loss.
 

Example A: Two TCP flows share reserved queue 64 at port 1.4

Steps (In Brief)

We use the same dumbbell configuration and monitoring as in Example A except that we modify the filters to match on any protocol (*). Our setup will use the same forward path and use the reverse path for ACK packets sent by the receivers to the senders; e.g., ACK packets from both n2p2 and n2p3 will go to port 2.1, then out the link to port 1.4, and finally to the senders. The three charts will look different than those for UDP flows because of TCP's slow-start and congestion avoidance algorithms.

The main steps in Example A are:

  1. Start with the UDP configuration file
  2. Modify the new configuration file
  3. Start the two TCP receivers
  4. Start the two TCP senders
  5. Run the TCP senders longer

Steps (In Detail)

  1. Start with the UDP configuration file
  2. We will start with the configuration file created in the preceding example and modify it by modifying the filters at ports 1.2 and 1.3 and adding filters at ports 2.2 and 2.3 for the ACK packets. We will purposely change the protocol fields of the filters to match any protocol so that ping packets will take the same path as the TCP packets, allowing us to verify the delay in Example B.
  3. Modify the new configuration file
    We will change the filters at ports 1.2 and 1.3 to match on any protocol, and then commit and save the configuration.
  4. Start the two TCP receivers
    This procedure generally follows the same one for the UDP example except that we use the trcvrs-2npr shell script. The script will start an iperf TCP server process on each of the n2p2 and n2p3 hosts.
  5. Start the two TCP senders
    Now that the two TCP receivers are running, start sending traffic from the two senders at n1p2 and n1p3 using the tsndrs-2npr shell script. The procedure is the same as in the UDP example except that we now use the tsndrs-2npr shell script.
  6. Run the TCP senders longer
  7. We run the two TCP flows for 60 seconds (40 seconds longer than before) to see if the behavior of the two flows changes.
  8. We will not terminate the iperf TCP receivers since we will need them in Example B.
 

Example B: Add a delay plugin to delay ACK packets

We delay ACK packets by 20 milliseconds by installing a delay plugin at NPR 2 and installing filters at ports 2.2 and 2.3 to direct packets to the plugin. We also monitor the number of ACK packets being dropped at port 2.1. Here are a couple of things to keep in mind:

The main steps in Example B are:

  1. Modify the sender script to have no stagger and 60 seconds of traffic
  2. Install a delay plugin on NPR 2
  3. Configure queue 64 at ports 1.4 and 2.1
  4. Install filters at ports 2.2, and 2.3
  5. Verify packets are getting delayed
  6. Add queue 64, port 2.1 to the queue length chart
  7. Add packet drops to the drops chart
  8. Start the two TCP senders
  9. Get counts from the delay plugin
  10. Terminate the TCP receivers

Steps (In Detail)

  1. Modify the sender script to have no stagger and 60 seconds of traffic
  2. Removing the stagger will reduce the chance that late sender will immediately find a full queue when it starts. The script should now look like this where the "sleep 1" command has been commented out and the time has been changed to 60:
    1   #!/bin/sh
    2   source /users/onl/.topology    # get defs of external interfaces
    3   ssh $n1p2 /usr/local/bin/iperf -c n2p2 -w 16m -t 60 &
    4   ### sleep 1
    5   ssh $n1p3 /usr/local/bin/iperf -c n2p3 -w 16m -t 60 &
    
  3. Install a delay plugin on NPR 2
  4. Here are the mini-steps involved in installing a plugin that will delay all packets (including ACK packets) by 20 msec:
  5. Configure queue 64 at ports 1.4 and 2.1
  6. We change the size of queue 64 at port 1.4 to be equal to 750,000 bytes, the bandwidth-delay product, and we configure queue 64 at port 2.1 for the ACK packets.
    [[ queue-table-1.4.png Figure ]]
    [[ queue-table-2.1.png Figure ]]
    We have left the port rate at its default value of 1 Gbps.
  7. Install filters at ports 2.2, and 2.3
  8. We install filters at ports 2.2 and 2.3 to direct all packets to the delay plugin and then on to reserved queue 64 at port 2.1. The plan is use queue 64 so that we can verify that no ACK packets are getting dropped at port 2.1. The steps are similar to those used to install filters at ports 1.2 and 1.3 earlier. The primary difference is that you need to direct the packets to the plugin instead of just an output port.
  9. Verify packets are getting delayed
  10. Ping packets from either sender (n1p2 or n1p3) to a receiver (n2p2 or n2p3) should show RTTs of just over 20 msec. Also, the plugin counters should indicate a total of five packets passing through the plugin and a maximum at any time of one packet in the delay queue.
  11. Add queue 64, port 2.1 to the queue length chart
  12. The procedure is similar to what we did for queue 64 at port 1.4 earlier.
  13. Add packet drops to the drops chart
  14. The procedure is similar to what we did for port 1.4 earlier.
  15. Start the two TCP senders
  16. Use the version of tsndrs-2npr that run the senders for 60 sec. Follow the same procedure as in Example A for starting the two TCP senders from the onlusr host.
    [[ drops-300Mbps-20ms-60s-begin.png Figure ]]
    Both flows use the slow-start algorithm as they attempt to find the available bandwidth starting around time 2,304 (solid black line). At this time, queue 64 overflows, and the Queue Manager at port 1.4 drops about 998 packets. A small number of drops occur at times 2,315, 2,328 and 2,338. No drops occur at port 2.1 (dashed blue line).

    [[ bandwidth-300Mbps-20ms-60s-begin.png Figure ]]
    The 2.2 and 2.3 charts (solid red and dashed fuscia lines) indicate that both receivers start receiving traffic around time 2,304 but don't get much traffic until around time 2,313 (9 seconds later) when both start receiving about 150 Mbps of traffic. The 9 seconds that it takes the senders to recover from the large number of packet drops is not unusually since the initial retransmission timeout is probably 3 seconds.
    Around time 2,328, the flow to n2p2 starts to get more bandwidth than the flow to n2p3.

    [[ queue-length-300Mbps-20ms-60s-begin.png Figure ]]
    The chart shows that queue 64 at port 1.4 is occassionally reaching its capacity of 750,000 bytes.
    There are two features of the chart that may seem odd: With regard to the first oddity, it may be that the non-empty queue during slow-start was too short to be detected in a one second monitoring period. The second oddity may just be due to the queue draining while TCP is in fast recovery rather than additive increase.

    The charts covering the end of the 60-second transmission period show features that are similar to the period following the intial slow-start period.
    [[ drops-300Mbps-20ms-60s-end.png Figure ]]
    There are packet drops occassionally, but there are only a few packet drops at three time periods.

    [[ bandwidth-300Mbps-20ms-60s-end.png Figure ]]
    The traffic bandwidth to the two receivers (charts 2.2 and 2.3) continue to converge toward an equal share (150 Mbps) of the 300 Mbps link capacity.

    [[ queue-length-300Mbps-20ms-60s-end.png Figure ]]
    The queue length chart for queue 64 at port 1.4 continues to display a jagged appearance.

  17. Get counts from the delay plugin
  18. We send the plugin the =counts command to verify that the maximum size of the delay queue is the bandwidth-delay product.
  19. Terminate the TCP receivers
  20. The procedure is identical to the one used in Filters, Queues and Bandwidth and is repeated below.
    onlusr> source /users/onl/.topology    # .topology.csh if using a c-shell
    onlusr> ssh $n2p2 pkill iperf          # kill all iperf on $n2p2
    onlusr> ssh $n2p3 pkill iperf          # kill all iperf on $n2p3
    
 

Test Your Understanding

A Simple Configuration Change

Repeat Example B but with three flows instead of two after connecting hosts to ports 1.1 and 2.4. What is the effect of this configuration change?

A New Configuration

See if you can modify the configuration in Example B to include the following changes:

Repeat the experiment. Do the results make sense?

 Revised:  Wed, Oct 29, 2008 

  
  

NPR Tutorial >> Examples TOC