# first.tcl
#
# This TCL script demonstrates the 4.3 BSD TCP with slow-start and
# congestion avoidance, showing packet loss and slow-start recovery.
#
# Advanced Data Communications (Fall, 1999), ns-vis1 group
# Daniel Hernandez/Scott Gammill
# Dr. Donahoo
# Baylor University



set ns [new Simulator]

# Set ns color indices
$ns color 0 blue
$ns color 1 red
$ns color 2 white

# Create 3 nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]

# Set node colors and shapes
$n0 shape hexagon
$n0 color red
$n0 label server
$n2 shape hexagon
$n2 color blue

# Open trace files
#set f [open out.tr w]
#$ns trace-all $f
set nf [open out.nam w]
$ns namtrace-all $nf

# Create 2 duplex links
$ns duplex-link $n0 $n1 1Mb 50ms DropTail
$ns duplex-link $n1 $n2 0.55Mb 50ms DropTail

# Set Node 1's queue size to 4
$ns queue-limit $n1 $n2 4

# Orient the nodes; show the queue
$ns duplex-link-op $n0 $n1 orient 10deg
$ns duplex-link-op $n1 $n2 orient 10deg
$ns duplex-link-op $n1 $n2 queuePos 0.5

# Create sender TCP agent at Node 0; set receiver advertised window to 8
set tcpSender [new Agent/TCP]
$tcpSender set window_ 8
$ns attach-agent $n0 $tcpSender

# Create CBR agent for TCP sender; set packet size to 1000 bytes, at 1 Mbps
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $tcpSender
$cbr set packet_size_ 1000
$cbr set rate_ 1Mbps

# Create receiver TCP agent at Node 0
set tcpReceiver [new Agent/TCPSink]
$ns attach-agent $n2 $tcpReceiver

# Connect the two TCP agents
$ns connect $tcpSender $tcpReceiver


# Welcome message and some explanations
$ns at 0.0 "$ns trace-annotate \"Welcome to the Scenario 3 demonstration of TCP with slow-start\""
$ns at 0.01 "$ns trace-annotate \"and congestion avoidance, showing packet drop.\""
$ns at 0.15 "$ns trace-annotate \"Here is the topology:  node 0 is the sender, and node 2 is the receiver.\""
$ns at 0.25 "$ns trace-annotate \"Node 1 is a router with a queue size of 4 packets.\""
$ns at 0.35 "$ns trace-annotate \"The link from nodes 0 to 1 is a 1-Mbps link, and the link from nodes 1 to 2 is 0.55 Mbps.\""
$ns at 0.50 "$ns trace-annotate \"You'll see the queue appear above Node 1 as it is being used.\"" 
$ns at 0.60 "$ns trace-annotate \"The TCP packet (segment) size is 1000 bytes.\""
$ns at 0.70 "$ns trace-annotate \"A packet will look bigger when it travels the 1-2 link than when it travels the 0-1 link,\""
$ns at 0.71 "$ns trace-annotate \"to show that the packet has to be 'squeezed' into the smaller pipe.\""

# Slow-start
$ns at 0.85 "$ns trace-annotate \" \""
$ns at 0.86 "$ns trace-annotate \"Let's watch the show.\""
$ns at 0.87 "$ns trace-annotate \"Node 2 advertises a receiver window of 8 packets.\""
$ns at 0.88 "$ns trace-annotate \"Node 0 begins with its congestion window (cwnd) at 1 and sends 1 packet...\""
$ns at 1.12 "$ns trace-annotate \"Node 2 acks...\""
$ns at 1.23 "$ns trace-annotate \"Node 0 increases its congestion window by 1 and sends 2 packets...\""
$ns at 1.36 "$ns trace-annotate \"Two acks coming back...\""
$ns at 1.46 "$ns trace-annotate \"Node 0 gets 2 acks and thus increases its window by 2 (now 4).\""
$ns at 1.48 "$ns trace-annotate \"(See the queue in use.)\""
$ns at 1.59 "$ns trace-annotate \"Four more acks coming back...\""
$ns at 1.68 "$ns trace-annotate \"These 4 acks cause Node 0's congestion window to open to 8...\""

# Packet dropped
$ns at 1.78 "$ns trace-annotate \"Node 1 is dropping the 8th packet!\""
$ns at 1.83 "$ns trace-annotate \"Only acks for the 7 packets are coming back.\""
$ns at 1.90 "$ns trace-annotate \"Node 0's window would open up upon receiving these acks, but it isn't because the receiver window size is 8.\""
$ns at 1.97 "$ns trace-annotate \"Node 0 is still waiting on an ack for the packet #8 that was dropped...\"" 
# Slow-start again
$ns at 2.14 "$ns trace-annotate \"Node 0 times out on that packet and reinitiates Slow-Start...\""
$ns at 2.20 "$ns trace-annotate \"Node 0's congestion window (cwnd) is now 1.\""
$ns at 2.21 "$ns trace-annotate \"Its congestion-avoidance threshold is 4 (half of its previous congestion window size--8).\""
$ns at 2.37 "$ns trace-annotate \"Node 0's congestion window is now 2.\""
$ns at 2.61 "$ns trace-annotate \"Node 0's congestion window is now 4 (the threshold).\""

# Congestion avoidance
$ns at 2.82 "$ns trace-annotate \"Node 0 has begun the Congestion Avoidance algorithm:  cwnd+=1/cwnd.  cwnd is still 4 for this round-trip.\""
$ns at 3.04 "$ns trace-annotate \"Node 0's congestion window increments to 5...\""
$ns at 3.27 "$ns trace-annotate \"Node 0's congestion window increments to 6...\""
$ns at 3.49 "$ns trace-annotate \"Node 0's congestion window increments to 7...\""
$ns at 3.72 "$ns trace-annotate \"Node 0's congestion window increments to 8...\""
$ns at 3.94 "$ns trace-annotate \"Node 0's congestion window remains at 8 because the receiver's advertised window is 8.\""

# Finish simulation
$ns at 4.01 "$ns trace-annotate \"The simulation continues, with 8 packets being sent per round trip.\""
$ns at 4.20 "$ns trace-annotate \"This concludes this simulation of TCP with slow-start and congestion avoidance.\""


# Run the simulation
$ns at 1.0 "$cbr start"
$ns at 4.5 "finish"

proc finish {} {
#    global ns nf f
    global ns nf
    $ns flush-trace
#    close $f
    close $nf

    puts "running nam..."
    exec nam out.nam &
    exit 0
}

$ns run


