1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#
# A simple (but not too realistic) rate-based congestion control
# scheme for Homework 3 in CS268.
#
# $Header: /cvsroot/nsnam/ns-2/tcl/ex/rc.tcl,v 1.4 1998/09/01 17:01:19 tomh Exp $
#
source timer.tcl
set ns [new Simulator]
proc build_topology { ns which } {
$ns color 1 red
$ns color 2 white
foreach i "0 1 2 3" {
global n$i
set tmp [$ns node]
set n$i $tmp
}
$ns duplex-link $n0 $n2 5Mb 2ms DropTail
$ns duplex-link $n1 $n2 5Mb 2ms DropTail
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
if { $which == "FIFO" } {
$ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
} elseif { $which == "RED" } {
$ns duplex-link $n2 $n3 1.5Mb 10ms RED
} else {
$ns duplex-link $n2 $n3 1.5Mb 10ms FQ
}
$ns duplex-link-op $n2 $n3 orient right
$ns duplex-link-op $n2 $n3 queuePos 0.5
}
Class Agent/Message/Sender -superclass {Agent/Message Timer}
Class Agent/Message/Receiver -superclass Agent/Message
Agent/Message/Sender instproc init {} {
$self next
$self instvar cbr_ seq_ udp_
set udp_ [new Agent/UDP]
set cbr_ [new Application/Traffic/CBR]
$cbr_ attach-agent $udp_
set seq_ 1
$self sched [$self randomize 0.05]
}
Agent/Message/Sender instproc randomize v {
return [expr $v * (1.0 + [ns-random] / 2147483647.)]
}
Agent/Message/Sender instproc timeout {} {
global ns
$self send "probe [$ns now]"
$self sched [$self randomize 0.05]
}
Agent/Message/Sender instproc handle msg {
set type [lindex $msg 0]
if { $type == "congested" } {
$self decrease
} else {
$self increase
}
}
Agent/Message/Sender instproc increase {} {
$self instvar cbr_
set delta [$cbr_ set interval_]
set delta [expr 1.0 / (1.0 / $delta + 100)]
$cbr_ set interval_ $delta
}
Agent/Message/Sender instproc decrease {} {
$self instvar cbr_
set delta [$cbr_ set interval_]
set delta [expr 2 * $delta]
$cbr_ set interval_ $delta
}
Agent/Message/Receiver instproc init {} {
$self next
$self instvar mon_ congested_
set mon_ [new Agent/LossMonitor]
$mon_ proc log-loss {} "$self log-loss"
set congested_ 0
}
Agent/Message/Receiver instproc log-loss {} {
global ns
$self instvar congested_
if !$congested_ {
$self send "congested 0"
set congested_ 1
}
}
Agent/Message/Receiver instproc handle msg {
$self instvar congested_
if $congested_ {
set congested_ 0
} else {
$self send "uncongested [lindex $msg 1]"
}
}
proc build_conn { from to startTime } {
global ns
set src [new Agent/Message/Sender]
set sink [new Agent/Message/Receiver]
$ns attach-agent $from $src
$ns attach-agent $to $sink
$ns connect $src $sink
$ns attach-agent $from [$src set udp_]
$ns attach-agent $to [$sink set mon_]
$ns connect [$src set udp_] [$sink set mon_]
$ns at $startTime "[$src set cbr_] start"
return [$src set udp_]
}
set f [open out.tr w]
$ns trace-all $f
set nf [open out.nam w]
$ns namtrace-all $nf
build_topology $ns FIFO
set c1 [build_conn $n0 $n3 0.1]
$c1 set class_ 1
set c2 [build_conn $n1 $n3 0.1]
$c2 set class_ 2
$ns at 5.0 "finish"
proc finish {} {
global ns f nf
$ns flush-trace
close $f
close $nf
#XXX
puts "running nam..."
exec nam out.nam &
exit 0
}
$ns run
|