#inserts a delau spike into a TCP connection

#interval between handover and its length
set ho_int_min 20
set ho_int_max 40
set ho_len_min 5
set ho_len_max 10

#link parameters
set line_rate 30kbps
set prop_delay 300ms
set buf_size 100

#enables or disables Eifel response
Agent/TCP set eifel_ true
Agent/TCP set timestamps_ true 

#first delay is scheduled after this many secs
set first_delay 3

#size of FTP transfer
set send_size 300000

#sender: TCP,TCP/Reno,TCP/Newreno,TCP/Sack1, TCP/Fack
#TCP/FullTcp,TCP/FullTcp/Tahoe,TCP/FullTcp/Newreno,TCP/FullTcp/Sack
set tcp_snd TCP/Reno
#receiver: TCPSink,TCPSink/DelAck,TCPSink/Sack1,TCPSink/Sack1/DelAck,TCP/FullTcp 
set tcp_rcv TCPSink/DelAck

#Define a 'finish' procedure
proc finish {} {
    global ns tf

    #Close the trace file
    close $tf

    exec mkdir plots
   
    #Generate files to plot cwnd and t_seqno over time

    exec echo \"snd_data\" >plots/snd.xgr
    exec awk {$1=="+" && $5=="tcp" {print $2 "\t" $11}} out.tr >>plots/snd.xgr
    exec echo \n\"snd_ack\" >>plots/snd.xgr
    exec awk {$1=="r" && $5=="ack" {if ($13==0) t=$11; else t=$13; print $2 "\t" t}} out.tr >>plots/snd.xgr
    exec echo \"rcv_data\" >plots/rcv.xgr
    exec awk {$1=="r" && $5=="tcp" {print $2 "\t" $11}} out.tr >>plots/rcv.xgr
    exec echo \n\"rcv_ack\" >>plots/rcv.xgr
    exec awk {$1=="+" && $5=="ack" {if ($13==0) t=$11; else t=$13; print $2 "\t" t}} out.tr >>plots/rcv.xgr

    cd plots
    exec xgraph -P snd.xgr
    exec xgraph -P rcv.xgr
    exit 0
}

proc intercept {} {
	global ns rnd ho_int_min ho_int_max ho_len_min ho_len_max queue_ul queue_dl line_rate
	puts "[$ns now]: Intercept"
	$queue_ul block
	$queue_dl block

	set dly [$rnd uniform $ho_len_min $ho_len_max]
        $ns after $dly "$queue_ul unblock" 
	$ns after $dly "$queue_dl unblock"
        $ns after  [$rnd uniform $ho_int_min $ho_int_max] "intercept"
}

########################################################################
#
# M A I N
#
######################################################################

#Create a simulator object
set ns [new Simulator]

Trace set show_tcphdr_ 1
set tf [open out.tr w]
$ns trace-all $tf

# Prepare rnd generation
set rnd [new RNG]

#Create two nodes
set ms [$ns node]
set bs [$ns node]

set sender [new Agent/$tcp_snd]
set receiver [new Agent/$tcp_rcv]
Agent/TCP set bugFix_ false 
	
#Create a duplex link between the nodes
$ns duplex-link $bs $ms $line_rate $prop_delay DropTail

set link_dl [$ns link $bs $ms]
set link_ul [$ns link $ms $bs] 
set queue_dl [$link_dl queue]
set queue_ul [$link_ul queue]


###
# Configure bottleneck link bs<->ms
###
$ns queue-limit $bs $ms $buf_size
$ns queue-limit $ms $bs $buf_size

###
# Construct foreground traffic
###
$ns attach-agent $bs $sender
$sender set close_on_empty_ true
set ftp [new Application/FTP]
$ftp attach-agent $sender
$ns attach-agent $ms $receiver
$ns connect $sender $receiver

# Add agent traces and variable trace
$ns add-agent-trace $sender sender
$ns add-agent-trace $receiver receiver
$ns monitor-agent-trace $sender
$ns monitor-agent-trace $receiver

$ns after 0.1 "$ftp send $send_size"

#schedule first delay
$ns after $first_delay "intercept"
$ns after 50 "finish"

$ns run


