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

通讯编程

开发平台:

Visual C++

  1. #
  2. # tcl/mcast/DM.tcl
  3. #
  4. # Copyright (C) 1997 by USC/ISI
  5. # All rights reserved.                                            
  6. #                                                                
  7. # Redistribution and use in source and binary forms are permitted
  8. # provided that the above copyright notice and this paragraph are
  9. # duplicated in all such forms and that any documentation, advertising
  10. # materials, and other materials related to such distribution and use
  11. # acknowledge that the software was developed by the University of
  12. # Southern California, Information Sciences Institute.  The name of the
  13. # University may not be used to endorse or promote products derived from
  14. # this software without specific prior written permission.
  15. # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
  16. # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18. # Ported/Modified by Polly Huang (USC/ISI), http://www-scf.usc.edu/~bhuang
  19. Class DM -superclass McastProtocol
  20. DM set PruneTimeout  0.5
  21. DM set CacheMissMode pimdm ;#or dvmrp (lowercase)
  22. DM instproc init { sim node } {
  23. $self instvar mctrl_
  24. set mctrl_ [new Agent/Mcast/Control $self]
  25. $node attach $mctrl_
  26. Timer/Iface/Prune set timeout [[$self info class] set PruneTimeout]
  27. $self next $sim $node
  28. }
  29. DM instproc join-group  { group } {
  30. $self instvar node_
  31. $self next $group
  32. set listOfReps [$node_ getReps * $group]
  33. foreach r $listOfReps {
  34. if ![$r is-active] {
  35. $self send-ctrl "graft" [$r set srcID_] $group
  36. set nbr [$node_ rpf-nbr [$r set srcID_]]
  37. set nbrs($nbr) 1
  38. }
  39. }
  40. foreach nbr [array names nbrs] {
  41. if [$nbr is-lan?] {
  42. # for each LAN we maintain an array of  counters 
  43. # of how many local receivers we have on the lan 
  44. # for a given group
  45. $nbr instvar receivers_
  46. if [info exists receivers_($group)] {
  47. incr receivers_($group)
  48. } else {
  49. set receivers_($group) 1
  50. }
  51. }
  52. }
  53. }
  54. DM instproc leave-group { group } {
  55.         $self next $group
  56. $self instvar node_
  57. # lan: decrement counters
  58. set listOfReps [$node_ getReps * $group]
  59. foreach r $listOfReps {
  60. set nbr [$node_ rpf-nbr [$r set srcID_]]
  61. set nbrs($nbr) 1
  62. }
  63. foreach nbr [array names nbrs] {
  64. if [$nbr is-lan?] {
  65. $nbr instvar receivers_
  66. if { [info exists receivers_($group)] && 
  67. $receivers_($group) > 0 } {
  68. incr receivers_($group) -1
  69. }
  70. }
  71. }
  72. }
  73. DM instproc handle-wrong-iif { srcID group iface } {
  74. $self instvar node_ ns_
  75. set inlink  [$node_ iif2link $iface]
  76. set from [$inlink src]
  77. $self send-ctrl "prune" $srcID $group [$from id]
  78. return 0 ;# don't call this method two times
  79. }
  80. DM instproc handle-cache-miss  { srcID group iface } {
  81. DM instvar CacheMissMode
  82. $self handle-cache-miss-$CacheMissMode $srcID $group $iface
  83. return 1 ;#call again
  84. }
  85. DM instproc handle-cache-miss-pimdm { srcID group iface } {
  86.         $self instvar node_ ns_
  87. if { $iface >= 0 } {
  88. set rpf_nbr [$node_ rpf-nbr $srcID]
  89. set inlink  [$node_ iif2link $iface]
  90. set rpflink [$ns_ link $rpf_nbr $node_]
  91. if { $inlink != $rpflink } {
  92. set from [$inlink src]
  93. $self send-ctrl "prune" $srcID $group [$from id]
  94. return 0; #drop this packet
  95. }
  96. set rpfoif [$node_ iif2oif $iface]
  97. } else {
  98. set rpfoif ""
  99. }
  100. set alloifs [$node_ get-all-oifs]
  101. set oiflist ""
  102. foreach oif $alloifs {
  103. if {$oif == $rpfoif} {
  104. continue ;#exclude incoming iface
  105. }
  106. set dst [[$node_ oif2link $oif] dst]
  107. if { [$dst is-lan?] && [$dst rpf-nbr $srcID] != $node_  } {
  108. # exclude also lan oifs for which we are not forwarders
  109. # this constitutes a form of "centralized" assert mechanism
  110. continue 
  111. }
  112. lappend oiflist $oif
  113. }
  114. #set idx [lsearch $oiflist $rpfoif]
  115. #set oiflist [lreplace $oiflist $idx $idx]
  116. $node_ add-mfc $srcID $group $iface $oiflist
  117. }
  118. DM instproc handle-cache-miss-dvmrp { srcID group iface } {
  119.         $self instvar node_ ns_
  120. set oiflist ""
  121.         foreach nbr [$node_ neighbors] {
  122. # peek into other nodes' routing tables to simulate 
  123. # child-parent relationship maintained by dvmrp
  124. set rpfnbr [$nbr rpf-nbr $srcID]
  125. if { $rpfnbr == $node_ } {
  126. set link [$ns_ link $node_ $nbr]
  127. lappend oiflist [$node_ link2oif $link]
  128. }
  129. }
  130. $node_ add-mfc $srcID $group $iface $oiflist
  131. }
  132. DM instproc drop { replicator src dst iface} {
  133. $self instvar node_ ns_
  134.         if { $iface < 0 } {
  135.                 # optimization for sender: if no listeners, set the ignore bit, 
  136. # so this function isn't called for every packet.
  137. $replicator set ignore_ 1
  138.         } else {
  139. set from [[$node_ iif2link $iface] src]
  140. if [$from is-lan?] {
  141. $self send-ctrl "prune" $src $dst
  142. } else {
  143. $self send-ctrl "prune" $src $dst [$from id]
  144. }
  145. }
  146. }
  147. DM instproc recv-prune { from src group iface} {
  148.         $self instvar node_ PruneTimer_ ns_
  149. set r [$node_ getReps $src $group]
  150. if { $r == "" } { 
  151. return 0
  152. }
  153. set id [$node_ id]
  154. set tmpoif [$node_ iif2oif $iface]
  155. if { [$r is-active-target $tmpoif] } {
  156. $r disable $tmpoif
  157. if ![$r is-active] {
  158. if { $src != $id } {
  159. # propagate prune only if the disabled oif
  160. # was the last one
  161. $self send-ctrl prune $src $group
  162. }
  163. }
  164. }
  165. if ![info exists PruneTimer_($src:$group:$tmpoif)] {
  166. set PruneTimer_($src:$group:$tmpoif) 
  167. [new Timer/Iface/Prune $self $src $group $tmpoif $ns_]
  168. }
  169. $PruneTimer_($src:$group:$tmpoif) schedule
  170. }
  171. DM instproc recv-graft { from src group iface} {
  172.         $self instvar node_ PruneTimer_ ns_
  173. set id [$node_ id]
  174.         set r [$node_ getReps $src $group]
  175. if { $r == "" } {
  176. if { $id == $src } {
  177. set iif "?"
  178. } else {
  179. set rpfnbr [$node_ rpf_nbr $src]
  180. set rpflnk [$ns_ link $src $id]
  181. set iif [$node_ link2iif $rpflnk]
  182. }
  183. $node_ add-mfc $src $group $iif ""
  184.         set r [$node_ getReps $src $group]
  185.         if { ![$r is-active] && $src != $id } {
  186.                 # propagate the graft
  187.                 $self send-ctrl graft $src $group
  188.         }
  189. set tmpoif [$node_ iif2oif $iface]
  190.         $r enable $tmpoif
  191. if [info exists PruneTimer_($src:$group:$tmpoif)] {
  192. delete $PruneTimer_($src:$group:$tmpoif)
  193. unset  PruneTimer_($src:$group:$tmpoif)
  194. }
  195. }
  196. # send a graft/prune for src/group up to the source or towards $to
  197. DM instproc send-ctrl { which src group { to "" } } {
  198.         $self instvar mctrl_ ns_ node_
  199. if { $to != "" } {
  200. set n [$ns_ get-node-by-id $to]
  201. # we don't want to send anything to a lanNode
  202. if [$n is-lan?] return
  203. set toid $to
  204. } else {
  205. set toid $src
  206. }
  207. set nbr [$node_ rpf-nbr $toid]
  208. if [$nbr is-lan?] {
  209. # we're requested to send via a lan: $nbr
  210. $nbr instvar receivers_
  211. # send a graft/prune only if there're no other receivers on the lan
  212. if { [info exists receivers_($group)] && 
  213. $receivers_($group) > 0 } return 
  214. # need to send: find the next hope node
  215. set nbr [$nbr rpf-nbr $toid]
  216. }
  217. $ns_ simplex-connect $mctrl_ 
  218. [[[$nbr getArbiter] getType [$self info class]] set mctrl_]
  219.         if { $which == "prune" } {
  220.                 $mctrl_ set class_ 30
  221.         } else {
  222.                 $mctrl_ set class_ 31
  223.         }        
  224.         $mctrl_ send $which [$node_ id] $src $group
  225. }
  226. DM instproc timeoutPrune { oif src grp } {
  227. $self instvar node_ PruneTimer_ ns_
  228. set r [$node_ getReps $src $grp]
  229. $r insert $oif
  230. if [info exists PruneTimer_($src:$grp:$oif)] {
  231. delete $PruneTimer_($src:$grp:$oif)
  232. unset PruneTimer_($src:$grp:$oif)
  233. }
  234. return
  235. }
  236. Class Timer/Iface/Prune -superclass Timer/Iface
  237. Timer/Iface/Prune set timeout 0.5
  238. Timer/Iface/Prune instproc timeout {} {
  239. $self instvar proto_ src_ grp_ oif_
  240. $proto_ timeoutPrune $oif_ $src_ $grp_
  241. }