TDC 562/ Winter'02 Network Simulation Project: Studying the TCP and UDP Fairness on the Internet Jeffrey Absher In this assignment you will do network simulation experiments to using ns to show how TCP streams of the same traffic type (bulk vs. interactive traffic) coexist with each other. Also you will show how UDP streams impact others and compromise the bandwidth fairness in Internet. Initiate FTP traffic using TCP Reno from n1 to h1 and another FTP traffic that uses TCP Tahoe from n2 to h2. Each FTP traffic use packet size of 1024 bytes. Connect n3 and h3 with a TELNET stream and n4 with h4 with an HTTP stream. The HTTP traffic is generated between one Web client and one Web server such that HTTP request average rate (surfing rate) is 800 ms exponentially distributed. A typical page average consists of 4 objects where the average size of each object is 12 packets in constant distribution and the page pool size is 100 pages. The Web server is lightly loaded which enables sending requested objects every 15 ms in average exponentially distributed (inter-object arrival time). Finally, initiate an audio traffic using UDP from n5 to h5 such that the audio packet size 1000 bytes and the rate is 1 Mbps. FTP1/Reno n1 h1 | | FTP2 n2 |1Mb 1Mb| h2 \ | | / 1Mb\ | |/1Mb Telnet n3 ----- R1 ------>------ R2 ----- h3 1Mb/ | (RED/SFQ) |\1Mb / | | \ HTTP n4 |1Mb 1Mb| h4 | | CBR n5 h5 Running Scenario Start the traffic as follows: TELNET at time 0, FTP1 at time 3, FTP2 at time 5, HTTP at time 15, UDP at time 25. Stop UDP traffic at time 40 and then stop simulation and time 45. See Appendix A for sample tcl code for Part 1; Part 2 is similar code with opt(bw2) set to 2Mb and 1Mb, Part 4 is similar to Part 1 with opt(bw2) set to 1Mb and opt(rtrq) set to . Key Items to note: I placed the http server on the left-hand side (n4) and the client on the right (h4) to increase the contention for resources at router R1 and to maximize the left-to-right traffic flow. This assumes that the server-to-client transmission is larger (which it is). Email to grader confirmed that only the R1<->R2 link should be of different queue type, the host<>router links should remain DropTail In the assignment, it said “A typical page average consists of 4 objects…” I took this to mean that the number of objects in a page should be a constant distribution centered around 4. Note the setting of ftp to 1024-byte packets for ftp0 and ftp1 in the non-default settings section See Appendix B for the bash script used to extract data for all parts Part (1) Plot in two graphs the throughput in Mbps and number of packet dropped for FTP1, FTP2, TELNET, HTTP and UDP streams every 1 sec till the end of the simulation. (2 graphs – 20%) Part 1 Throughput 1.2 1 0.8 1_ftp1_thru_mbps 1_ftp2_thru_mbps 0.6 1_telnet_thru_mbps 1_http_thru_mbps 1_udp_thru_mbps 0.4 0.2 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 9 11 7 5 3 1 Se co nd s 0 Part 1 Dropped Packets 1 0.9 0.8 0.7 0.6 1_ftp1_drop 1_ftp2_drop 0.5 1_telnet_drop 1_http_drop 0.4 1_udp_drop 0.3 0.2 0.1 Se co 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 nd s 0 Part (2): Repeat Part(1) when L = 2 Mbps (2a) and 1 Mbps (2b) respectively (4 graphs – 40%). Part 2a Throughput 1.2 1 0.8 2a_ftp1_thru_mbps 2a_ftp2_thru_mbps 0.6 2a_telnet_thru_mbps 2a_http_thru_mbps 2a_udp_thru_mbps 0.4 0.2 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 9 11 7 5 3 1 Se co nd s 0 Part 2a Dropped Packets 4.5 4 3.5 3 2a_ftp1_drop 2a_ftp2_drop 2.5 2a_telnet_drop 2a_http_drop 2 2a_udp_drop 1.5 1 0.5 Se co 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 nd s 0 Part 2b Throughput 1.2 1 0.8 2b_ftp1_thru_mbps 2b_ftp2_thru_mbps 0.6 2b_telnet_thru_mbps 2b_http_thru_mbps 2b_udp_thru_mbps 0.4 0.2 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 9 11 7 5 3 1 Se co nd s 0 Part 2b Dropped Packets 40 35 30 25 2b_ftp1_drop 2b_ftp2_drop 20 2b_telnet_drop 2b_http_drop 2b_udp_drop 15 10 5 Se co 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 nd s 0 Part (3): Make R1 and R2 use SFQ instead of RED. Repeat part(1) when link L has 1 Mbps (2 graphs – 20%). Part 3 Throughput 1.2 1 0.8 3_ftp1_thru_mbps 3_ftp2_thru_mbps 0.6 3_telnet_thru_mbps 3_http_thru_mbps 3_udp_thru_mbps 0.4 0.2 0 co Se s nd 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 Part 3 Dropped Packets 100 90 80 70 60 3_ftp1_drop 3_ftp2_drop 50 3_telnet_drop 3_http_drop 40 3_udp_drop 30 20 10 Se co 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 9 11 7 5 3 1 nd s 0 Part (4): What is your observations and conclusion about the fairness of TCP and UDP in each part above (20%)? Part 1 had no contention and no dropped packets, therefore there was no fairness test. In Part 2a using RED with some contention, there were some packet drops for the tcp streams as well as some for the udp stream, When contention started, FTP2 (Tahoe) was better able to maintain its throughput than FTP1(reno), but reno did recover somewhat. This design (under “light” contention) maintained UDP at the expense of TCP, and dropped a similar absolute amount of packets for each connection. So if fairness is defined as picking a packet “roundrobin” from all of the current active connections to drop, this design is fair, but if fairness is defined as maintaining tcp at the expense of udp, or dropping a higher number of packets from the largest resource user, or allocating bandwidth, then this design is unfair. Even the sparse http and telnet streams experienced drops. Part 2b using RED with high contention, shows that udp is strongly favored over tcp connections. It appears that a udp stream can “bully” itself into being the favored stream. Also when contention started, FTP1 and FTP2 performed approximately the same, yet FTP2(tahoe) recovers from a slow link much more quickly. While udp did drop significantly more packets than any other protocol, it still also successfully delivered many more packets and starved the other tcp streams, . This is a consequence of tcp “playing nice” and having congestion control while udp does not. Again, the sparse protocol streams http and telnet did suffer, but not greatly with this set-up. The higher contention shows that RED is unfair to TCP streams, and to sparse streams. Part 3 using Stochastic Fair Queuing instead of Random Early Detection shows that SFQ allocates bandwidth significantly more fairly than RED in the presence of udp. While there are a few anomalies, the high network utilizers such as ftp1, ftp2, and udp, experience more dropped packets than the others, and the sparse streams experienced no drops. As well, ftp1 and ftp2 continued to use approximately one third of the total available bandwidth when the udp was started. For this particular experiment, I would conclude that SFQ is the fairest allocator of bandwidth, and it fairly drops packets because the number of packets dropped is relative to bandwidth demand. Appendix A… Sample tcl code #!/bin/sh set opt(tr) "ass3_1.tr" set opt(namtr) "" set opt(stop) 45 set set set set set set opt(bw1) 1Mb opt(delay1) 2ms opt(bw2) 4Mb opt(delay2) 15ms opt(ifq) DropTail opt(rtrq) RED proc finish {} { global env nshome pwd global ns opt trfd $ns flush-trace close $trfd exit 0 } proc create-trace {} { global ns opt if [file exists $opt(tr)] { catch "exec rm -f $opt(tr) $opt(tr)-bw [glob $opt(tr).*]" } set trfd [open $opt(tr) w] $ns trace-all $trfd if {$opt(namtr) != ""} { $ns namtrace-all [open $opt(namtr) w] } return $trfd } proc create-topology {} { global ns opt node ## first 5 nodes(n1-N5 = 0-4) for {set i 0} {$i < 5} {incr i} { set node($i) [$ns node] } ## second 5 nodes (h1-h5 as 6-9) for {set i 5} {$i < 10} {incr i} { set node($i) [$ns node] } ##routers (10 = R1, 11=R2) set node(10) [$ns node] set node(11) [$ns node] ##node-router links ##note I am using droptail for these links, and RED/SFQ for the Router-Router link. for {set i 0} {$i < 5} {incr i} { $ns duplex-link $node($i) $node(10) $opt(bw1) $opt(delay1) $opt(ifq) } for {set i 5} {$i < 10} {incr i} { $ns duplex-link $node($i) $node(11) $opt(bw1) $opt(delay1) $opt(ifq) } ##router-router link $ns duplex-link $node(10) $node(11) $opt(bw2) $opt(delay2) $opt(rtrq) } proc create-traffic {} { global ns opt node $ns rtproto DV set tcp0 [new Agent/TCP/Reno] set tcp1 [new Agent/TCP] set tcp2 [new Agent/TCP] #set tcp3 [new Agent/TCP] set udp4 [new Agent/UDP] set sink0 [new Agent/TCPSink] set sink1 [new Agent/TCPSink] set sink2 [new Agent/TCPSink] #set sink3 [new Agent/TCPSink] set sink4 [new Agent/Null] $ns attach-agent $node(0) $tcp0 $ns attach-agent $node(1) $tcp1 $ns attach-agent $node(2) $tcp2 #$ns attach-agent $node(3) $tcp3 $ns attach-agent $node(4) $udp4 $ns attach-agent $node(5) $sink0 $ns attach-agent $node(6) $sink1 $ns attach-agent $node(7) $sink2 #$ns attach-agent $node(8) $sink3 $ns attach-agent $node(9) $sink4 set set set set set ftp0 [new Application/FTP] ftp1 [new Application/FTP] telnet2 [new Application/Telnet] pgp3 [new PagePool/WebTraf] cbr4 [new Application/Traffic/CBR] $ftp0 attach-agent $tcp0 $ftp1 attach-agent $tcp1 $telnet2 attach-agent $tcp2 # $http3 attach-agent $tcp3 $cbr4 attach-agent $udp4 ##http extras $pgp3 $pgp3 $pgp3 $pgp3 $pgp3 set-num-server 1 set-num-client 1 set-server 0 $node(3) set-client 0 $node(8) set-num-session 1 set numPage 100 #interPage...hope that it is arrival of requests? set interPage [new RandomVariable/Exponential] $interPage set avg_ .8 #pageSize.. set pageSize [new RandomVariable/Constant] $pageSize set val_ 4 #inter-arrival time for obj set interObj [new RandomVariable/Exponential] $interObj set avg_ 0.015 #avg object size in pkts set objSize [new RandomVariable/Constant] $objSize set avg_ 12 ##non-default settings $cbr4 set packetSize_ 1000 $cbr4 set interval_ 8ms $ftp0 set packetSize_ 1024 $ftp1 set packetSize_ 1024 ##agent connections $ns connect $tcp0 $sink0 $ns connect $tcp1 $sink1 $ns connect $tcp2 $sink2 $pgp3 create-session 0 $numPage 15 $interPage $pageSize $interObj $objSize $ns connect $udp4 $sink4 ##start-stoptimes $ns at 3 "$ftp0 start" $ns at 5 "$ftp1 start" $ns at 0 "$telnet2 start" #$ns at 15 $pgp3 start $ns at 25 "$cbr4 start" $ns at 40 "$cbr4 stop" } ## MAIN ## set ns [new Simulator] set trfd [create-trace] create-topology create-traffic $ns at $opt(stop) "finish" $ns run Appendix B… Extraction bash script #!/usr/bin/bash for ((s=0; $s<45; s = $s+1)) do awk '$1=="d" && int($2)=='$s' && awk '$1=="d" && int($2)=='$s' && awk '$1=="d" && int($2)=='$s' && awk '$1=="d" && int($2)=='$s' && $5=="cbr" $5=="cbr" $5=="cbr" $5=="cbr" && && && && int($9)==4 int($9)==4 int($9)==4 int($9)==4 && && && && int($10)==9 int($10)==9 int($10)==9 int($10)==9 {xmit {xmit {xmit {xmit += += += += 1} 1} 1} 1} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_udp_drop_inpackets.txt; ass3_2a.tr >> ass3_2a_udp_drop_inpackets.txt; ass3_2b.tr >> ass3_2b_udp_drop_inpackets.txt; ass3_3.tr >> ass3_3_udp_drop_inpackets.txt; awk awk awk awk '$1=="d" '$1=="d" '$1=="d" '$1=="d" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==3 int($9)==3 int($9)==3 int($9)==3 && && && && int($10)==8 int($10)==8 int($10)==8 int($10)==8 {xmit {xmit {xmit {xmit += += += += 1} 1} 1} 1} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_http_drop_inpackets.txt; ass3_2a.tr >> ass3_2a_http_drop_inpackets.txt; ass3_2b.tr >> ass3_2b_http_drop_inpackets.txt; ass3_3.tr >> ass3_3_http_drop_inpackets.txt; awk awk awk awk '$1=="d" '$1=="d" '$1=="d" '$1=="d" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==2 int($9)==2 int($9)==2 int($9)==2 && && && && int($10)==7 int($10)==7 int($10)==7 int($10)==7 {xmit {xmit {xmit {xmit += += += += 1} 1} 1} 1} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_telnet_drop_inpackets.txt; ass3_2a.tr >> ass3_2a_telnet_drop_inpackets.txt; ass3_2b.tr >> ass3_2b_telnet_drop_inpackets.txt; ass3_3.tr >> ass3_3_telnet_drop_inpackets.txt; awk awk awk awk '$1=="d" '$1=="d" '$1=="d" '$1=="d" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==1 int($9)==1 int($9)==1 int($9)==1 && && && && int($10)==6 int($10)==6 int($10)==6 int($10)==6 {xmit {xmit {xmit {xmit += += += += 1} 1} 1} 1} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_ftp2_drop_inpackets.txt; ass3_2a.tr >> ass3_2a_ftp2_drop_inpackets.txt; ass3_2b.tr >> ass3_2b_ftp2_drop_inpackets.txt; ass3_3.tr >> ass3_3_ftp2_drop_inpackets.txt; awk awk awk awk '$1=="d" '$1=="d" '$1=="d" '$1=="d" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==0 int($9)==0 int($9)==0 int($9)==0 && && && && int($10)==5 int($10)==5 int($10)==5 int($10)==5 {xmit {xmit {xmit {xmit += += += += 1} 1} 1} 1} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_ftp1_drop_inpackets.txt; ass3_2a.tr >> ass3_2a_ftp1_drop_inpackets.txt; ass3_2b.tr >> ass3_2b_ftp1_drop_inpackets.txt; ass3_3.tr >> ass3_3_ftp1_drop_inpackets.txt; awk awk awk awk '$1=="r" '$1=="r" '$1=="r" '$1=="r" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==0 int($9)==0 int($9)==0 int($9)==0 && && && && int($10)==5 int($10)==5 int($10)==5 int($10)==5 && && && && $4==5 $4==5 $4==5 $4==5 {xmit {xmit {xmit {xmit += += += += $6} $6} $6} $6} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_ftp1_thru_inbytes.txt; ass3_2a.tr >> ass3_2a_ftp1_thru_inbytes.txt; ass3_2b.tr >> ass3_2b_ftp1_thru_inbytes.txt; ass3_3.tr >> ass3_3_ftp1_thru_inbytes.txt; awk awk awk awk '$1=="r" '$1=="r" '$1=="r" '$1=="r" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==1 int($9)==1 int($9)==1 int($9)==1 && && && && int($10)==6 int($10)==6 int($10)==6 int($10)==6 && && && && $4==6 $4==6 $4==6 $4==6 {xmit {xmit {xmit {xmit += += += += $6} $6} $6} $6} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_ftp2_thru_inbytes.txt; ass3_2a.tr >> ass3_2a_ftp2_thru_inbytes.txt; ass3_2b.tr >> ass3_2b_ftp2_thru_inbytes.txt; ass3_3.tr >> ass3_3_ftp2_thru_inbytes.txt; awk awk awk awk '$1=="r" '$1=="r" '$1=="r" '$1=="r" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==2 int($9)==2 int($9)==2 int($9)==2 && && && && int($10)==7 int($10)==7 int($10)==7 int($10)==7 && && && && $4==7 $4==7 $4==7 $4==7 {xmit {xmit {xmit {xmit += += += += $6} $6} $6} $6} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_telnet_thru_inbytes.txt; ass3_2a.tr >> ass3_2a_telnet_thru_inbytes.txt; ass3_2b.tr >> ass3_2b_telnet_thru_inbytes.txt; ass3_3.tr >> ass3_3_telnet_thru_inbytes.txt; awk awk awk awk '$1=="r" '$1=="r" '$1=="r" '$1=="r" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="tcp" $5=="tcp" $5=="tcp" $5=="tcp" && && && && int($9)==3 int($9)==3 int($9)==3 int($9)==3 && && && && int($10)==8 int($10)==8 int($10)==8 int($10)==8 && && && && $4==8 $4==8 $4==8 $4==8 {xmit {xmit {xmit {xmit += += += += $6} $6} $6} $6} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_http_thru_inbytes.txt; ass3_2a.tr >> ass3_2a_http_thru_inbytes.txt; ass3_2b.tr >> ass3_2b_http_thru_inbytes.txt; ass3_3.tr >> ass3_3_http_thru_inbytes.txt; awk awk awk awk '$1=="r" '$1=="r" '$1=="r" '$1=="r" && && && && int($2)=='$s' int($2)=='$s' int($2)=='$s' int($2)=='$s' && && && && $5=="cbr" $5=="cbr" $5=="cbr" $5=="cbr" && && && && int($9)==4 int($9)==4 int($9)==4 int($9)==4 && && && && int($10)==9 int($10)==9 int($10)==9 int($10)==9 && && && && $4==9 $4==9 $4==9 $4==9 {xmit {xmit {xmit {xmit += += += += $6} $6} $6} $6} END END END END {print {print {print {print '$s'": '$s'": '$s'": '$s'": " " " " xmit}' xmit}' xmit}' xmit}' ass3_1.tr >> ass3_1_udp_thru_inbytes.txt; ass3_2a.tr >> ass3_2a_udp_thru_inbytes.txt; ass3_2b.tr >> ass3_2b_udp_thru_inbytes.txt; ass3_3.tr >> ass3_3_udp_thru_inbytes.txt; done