ns-link.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:14k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. # Copyright (c) 1996 Regents of the University of California.
  3. # All rights reserved.
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. # 1. Redistributions of source code must retain the above copyright
  8. #    notice, this list of conditions and the following disclaimer.
  9. # 2. Redistributions in binary form must reproduce the above copyright
  10. #    notice, this list of conditions and the following disclaimer in the
  11. #    documentation and/or other materials provided with the distribution.
  12. # 3. All advertising materials mentioning features or use of this software
  13. #    must display the following acknowledgement:
  14. #  This product includes software developed by the MASH Research
  15. #  Group at the University of California Berkeley.
  16. # 4. Neither the name of the University nor of the Research Group may be
  17. #    used to endorse or promote products derived from this software without
  18. #    specific prior written permission.
  19. # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. # SUCH DAMAGE.
  30. #
  31. # @(#) $Header: /cvsroot/nsnam/ns-2/tcl/lib/ns-link.tcl,v 1.48 2004/10/28 23:35:39 haldar Exp $
  32. #
  33. Class Link
  34. Link set nl_ 0
  35. Link instproc init { src dst } {
  36. $self next
  37. # Debo
  38. $self instvar id_
  39. set id_ [Link set nl_]
  40.         Link set nl_ [expr $id_ + 1]
  41. # puts -nonewline "Link " 
  42. # puts " $id_  init"
  43.         #modified for interface code
  44. $self instvar trace_ fromNode_ toNode_ color_ oldColor_
  45. set fromNode_ $src
  46. set toNode_   $dst
  47. set color_ "black"
  48. set oldColor_ "black"
  49. set trace_ ""
  50. }
  51. Link instproc head {} {
  52. $self instvar head_
  53. return $head_
  54. }
  55. Link instproc add-to-head { connector } {
  56. $self instvar head_
  57. $connector target [$head_ target]
  58. $head_ target $connector
  59. }
  60. Link instproc queue {} {
  61. $self instvar queue_
  62. return $queue_
  63. }
  64. Link instproc link {} {
  65. $self instvar link_
  66. return $link_
  67. }
  68. Link instproc src {} { $self set fromNode_ }
  69. Link instproc dst {} { $self set toNode_ }
  70. Link instproc cost c { $self set cost_ $c }
  71. Link instproc cost? {} {
  72. $self instvar cost_
  73. if ![info exists cost_] {
  74. set cost_ 1
  75. }
  76. set cost_
  77. }
  78. # Debo
  79. Link instproc id {}  { $self set id_ }
  80. Link instproc setid { x } { $self set id_ $x }
  81. Link instproc bw {} { $self set bandwidth_ }
  82. Link instproc if-label? {} {
  83. $self instvar iif_
  84. $iif_ label
  85. }
  86. Link instproc up { } {
  87. $self instvar dynamics_ dynT_
  88. if ![info exists dynamics_] return
  89. $dynamics_ set status_ 1
  90. if [info exists dynT_] {
  91. foreach tr $dynT_ {
  92. $tr format link-up {$src_} {$dst_}
  93. set ns [Simulator instance]
  94. $self instvar fromNode_ toNode_
  95. $tr ntrace "l -t [$ns now] -s [$fromNode_ id] -d [$toNode_ id] -S UP"
  96. $tr ntrace "v -t [$ns now] link-up [$ns now] [$fromNode_ id] [$toNode_ id]"
  97. }
  98. }
  99. }
  100. Link instproc down { } {
  101. $self instvar dynamics_ dynT_
  102. if ![info exists dynamics_] {
  103. puts stderr "$class::$proc Link $self was not declared dynamic, and cannot be taken down.  ignored"
  104. return
  105. }
  106. $dynamics_ set status_ 0
  107. $self all-connectors reset
  108. if [info exists dynT_] {
  109. foreach tr $dynT_ {
  110. $tr format link-down {$src_} {$dst_}
  111. set ns [Simulator instance]
  112. $self instvar fromNode_ toNode_
  113. $tr ntrace "l -t [$ns now] -s [$fromNode_ id] -d [$toNode_ id] -S DOWN"
  114. $tr ntrace "v -t [$ns now] link-down [$ns now] [$fromNode_ id] [$toNode_ id]"
  115. }
  116. }
  117. }
  118. Link instproc up? {} {
  119. $self instvar dynamics_
  120. if [info exists dynamics_] {
  121. return [$dynamics_ status?]
  122. } else {
  123. return "up"
  124. }
  125. }
  126. Link instproc all-connectors op {
  127. foreach c [$self info vars] {
  128. $self instvar $c
  129. if ![info exists $c] continue
  130. if [array size $c] continue
  131. foreach var [$self set $c] {
  132. if [catch "$var info class"] {
  133. continue
  134. }
  135. if ![$var info class Node] { ;# $op on most everything
  136. catch "$var $op";# in case var isn't a connector
  137. }
  138. }
  139. }
  140. }
  141. Link instproc install-error {em} {
  142. $self instvar link_
  143. $em target [$link_ target]
  144. $link_ target $em
  145. }
  146. Class SimpleLink -superclass Link
  147. SimpleLink instproc init { src dst bw delay q {lltype "DelayLink"} } {
  148. $self next $src $dst
  149. $self instvar link_ queue_ head_ toNode_ ttl_
  150. $self instvar drophead_
  151. set ns [Simulator instance]
  152. set drophead_ [new Connector]
  153. $drophead_ target [$ns set nullAgent_]
  154. set head_ [new Connector]
  155. $head_ set link_ $self
  156. #set head_ $queue_ -> replace by the following
  157. # xxx this is hacky
  158. if { [[$q info class] info heritage ErrModule] == "ErrorModule" } {
  159. $head_ target [$q classifier]
  160.         } else {
  161.                 $head_ target $q
  162.         }
  163. set queue_ $q
  164. set link_ [new $lltype]
  165. $link_ set bandwidth_ $bw
  166. $link_ set delay_ $delay
  167. $queue_ target $link_
  168. $link_ target [$dst entry]
  169. $queue_ drop-target $drophead_
  170. # XXX
  171. # put the ttl checker after the delay
  172. # so we don't have to worry about accounting
  173. # for ttl-drops within the trace and/or monitor
  174. # fabric
  175. #
  176. set ttl_ [new TTLChecker]
  177. $ttl_ target [$link_ target]
  178. $self ttl-drop-trace
  179. $link_ target $ttl_
  180. # Finally, if running a multicast simulation,
  181. # put the iif for the neighbor node...
  182. if { [$ns multicast?] } {
  183. $self enable-mcast $src $dst
  184. }
  185.         $ns instvar srcRt_
  186. if [info exists srcRt_] {
  187.          if { $srcRt_ == 1 } {
  188.              $self enable-src-rt $src $dst $head_
  189.          }
  190. }
  191. }
  192. SimpleLink instproc enable-src-rt {src dst head} {
  193.     $self instvar ttl_
  194.     $src instvar src_agent_
  195.     $ttl_ target [$dst entry]
  196.     $src_agent_ install_slot $head [$dst id]
  197. }
  198. SimpleLink instproc enable-mcast {src dst} {
  199. $self instvar iif_ ttl_
  200. set iif_ [new NetworkInterface]
  201. $iif_ target [$ttl_ target]
  202. $ttl_ target $iif_
  203.         $src add-oif [$self head]  $self
  204.         $dst add-iif [$iif_ label] $self
  205. }
  206. # Debo
  207. SimpleLink instproc bw {} { 
  208. $self instvar link_
  209. $link_ set bandwidth_ 
  210. }
  211. SimpleLink instproc delay {} {
  212.         $self instvar link_
  213.         $link_ set delay_
  214. }
  215. SimpleLink instproc qsize {} {
  216. [$self queue] set limit_
  217. }
  218. #
  219. # should be called after SimpleLink::trace
  220. #
  221. SimpleLink instproc nam-trace { ns f } {
  222. $self instvar enqT_ deqT_ drpT_ rcvT_ dynT_
  223. #XXX 
  224. # we use enqT_ as a flag of whether tracing has been
  225. # initialized
  226. if [info exists enqT_] {
  227. $enqT_ namattach $f
  228. if [info exists deqT_] {
  229. $deqT_ namattach $f
  230. }
  231. if [info exists drpT_] {
  232. $drpT_ namattach $f
  233. }
  234. if [info exists rcvT_] {
  235. $rcvT_ namattach $f
  236. }
  237. if [info exists dynT_] {
  238. foreach tr $dynT_ {
  239. $tr namattach $f
  240. }
  241. }
  242. } else {
  243. $self trace $ns $f "nam"
  244. }
  245. }
  246. #
  247. # Build trace objects for this link and
  248. # update the object linkage
  249. #
  250. # create nam trace files if op == "nam"
  251. #
  252. SimpleLink instproc trace { ns f {op ""} } {
  253. $self instvar enqT_ deqT_ drpT_ queue_ link_ fromNode_ toNode_
  254. $self instvar rcvT_ ttl_ trace_
  255. $self instvar drophead_ ;# idea stolen from CBQ and Kevin
  256. set trace_ $f
  257. set enqT_ [$ns create-trace Enque $f $fromNode_ $toNode_ $op]
  258. set deqT_ [$ns create-trace Deque $f $fromNode_ $toNode_ $op]
  259. set drpT_ [$ns create-trace Drop $f $fromNode_ $toNode_ $op]
  260. set rcvT_ [$ns create-trace Recv $f $fromNode_ $toNode_ $op]
  261. $self instvar drpT_ drophead_
  262. set nxt [$drophead_ target]
  263. $drophead_ target $drpT_
  264. $drpT_ target $nxt
  265. $queue_ drop-target $drophead_
  266. # $drpT_ target [$queue_ drop-target]
  267. # $queue_ drop-target $drpT_
  268. $deqT_ target [$queue_ target]
  269. $queue_ target $deqT_
  270. # head is, like the drop-head_ a special connector.
  271. # mess not with it.
  272. $self add-to-head $enqT_
  273. # put recv trace after ttl checking, so that only actually 
  274. # received packets are recorded
  275. $rcvT_ target [$ttl_ target]
  276. $ttl_ target $rcvT_
  277. $self instvar dynamics_
  278. if [info exists dynamics_] {
  279. $self trace-dynamics $ns $f $op
  280. }
  281. }
  282. SimpleLink instproc trace-dynamics { ns f {op ""}} {
  283. $self instvar dynT_ fromNode_ toNode_
  284. lappend dynT_ [$ns create-trace Generic $f $fromNode_ $toNode_ $op]
  285. $self transit-drop-trace
  286. $self linkfail-drop-trace
  287. }
  288. SimpleLink instproc ttl-drop-trace args {
  289. $self instvar ttl_
  290. if ![info exists ttl_] return
  291. if {[llength $args] != 0} {
  292. $ttl_ drop-target [lindex $args 0]
  293. } else {
  294. $self instvar drophead_
  295. $ttl_ drop-target $drophead_
  296. }
  297. }
  298. SimpleLink instproc transit-drop-trace args {
  299. $self instvar link_
  300. if {[llength $args] != 0} {
  301. $link_ drop-target [lindex $args 0]
  302. } else {
  303. $self instvar drophead_
  304. $link_ drop-target $drophead_
  305. }
  306. }
  307. SimpleLink instproc linkfail-drop-trace args {
  308. $self instvar dynamics_
  309. if ![info exists dynamics_] return
  310. if {[llength $args] != 0} {
  311. $dynamics_ drop-target [lindex $args 0]
  312. } else {
  313. $self instvar drophead_
  314. $dynamics_ drop-target $drophead_
  315. }
  316. }
  317. #
  318. # Trace to a callback function rather than a file.
  319. #
  320. SimpleLink instproc trace-callback {ns cmd} {
  321. $self trace $ns {}
  322. foreach part {enqT_ deqT_ drpT_ rcvT_} {
  323. $self instvar $part
  324. set to [$self set $part]
  325. $to set callback_ 1
  326. $to proc handle a "$cmd $a"
  327. }
  328. }
  329. #
  330. # like init-monitor, but allows for specification of more of the items
  331. # attach-monitors $insnoop $inqm $outsnoop $outqm $dropsnoop $dropqm
  332. #
  333. SimpleLink instproc attach-monitors { insnoop outsnoop dropsnoop qmon } {
  334. $self instvar drpT_ queue_ snoopIn_ snoopOut_ snoopDrop_
  335. $self instvar qMonitor_ drophead_
  336. set snoopIn_ $insnoop
  337. set snoopOut_ $outsnoop
  338. set snoopDrop_ $dropsnoop
  339. $self add-to-head $snoopIn_
  340. $snoopOut_ target [$queue_ target]
  341. $queue_ target $snoopOut_
  342. set nxt [$drophead_ target]
  343. $drophead_ target $snoopDrop_
  344. $snoopDrop_ target $nxt
  345. # if [info exists drpT_] {
  346. # $snoopDrop_ target [$drpT_ target]
  347. # $drpT_ target $snoopDrop_
  348. # $queue_ drop-target $drpT_
  349. # } else {
  350. # $snoopDrop_ target [[Simulator instance] set nullAgent_]
  351. # $queue_ drop-target $snoopDrop_
  352. # }
  353. $snoopIn_ set-monitor $qmon
  354. $snoopOut_ set-monitor $qmon
  355. $snoopDrop_ set-monitor $qmon
  356. set qMonitor_ $qmon
  357. }
  358. # Added by Yun Wang, based on attach-monitors
  359. # like init-monitor, but allows for specification of more of the items
  360. # attach-taggers $insnoop $inqm
  361. #
  362. SimpleLink instproc attach-taggers { insnoop qmon } {
  363.         $self instvar drpT_ queue_ head_ snoopIn_ snoopOut_ snoopDrop_
  364.         $self instvar qMonitor_ drophead_
  365.         set snoopIn_ $insnoop
  366.         $snoopIn_ target $head_
  367.         set head_ $snoopIn_
  368.         $snoopIn_ set-monitor $qmon
  369. # This may cause problem when you want to insert both flow monitor and tagger.
  370. # Yun Wang
  371.         set qMonitor_ $qmon
  372. }
  373. #
  374. # Insert objects that allow us to monitor the queue size
  375. # of this link.  Return the name of the object that
  376. # can be queried to determine the average queue size.
  377. #
  378. SimpleLink instproc init-monitor { ns qtrace sampleInterval} {
  379. $self instvar qMonitor_ ns_ qtrace_ sampleInterval_
  380. set ns_ $ns
  381. set qtrace_ $qtrace
  382. set sampleInterval_ $sampleInterval
  383. set qMonitor_ [new QueueMonitor]
  384. $self attach-monitors [new SnoopQueue/In] 
  385. [new SnoopQueue/Out] [new SnoopQueue/Drop] $qMonitor_
  386. set bytesInt_ [new Integrator]
  387. $qMonitor_ set-bytes-integrator $bytesInt_
  388. set pktsInt_ [new Integrator]
  389. $qMonitor_ set-pkts-integrator $pktsInt_
  390. return $qMonitor_
  391. }
  392. SimpleLink instproc start-tracing { } {
  393. $self instvar qMonitor_ ns_ qtrace_ sampleInterval_
  394. $self instvar fromNode_ toNode_
  395. if {$qtrace_ != 0} {
  396. $qMonitor_ trace $qtrace_
  397. }
  398. $qMonitor_ set-src-dst [$fromNode_ id] [$toNode_ id]
  399. SimpleLink instproc queue-sample-timeout { } {
  400. $self instvar qMonitor_ ns_ qtrace_ sampleInterval_
  401. $self instvar fromNode_ toNode_
  402. set qavg [$self sample-queue-size]
  403. if {$qtrace_ != 0} {
  404. puts $qtrace_ "[$ns_ now] [$fromNode_ id] [$toNode_ id] $qavg"
  405. }
  406. $ns_ at [expr [$ns_ now] + $sampleInterval_] "$self queue-sample-timeout"
  407. }
  408. SimpleLink instproc sample-queue-size { } {
  409. $self instvar qMonitor_ ns_ qtrace_ sampleInterval_ lastSample_
  410. set now [$ns_ now]
  411. set qBytesMonitor_ [$qMonitor_ get-bytes-integrator]
  412. set qPktsMonitor_ [$qMonitor_ get-pkts-integrator]
  413. $qBytesMonitor_ newpoint $now [$qBytesMonitor_ set lasty_]
  414. set bsum [$qBytesMonitor_ set sum_]
  415. $qPktsMonitor_ newpoint $now [$qPktsMonitor_ set lasty_]
  416. set psum [$qPktsMonitor_ set sum_]
  417. if ![info exists lastSample_] {
  418. set lastSample_ 0
  419. }
  420. set dur [expr $now - $lastSample_]
  421. if { $dur != 0 } {
  422. set meanBytesQ [expr $bsum / $dur]
  423. set meanPktsQ [expr $psum / $dur]
  424. } else {
  425. set meanBytesQ 0
  426. set meanPktsQ 0
  427. }
  428. $qBytesMonitor_ set sum_ 0.0
  429. $qPktsMonitor_ set sum_ 0.0
  430. set lastSample_ $now
  431. #return "$meanBytesQ $meanPktsQ"
  432. $qMonitor_ instvar pdrops_ pdepartures_ parrivals_ bdrops_ bdepartures_ barrivals_
  433. return "$meanBytesQ $meanPktsQ $parrivals_ $pdepartures_ $pdrops_ $barrivals_ $bdepartures_ $bdrops_"
  434. }
  435. SimpleLink instproc dynamic {} {
  436. $self instvar dynamics_
  437. if [info exists dynamics_] return
  438. set dynamics_ [new DynamicLink]
  439. $self add-to-head $dynamics_
  440. $self transit-drop-trace
  441. $self all-connectors isDynamic
  442. }
  443. #
  444. # insert an "error module" BEFORE the queue
  445. # point the em's drop-target to the drophead
  446. #
  447. SimpleLink instproc errormodule args {
  448. $self instvar errmodule_ queue_ drophead_
  449. if { $args == "" } {
  450. return $errmodule_
  451. }
  452. set em [lindex $args 0]
  453. set errmodule_ $em
  454. $self add-to-head $em
  455. $em drop-target $drophead_
  456. }
  457. #
  458. # Insert a loss module AFTER the queue. 
  459. #
  460. # Must be inserted *RIGHT AFTER* the deqT_ (if present) or queue_, because
  461. # nam can only visualize a packet drop if and only if it is on the link or 
  462. # in the queue
  463. #
  464. SimpleLink instproc insert-linkloss args { 
  465. $self instvar link_errmodule_ queue_ drophead_ deqT_ 
  466. if { $args == "" } {
  467. return $link_errmodule_
  468. }
  469. set em [lindex $args 0]
  470. if [info exists link_errmodule_] {
  471. delete link_errmodule_
  472. }
  473. set link_errmodule_ $em
  474.         if [info exists deqT_] {
  475.                 $em target [$deqT_ target]
  476.                 $deqT_ target $em
  477.         } else {
  478.                 $em target [$queue_ target]
  479.                 $queue_ target $em
  480.         }
  481. $em drop-target $drophead_
  482. }