📄 ns-lib.tcl
字号:
Simulator instproc namtrace-all file { $self instvar namtraceAllFile_ if {$file != ""} { set namtraceAllFile_ $file } else { unset namtraceAllFile_ }}Simulator instproc namtrace-some file { $self instvar namtraceSomeFile_ set namtraceSomeFile_ $file}Simulator instproc namtrace-all-wireless {file optx opty} { $self instvar namtraceAllFile_ if {$file != ""} { set namtraceAllFile_ $file } else { unset namtraceAllFile_ } $self puts-nam-config "W -t * -x $optx -y $opty"} Simulator instproc initial_node_pos {nodep size} { $self puts-nam-config "n -t * -s [$nodep id] \-x [$nodep set X_] -y [$nodep set Y_] -Z [$nodep set Z_] -z $size \-v circle -c black"}Simulator instproc trace-all file { $self instvar traceAllFile_ set traceAllFile_ $file}Simulator instproc get-nam-traceall {} { $self instvar namtraceAllFile_ if [info exists namtraceAllFile_] { return $namtraceAllFile_ } else { return "" }}Simulator instproc get-ns-traceall {} { $self instvar traceAllFile_ if [info exists traceAllFile_] { return $traceAllFile_ } else { return "" }}# If exists a traceAllFile_, print $str to $traceAllFile_Simulator instproc puts-ns-traceall { str } { $self instvar traceAllFile_ if [info exists traceAllFile_] { puts $traceAllFile_ $str }}# If exists a traceAllFile_, print $str to $traceAllFile_Simulator instproc puts-nam-traceall { str } { $self instvar namtraceAllFile_ if [info exists namtraceAllFile_] { puts $namtraceAllFile_ $str } elseif [info exists namtraceSomeFile_] { puts $namtraceSomeFile_ $str }}# namConfigFile is used for writing color/link/node/queue/annotations. # XXX It cannot co-exist with namtraceAll.Simulator instproc namtrace-config { f } { $self instvar namConfigFile_ set namConfigFile_ $f}Simulator instproc get-nam-config {} { $self instvar namConfigFile_ if [info exists namConfigFile_] { return $namConfigFile_ } else { return "" }}# Used only for writing nam configurations to trace file(s). This is different# from puts-nam-traceall because we may want to separate configuration # informations and actual tracing informationSimulator instproc puts-nam-config { str } { $self instvar namtraceAllFile_ namConfigFile_ if [info exists namConfigFile_] { puts $namConfigFile_ $str } elseif [info exists namtraceAllFile_] { puts $namtraceAllFile_ $str } elseif [info exists namtraceSomeFile_] { puts $namtraceSomeFile_ $str }}Simulator instproc color { id name } { $self instvar color_ set color_($id) $name}Simulator instproc get-color { id } { $self instvar color_ return $color_($id)}# you can pass in {} as a null fileSimulator instproc create-trace { type file src dst {op ""} } { $self instvar alltrace_ set p [new Trace/$type] if [catch {$p set src_ [$src id]}] { $p set src_ $src } if [catch {$p set dst_ [$dst id]}] { $p set dst_ $dst } lappend alltrace_ $p if {$file != ""} { $p ${op}attach $file } return $p}Simulator instproc namtrace-queue { n1 n2 {file ""} } { $self instvar link_ namtraceAllFile_ if {$file == ""} { if ![info exists namtraceAllFile_] return set file $namtraceAllFile_ } $link_([$n1 id]:[$n2 id]) nam-trace $self $file}Simulator instproc trace-queue { n1 n2 {file ""} } { $self instvar link_ traceAllFile_ if {$file == ""} { if ![info exists traceAllFile_] return set file $traceAllFile_ } $link_([$n1 id]:[$n2 id]) trace $self $file}## arrange for queue length of link between nodes n1 and n2# to be tracked and return object that can be queried# to learn average q size etc. XXX this API still rough#Simulator instproc monitor-queue { n1 n2 qtrace { sampleInterval 0.1 } } { $self instvar link_ return [$link_([$n1 id]:[$n2 id]) init-monitor $self $qtrace $sampleInterval]}Simulator instproc queue-limit { n1 n2 limit } { $self instvar link_ [$link_([$n1 id]:[$n2 id]) queue] set limit_ $limit}Simulator instproc drop-trace { n1 n2 trace } { $self instvar link_ [$link_([$n1 id]:[$n2 id]) queue] drop-target $trace}Simulator instproc cost {n1 n2 c} { $self instvar link_ $link_([$n1 id]:[$n2 id]) cost $c}Simulator instproc attach-agent { node agent } { $node attach $agent}Simulator instproc attach-tbf-agent { node agent tbf } { $node attach $agent $agent attach-tbf $tbf}Simulator instproc detach-agent { node agent } { $self instvar nullAgent_ $node detach $agent $nullAgent_}## Helper proc for setting delay on an existing link#Simulator instproc delay { n1 n2 delay } { $self instvar link_ set sid [$n1 id] set did [$n2 id] if [info exists link_($sid:$did)] { set d [$link_($sid:$did) link] $d set delay_ $delay }}#XXX need to check that agents are attached to nodes alreadySimulator instproc connect {src dst} { $self simplex-connect $src $dst $self simplex-connect $dst $src return $src}Simulator instproc simplex-connect { src dst } { $src set dst_ [$dst set addr_] # Polly Huang: to support abstract TCP simulations if {[lindex [split [$src info class] "/"] 1] == "AbsTCP"} { $self at [$self now] "$self rtt $src $dst" $dst set class_ [$src set class_] } return $src}## Here are a bunch of helper methods.#Simulator proc instance {} { set ns [Simulator info instances] if { $ns != "" } { return $ns } foreach sim [Simulator info subclass] { set ns [$sim info instances] if { $ns != "" } { return $ns } } error "Cannot find instance of simulator"}Simulator instproc get-node-by-id id { $self instvar Node_ set Node_($id)}Simulator instproc all-nodes-list {} { $self instvar Node_ set nodes "" foreach n [array names Node_] { lappend nodes $Node_($n) } set nodes}Simulator instproc link { n1 n2 } { $self instvar Node_ link_ if { ![catch "$n1 info class Node"] } { set n1 [$n1 id] } if { ![catch "$n2 info class Node"] } { set n2 [$n2 id] } if [info exists link_($n1:$n2)] { return $link_($n1:$n2) } return ""}# Creates connection. First creates a source agent of type s_type and binds# it to source. Next creates a destination agent of type d_type and binds# it to dest. Finally creates bindings for the source and destination agents,# connects them, and returns the source agent.Simulator instproc create-connection {s_type source d_type dest pktClass} { set s_agent [new Agent/$s_type] set d_agent [new Agent/$d_type] $s_agent set fid_ $pktClass $d_agent set fid_ $pktClass $self attach-agent $source $s_agent $self attach-agent $dest $d_agent $self connect $s_agent $d_agent return $s_agent}# Creates connection. First creates a source agent of type s_type and binds# it to source. Next creates a destination agent of type d_type and binds# it to dest. Finally creates bindings for the source and destination agents,# connects them, and returns a list of source agent and destination agent.Simulator instproc create-connection-list {s_type source d_type dest pktClass} { set s_agent [new Agent/$s_type] set d_agent [new Agent/$d_type] $s_agent set fid_ $pktClass $d_agent set fid_ $pktClass $self attach-agent $source $s_agent $self attach-agent $dest $d_agent $self connect $s_agent $d_agent return [list $s_agent $d_agent]} # This seems to be an obsolete procedure.Simulator instproc create-tcp-connection {s_type source d_type dest pktClass} { set s_agent [new Agent/$s_type] set d_agent [new Agent/$d_type] $s_agent set fid_ $pktClass $d_agent set fid_ $pktClass $self attach-agent $source $s_agent $self attach-agent $dest $d_agent# $self connect $s_agent $d_agent return "$s_agent $d_agent"}Classifier instproc no-slot slot { #XXX should say something better for routing problem puts stderr "$self: no target for slot $slot" exit 1}## Other classifier methods overload the instproc-likes to track # and return the installed objects.#Classifier instproc install {slot val} { $self set slots_($slot) $val $self cmd install $slot $val}Classifier instproc installNext val { set slot [$self cmd installNext $val] $self set slots_($slot) $val set slot}Classifier instproc adjacents {} { $self array get slots_}Classifier instproc in-slot? slot { $self instvar slots_ set ret "" if {[array size slots_] < $slot} { set ret slots_($slot) } set ret}# dump is for debugging purposesClassifier instproc dump {} { $self instvar slots_ offset_ shift_ mask_ puts "classifier $self" puts "\t$offset_ offset" puts "\t$shift_ shift" puts "\t$mask_ mask" puts "\t[array size slots_] slots" foreach i [lsort -integer [array names slots_]] { set iv $slots_($i) puts "\t\tslot $i: $iv" }}Classifier/Hash instproc dump args { eval $self next $args $self instvar default_ puts "\t$default_ default"}Classifier/Hash instproc init nbuck { # we need to make sure that port shift/mask values are there # so we set them after they get their default values $self next $nbuck $self instvar shift_ mask_ set shift_ [AddrParams set NodeShift_(1)] set mask_ [AddrParams set NodeMask_(1)]}Simulator instproc makeflowmon { cltype { clslots 29 } } { set flowmon [new QueueMonitor/ED/Flowmon] set cl [new Classifier/Hash/$cltype $clslots] $cl proc unknown-flow { src dst fid hashbucket } { set fdesc [new QueueMonitor/ED/Flow] set dsamp [new Samples] $fdesc set-delay-samples $dsamp set slot [$self installNext $fdesc] $self set-hash $hashbucket $src $dst $fid $slot } $cl proc no-slot slotnum { # # note: we can wind up here when a packet passes # through either an Out or a Drop Snoop Queue for # a queue that the flow doesn't belong to anymore. # Since there is no longer hash state in the # hash classifier, we get a -1 return value for the # hash classifier's classify() function, and there # is no node at slot_[-1]. What to do about this? # Well, we are talking about flows that have already # been moved and so should rightly have their stats # zero'd anyhow, so for now just ignore this case.. # puts "classifier $self, no-slot for slotnum $slotnum" } $flowmon classifier $cl return $flowmon}# attach a flow monitor to a link# 3rd argument dictates whether early drop support is to be usedSimulator instproc attach-fmon {lnk fm { edrop 0 } } { set isnoop [new SnoopQueue/In] set osnoop [new SnoopQueue/Out] set dsnoop [new SnoopQueue/Drop] $lnk attach-monitors $isnoop $osnoop $dsnoop $fm if { $edrop != 0 } { set edsnoop [new SnoopQueue/EDrop] $edsnoop set-monitor $fm [$lnk queue] early-drop-target $edsnoop $edsnoop target [$self set nullAgent_] } [$lnk queue] drop-target $dsnoop}# Imported from session.tcl. It is deleted there.### to insert loss module to regular links in detailed SimulatorSimulator instproc lossmodel {lossobj from to} { set link [$self link $from $to] $link errormodule $lossobj}# This function generates losses that can be visualized by nam.Simulator instproc link-lossmodel {lossobj from to} { set link [$self link $from $to] $link insert-linkloss $lossobj}Simulator instproc bw_parse { bspec } { if { [scan $bspec "%f%s" b unit] == 1 } { set unit b } # xxx: all units should support X"ps" --johnh switch $unit { b { return $b } bps { return $b } kb { return [expr $b*1000] } Mb { return [expr $b*1000000] } Gb { return [expr $b*1000000000] } default { puts "error: bw_parse: unknown unit `$unit'" exit 1 } }}Simulator instproc delay_parse { dspec } { if { [scan $dspec "%f%s" b unit] == 1 } { set unit s } switch $unit { s { return $b } ms { return [expr $b*0.001] } ns { return [expr $b*0.000001] } default { puts "error: bw_parse: unknown unit `$unit'" exit 1 } }}#### Polly Huang: Simulator class instproc to support abstract tcp simulationsSimulator instproc rtt { src dst } { $self instvar routingTable_ delay_ set srcid [[$src set node_] id] set dstid [[$dst set node_] id] set delay 0 set tmpid $srcid while {$tmpid != $dstid} { set nextid [$routingTable_ lookup $tmpid $dstid] set tmpnode [$self get-node-by-id $tmpid] set nextnode [$self get-node-by-id $nextid] set tmplink [[$self link $tmpnode $nextnode] link] set delay [expr $delay + [expr 2 * [$tmplink set delay_]]] set delay [expr $delay + [expr 8320 / [$tmplink set bandwidth_]]] set tmpid $nextid } $src rtt $delay return $delay}Simulator instproc abstract-tcp {} { $self instvar TahoeAckfsm_ RenoAckfsm_ TahoeDelAckfsm_ RenoDelAckfsm_ dropper_ $self set TahoeAckfsm_ [new FSM/TahoeAck] $self set RenoAckfsm_ [new FSM/RenoAck] $self set TahoeDelAckfsm_ [new FSM/TahoeDelAck] $self set RenoDelAckfsm_ [new FSM/RenoDelAck] $self set nullAgent_ [new DropTargetAgent]}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -