# detailed tracing of multiple competing hstcp and tcp flows
# with background traffic

# scoreboard.h  --- fix SBSIZE
# tcp-sink.h --- fix HS_MWS, to be a power of two. currently at 65536 

remove-all-packet-headers       ;# removes all except common
add-packet-header Flags IP TCP  ;# hdrs reqd for TCP

# qflag=1 enables queue monitoring
set qflag [lindex $argv 0]
# qflag: use monitoring?
set endtime [lindex $argv 1]
set hstcp [lindex $argv 2]
# hstcp: use high-speed TCP?
set delay 50
set bandwidth 1000
set hstcpflows 5 
set tcpflows 5 
set reversehstcpflows 5 

source utils.tcl 
source web.tcl

proc printlegend {} {
	global hstcpflows tcpflows
	puts "forward HSTCP traffic: flows 0 to [expr $hstcpflows - 1]"
	puts "forward TCP traffic: flows 10 to [expr 10 + $tcpflows - 1]"
	puts "forward small TCP traffic: class 100"
	puts "forward web traffic: class 102"
	puts "forward bursty TCP traffic: class 103"
	puts "reverse traffic: classes 99, 101"
}

set ns [new Simulator]
#ns-random 0

set n1 [$ns node]
set n2 [$ns node]

Queue/RED set gentle_ true 
Queue/RED set adaptive_ 1 
Queue/RED set bottom_ 0.001
Queue/RED set thresh_ 300 
Queue/RED set maxthresh_ 0
Queue/RED set q_weight_ 0 
Queue/RED set drop_tail_ 0
Queue/RED set setbit_ 1 

Agent/TCP set ecn_ 1 
Agent/TCP set window_ 100000
Agent/TCP set packetSize_ 1000 
Agent/TCP set overhead_ 0.000008
Agent/TCP set set max_ssthresh_ 1000

$ns duplex-link $n1 $n2 [expr $bandwidth]Mb [expr $delay]ms RED 
$ns queue-limit $n1 $n2 12500 
$ns queue-limit $n2 $n1 12500

#set em [new ErrorModel]
#$em unit pkt
#$em set rate_ 0.00
#$em ranvar [new RandomVariable/Uniform]
#$em drop-target [new Agent/Null]
#$ns lossmodel $em $n1 $n2 

if {$qflag} {
	set qmon [$ns monitor-queue $n1 $n2 ""]
	print-qstats 0.0 $endtime 
	set fmon [$ns makeflowmon Fid]
	$ns attach-fmon [$ns link $n1 $n2] $fmon
}

set rng_ [new RNG]

for {set i 0} {$i < 5} {incr i} { 

	set node_(s$i) [$ns node]
	set node_(k$i) [$ns node]
	$ns duplex-link $node_(s$i) $n1 10000Mb [expr $i*1.0] DropTail
	$ns duplex-link $node_(k$i) $n2 10000Mb [expr 10*$i+1]ms DropTail
}


# HSTCP traffic on the forward path
for {set i 0} {$i < $hstcpflows} {incr i} { 
	if {$hstcp==1} {
		set createType create-highspeed-connection 
	} else {
		set createType create-connection
	}
	set hstcp$i [$ns create-highspeed-connection TCP/Sack1 $n1 TCPSink/Sack1 $n2 $i]
	if {$hstcp==1} {
		[set hstcp$i] set windowOption_ 8 
	}
	set hsftp$i [[set hstcp$i] attach-app FTP]
	set sec [expr int(5*$i)] 
	set frac [expr int([$rng_ uniform 0 25])]
	set starttime $sec.$frac

	$ns at $starttime "[set hsftp$i] start"
	$ns at $endtime "[set hsftp$i] stop"
	print-stats [set hstcp$i] $starttime $endtime 
	#print-fstats $i [expr $starttime + 0.1] $endtime
	puts "hstcp$i, starttime: $starttime"
}

if {$hstcpflows > 0} {
	tcpDumpAll $hstcp0 1 hstcp0
}

for {set i 0} {$i < $tcpflows} {incr i} { 
	set tcp$i [$ns create-connection TCP/Sack1 $n1 TCPSink/Sack1 $n2 [expr 10 + $i]]
	set ftp$i [[set tcp$i] attach-app FTP]
	set sec [expr int(3*$i)] 
	set frac [expr int([$rng_ uniform 0 25])]
	set starttime $sec.$frac

	$ns at $starttime "[set ftp$i] start"
	$ns at $endtime "[set ftp$i] stop"
	print-stats [set tcp$i] $starttime $endtime 
	#print-fstats [expr 10 + $i] [expr $starttime + 0.1] $endtime
	puts "tcp$i, starttime: $starttime"
}


for {set i 0} {$i < $reversehstcpflows} {incr i} { 
	
	set dstnode [expr int([$rng_ uniform 0 4.99])]
	set hstcp [$ns create-highspeed-connection TCP/Sack1 $node_(k$i) TCPSink/Sack1 $node_(s$dstnode) 99]
	$hstcp set windowOption_ 8 
	$hstcp set packetSize 800
	set hsftp [$hstcp attach-app FTP]
	set sec [expr 7*$i] 
	set frac [expr int([$rng_ uniform 0 25])]
	set starttime $sec.$frac

	$ns at $starttime "$hsftp start"
	$ns at $endtime "$hsftp stop"
	puts "reverse hstcp $i, starttime: $starttime"
}

# Bursty traffic on forward path
set srcnode [expr int([$rng_ uniform 0 4.99])]
set dstnode [expr int([$rng_ uniform 0 4.99])]
set tcp [$ns create-connection TCP/Newreno $node_(s$srcnode) TCPSink $node_(k$dstnode) 103]
set ftp [$tcp attach-app FTP]
set starttime [$rng_ uniform 50 75]
set stoptime [expr $starttime + 10]
$ns at $starttime "$ftp start"
$ns at $stoptime "$ftp stop"
puts "bursty tcp, starttime: [format %.2f $starttime], stoptime: [format %.2f $stoptime]"

# TCP traffic on forward path 
set smalltcpflows 100 
for {set i 0} {$i < $smalltcpflows} {incr i} {

	set srcnode [expr int([$rng_ uniform 0 4.99])]
	set dstnode [expr int([$rng_ uniform 0 4.99])]
	set tcp [$ns create-connection TCP/Newreno $node_(s$srcnode) TCPSink $node_(k$dstnode) 100]
	$tcp set window_ 8
	set ftp [$tcp attach-app FTP]
	set starttime [$rng_ uniform 0 [expr $endtime/3]] 
	set stoptime [$rng_ uniform [expr ($endtime*2)/3] $endtime] 
	$ns at $starttime "$ftp start" 
	$ns at $stoptime "$ftp stop" 
	
	#puts "tcp in fwd direction from $starttime to $stoptime"
}


# TCP traffic on reverse path 
for {set i 0} {$i < $smalltcpflows} {incr i} {

	set srcnode [expr int([$rng_ uniform 0 4.99])]
	set dstnode [expr int([$rng_ uniform 0 4.99])]
	set tcp [$ns create-connection TCP/Newreno $node_(k$srcnode) TCPSink $node_(s$dstnode) 101]
	$tcp set packetSize 1500
	$tcp set window_ 8
	set ftp [$tcp attach-app FTP]
	set starttime [$rng_ uniform 0 [expr $endtime/3]] 
	set stoptime [$rng_ uniform [expr ($endtime*2)/3] $endtime] 
	$ns at $starttime "$ftp start" 
	$ns at $stoptime "$ftp stop" 
	
	#puts "tcp in reverse direction from $starttime to $stoptime"
}

set count 1
add_web_traffic $delay 10 4 10 10 102

if {$qflag} {
	set half [expr $endtime / 2]
	$ns at $half "printlegend; printall $fmon $half"
	$ns at $endtime "printlegend; printall $fmon $endtime"
	for {set i 0} {$i < $hstcpflows} {incr i} {
		$ns at $endtime "printdrops $i $fmon"
	}
	for {set i 10} {$i < [expr 10 + $tcpflows]} {incr i} {
		$ns at $endtime "printdrops $i $fmon"
	}
	for {set i 99} {$i < 103} {incr i} {
		$ns at $endtime "printdrops $i $fmon"
	}
}
$ns at [expr $endtime + 1.0] "finish"

set tf [open out.tr w]
#$ns trace-queue $n1 $n2 $tf 
#$ns trace-queue $n2 $n1 $tf 
 
puts "Starting Simulation..."
$ns run
