Comp 443 -- Alternative assignment using ns Dordal, December 2007 I've *finally* gotten ns working on xenon. All the materials are in /homes/users/cs/faculty/pld. You will have to copy some things from there to get ns to work. Let's call that directory PLDHOME. The file $PLDHOME/bin/ns is a three-line script that has all the exact paths for ns embedded in it. Copy that to your own directory (or $HOME/bin). This is your ns command. The directory $PLDHOME/ns is the build directory -- you won't need that. The examples are in $PLDHOME/ns_examples. All you really need are the *.tcl files; the rest are all generated by ns. *.nam files are for the animation. *.tr files are the actual trace files, listing the time each packet is sent from each node. Here are a few specific things to try. You may not be able to answer all the questions below, but you should at least consider them. Some of them are easy to answer; some require some sort of scripting to figure out what's going on. (See the queue-size script, below.) In $PLDHOME/ns_examples/basic1, I've done two tracefiles, one with a max window size of 20 (the default) and one with a max window size of 50. We saw the animation of the window_ = 20 example in class; the link "capacity" was about 22 and so once the steady state was reached there were no further losses. Examining the file basic1_20.tr (window_ = 20), one finds that the first lost packet is #23, at T=0.968288. (The initial 'd' on the line means the packet was lost (dropped), on the link from node 1 to node 2. The packet number, 23, is the second-to-last number on the line.) d 0.968288 1 2 tcp 1040 ------- 1 0.0 2.0 23 38 After that #25, #27 etc are lost, alternating. 1. How long does this alternating sequence of losses continue? Are these losses detected by fast retransmit, or are there timeouts? What is the next loss after this particular alternating sequence ends? How does basic1_50.tr compare? 2. What is the RTT of #24? This is the first packet following the loss. What is the RTT of the first packet packet after the above alternating sequence of losses? 3. When are these losses detected by the sender? What happens at that point? How does cwnd change? Are the losses all discovered together? How quickly does transmission resume? 4. When a loss is detected, is Slow Start followed as described in the book? (When I first did this simulation, some years ago, it was *not*; for one thing, transmission resumed with cwnd_ = 2, not cwnd_ = 1. What is going on in the current run?) 5. Are there any times when the queue is empty? See the awk scripts below. 6. How do things change when we switch to Reno? You will have to modify basic1.tcl for this, and then re-run ns. How are the first few losses detected now? Are there timeouts? What evidence is there of fast recovery? 7. Try setting ssthresh =20, which means the first loss occurs in the congestion-avoidance phase. What does this *mean*? How, qualitatively, does this change things? Is the throughput worse or better? Use either Tahoe or Reno. 8. When window_ = 20, once a steady state is achieved there are no losses and in fact no queue buildup. What happens when window_ = 50 (basic1_50.tr)? When is the last loss? (Easy: look for lines beginning 'd'.) How big does cwnd_ get? 9. In the previous example, with window_ = 50, can you restructure things (eg run the simulation longer, or reduce the delay times) so that cwnd_ has enough chance to exhibit some of the "tcp sawtooth" pattern? At least make sure there are a couple of losses. At what value of cwnd_ do the losses occor? At what value are they *detected*? When a loss occurs, does the queue drain? When we're back at the steady state of cwnd = cwnd_prev/2, is usage of the bottleneck link (the link between nodes 1 and 2) still saturated? Or are there now idle periods? --------------------------------------------------------------- The ns trace file here contains two types of lines. One type is the "trace variable" format, that indicates the time at which some variable is changed, and to what: 0.05123 0 0 2 0 ack_ 0 0.05123 0 0 2 0 cwnd_ 2.000 The first field here is the time, then come four fields relating to sender and receiver, then the variable name, and its new value. The other type of line, the most common type, describes a "packet event". Here are some examples: r 0.062032 0 1 tcp 1000 ------- 1 0.0 2.0 1 2 + 0.062032 1 2 tcp 1000 ------- 1 0.0 2.0 1 2 - 0.062032 1 2 tcp 1000 ------- 1 0.0 2.0 1 2 These lines consist of 12 fields: 1. disposition (+: arrival, -: departure, d: drop, r: received at far end) 2. time 3. link src 4. link dest 5. type, eg "tcp" 6. packet size 7. flag string, which we'll ignore 8. flowid, useful for distinguishing between multiple connections 9. srchost.srcport 10. dsthost.dstport 11. sequence number 12. unique packet id We'll only be concerned with a few of these. Queues are considered by ns to be attached to a _link_, eg from node 1 to node 2 in the second two lines above, and not to a node itself. The topology for the packet event lines above is 0--1--2, and the three lines shown describe a packet arriving at 1 on the 0-1 link and then departing on the 1-2 link. The first line, beginning "r", indicates that the packet arrives via the 0--1 link (3rd and 4th fields). The "+" line means that the packet was placed into the queue for the 1--2 link; the "-" line means the packet was then sent on the link and thus left the queue. That all these happened at the same instant (T=0.062032) means that there was no waiting. "r" events will usually be followed by "+" events immediately. Sometimes there will be "d" (drop) events, if there's no room in the queue. The "-" event may come a good deal later, if there is some queue buildup. Sometimes it helps to have text-analysis tools to work through the tracefiles; awk is one such. Perl is another. To answer the question above about whether the queue is ever empty, what you need to do is maintain a running total of the current queue size, and print out the times the queue size hits zero. Here is a simple script in the "awk" language, available on abel, that does this. Awk parses the input lines into fields, denoted $1 through $12 (though we only use $1 and $2 here). Awk is string-based; you can get further information from the "man" page, obtained on abel by typing "man awk", or else by searching on the web. We also look at fields $3 and $4 to make sur we're only looking at +/-/d events on the 1--2 link. The "next" operator (in braces below, as an "action") means to ignore the line further; think of "continue" in a C/Java loop. BEGIN {size=0; prevtime=0.0;sum=0.0;} $1 == "r" {next} $3 != 1 {next} $4 != 2 {next} $1 == "+" {size+=1} $1 == "-" {size-=1; if (size==0) print "size zero at ", $2} $1 == "d" {size-=1; print "size at drop is ", size, " ", sum} END {print "sum is ", sum, " final size is ", size} Put this into a file, say "queue_avg", and then run it via awk -f queue_avg mytracexy.tr Awk is also handy for searching for all lines in which packet 29, say, is moving from node 1 to node 2.