1 # network.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1996-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #
31 # @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/net/network.tcl,v 1.51 2004/01/21 01:09:04 aswan Exp $
32
33
34 import AddressBlock MMG/mash ErrorWindow
35 #provide Network
36
37
38 Network set rtptv_compat_ 0
39
40 #FIXME backward compat
41 Class Network/IP -superclass Network
42 Network/IP instproc init args {
43 puts stderr "Network/IP called... change to Network"
44 eval $self next $args
45 }
46
47 proc in_multicast addr {
48 return [expr ([lindex [split $addr .] 0] & 0xf0) == 0xe0]
49 }
50
51 Class NetworkLayer
52 Class NetworkManager
53
54 NetworkManager instproc graphics-init n {
55 # some apps may instantiate multiple NetworkManagers.
56 # in such a case, build layers window only for real
57 # layered sessions and don't try to build more than one.
58 if {$n == 1 || [winfo exists .l]} { return }
59
60 $self instvar nchan_
61 set nchan_ $n
62
63 toplevel .l
64 set k 0
65 while { $k < $nchan_ } {
66 radiobutton .l.b$k -command "$self set-subscription-level $k" \
67 -text "Level $k" \
68 -variable nLayers -value $k
69 pack .l.b$k
70 incr k
71 }
72 wm withdraw .l
73 bind . <l> {
74 if [winfo ismapped .l] {
75 wm withdraw .l
76 } else {
77 wm deiconify .l
78 }
79 }
80 }
81
82 #
83 # set level of subscription to layers 0 through n (inclusive of n)
84 # n must be strictly less than the total number of layers
85 #
86 NetworkManager instproc set-subscription-level n {
87 $self instvar agent_ nchan_ session_ net_
88 $agent_ set_maxchannel $n
89 $session_ set loopbackLayer_ [expr $n + 1]
90
91 set i 0
92 while { $i <= $n } {
93 $net_($i) enable
94 incr i
95 }
96 while { $i < $nchan_ } {
97 $net_($i) disable
98 incr i
99 }
100
101 #FIXME
102 global nLayers
103 set nLayers $n
104 }
105
106 NetworkLayer instproc init { session addr sport rport ttl channel } {
107 $self next
108 $self instvar session_ addr_ port_ ttl_ dn_ cn_ channel_ active_
109 set addr_ $addr
110 set port_ $rport
111 set sport_ $sport
112 set rport_ $rport
113 set session_ $session
114 set ttl_ $ttl
115 set channel_ $channel
116
117 # open the data network
118 set dn_ [new Network]
119 if { [$self get_option rtptvCompat] == 1 } {
120 $dn_ set rtptv_compat_ 1
121 }
122
123 set result [$dn_ open $addr_ $sport_ $rport_ $ttl_]
124 if {$result == {0}} {
125 new ErrorWindow {Cannot open network connection.}
126 exit 1
127 }
128
129 # for the data sockets only, make sure we have
130 # reasonably large send/recv buffers
131 $dn_ large_buffers
132
133 set bufsize [$self get_option netBufferSize]
134 if { $bufsize != "" } {
135 if [catch {$dn_ recv_bufset $bufsize} msg] {
136 #puts stderr $msg
137 puts stderr "Could not set buffer size to $bufsize"
138 }
139 }
140
141 # open the control network
142 set cn_ [new Network]
143 if { [$self get_option rtptvCompat] == 1 } {
144 $cn_ set rtptv_compat_ 1
145 }
146
147 set result [$cn_ open $addr_ [expr $sport_ + 1] [expr $rport_ + 1] $ttl_]
148 if {$result == {0}} {
149 new ErrorWindow {Cannot open network connection.}
150 exit 1
151 }
152
153 #FIXME loop back control messages for local rtp monitor
154 $cn_ loopback 1
155
156 # report the new Network objects to the Session/RTP/...
157 $session_ data-net $dn_ $channel_
158 $session_ ctrl-net $cn_ $channel_
159
160 #FIXME start out inactive
161 set active_ 0
162 $dn_ drop-membership
163 $cn_ drop-membership
164 # when membership is dropped (socket closed), handlers must be unlinked
165 $session_ data-net "" $channel_
166 $session_ ctrl-net "" $channel_
167
168 $self set tloss_ 0
169 }
170
171 NetworkLayer instproc destroy {} {
172 $self instvar dn_ cn_
173
174 if [info exists dn_] {
175 delete $dn_
176 }
177 if [info exists cn_] {
178 delete $cn_
179 }
180
181 $self next
182 }
183
184
185 NetworkLayer instproc data-net {} {
186 return [$self set dn_]
187 }
188
189 NetworkLayer instproc ctrl-net {} {
190 return [$self set cn_]
191 }
192
193 NetworkLayer instproc enable-send {} {
194 $self instvar dn_ cn_ session_ channel_
195 $session_ data-net $dn_ $channel_
196 $session_ ctrl-net $cn_ $channel_
197 }
198
199 NetworkLayer instproc disable-send {} {
200 $self instvar dn_ cn_ session_ channel_
201 $session_ data-net "" $channel_
202 $session_ ctrl-net "" $channel_
203 }
204
205
206 NetworkLayer instproc enable {} {
207 $self instvar active_ dn_ cn_ session_ channel_
208 if !$active_ {
209 set active_ 1
210 $dn_ add-membership
211 $cn_ add-membership
212 # FIXME relink the io channel in case the fd changes
213 $session_ data-net $dn_ $channel_
214 $session_ ctrl-net $cn_ $channel_
215 }
216 }
217
218 NetworkLayer instproc disable {} {
219 $self instvar dn_ cn_ active_ session_ channel_
220 if $active_ {
221 set active_ 0
222 $dn_ drop-membership
223 $cn_ drop-membership
224 # when membership is dropped (socket closed), handlers must be unlinked
225 $session_ data-net "" $channel_
226 $session_ ctrl-net "" $channel_
227 }
228 }
229
230 NetworkLayer instproc notify-loss {src} {
231 $self instvar loss_ tloss_
232 if ![info exists loss_($src)] {
233 set loss_($src) 0
234 }
235
236 set nloss [$src missing]
237 incr tloss_ [expr $nloss - $loss_($src)]
238 set loss_($src) $nloss
239 }
240
241 NetworkLayer instproc nlost {} {
242 $self instvar tloss_
243 return $tloss_
244 }
245
246 NetworkLayer instproc npkts {n} {
247 #FIXME
248 $self instvar agent_
249 set npkts 0
250 foreach s [$agent_ set sources_] {
251 set l [lindex [$s set layers_] $n]
252 incr npkts [$l set np_]
253 }
254 return $npkts
255 }
256
257 NetworkLayer instproc crypt { dc cc } {
258 $self instvar dn_ cn_
259 $dn_ crypt $dc
260 $cn_ crypt $cc
261 }
262
263 NetworkManager instproc init { ab session agent } {
264 $self next
265 $self instvar session_ agent_ encrypt_ key_ fmt_
266 set session_ $session
267 set agent_ $agent
268 set encrypt_ 0
269 set key_ ""
270 set fmt_ ""
271 $self allocate $ab $session
272 }
273
274 NetworkManager instproc session-info {} {
275 set net [$self data-net 0]
276
277 set addr [$net addr]
278 set rport [$net rport]
279 set sport [$net sport]
280 set ttl [$net ttl]
281
282 if { $rport == $sport } {
283 set port $rport
284 } else {
285 set port "$rport:$sport"
286 }
287
288 return "Dest: $addr Port: $port TTL: $ttl"
289 }
290
291 NetworkManager instproc allocate { ab session } {
292 $self instvar nchan_ net_ mmg_
293 if [info exists nchan_] {
294 set oldnchan $nchan_
295 } else {
296 set oldnchan 0
297 }
298 set nchan_ 0
299 while { $nchan_ < [$ab nchan] } {
300 set addr [$ab addr $nchan_]
301 set sport [$ab sport $nchan_]
302 set rport [$ab rport $nchan_]
303 set ttl [$ab ttl $nchan_]
304 if [info exists net_($nchan_)] {
305 delete $net_($nchan_)
306 }
307 set net_($nchan_) [new NetworkLayer $session $addr \
308 $sport $rport $ttl $nchan_]
309
310 #FIXME
311 $self instvar agent_
312 $net_($nchan_) set agent_ $agent_
313
314 incr nchan_
315 }
316 set n $nchan_
317 while {$n < $oldnchan} {
318 if [info exists net_($n)] {
319 delete $net_($n)
320 }
321 incr n
322 }
323
324 #XXX disable rtcp if using ssm
325 #XXX if we're the source then we should still send
326 # sender reports?
327 set addr0 [$ab addr 0]
328 if [string match "*@*" $addr0] {
329 $session send-rtcp 0
330 }
331
332 if [info exists mmg_] {
333 delete $mmg_
334 }
335
336 #FIXME
337 $self set-subscription-level 0
338
339 if {$nchan_ == 1} { return }
340 if [$self yesno useLayersWindow] {
341 $self graphics-init $nchan_
342 }
343 if [$self get_option useRLM] {
344 #FIXME
345 set caddr ""
346 set mmg_ [new MMG/mash $self $caddr]
347 }
348 }
349
350
351 NetworkManager instproc nchan {} {
352 return [$self set nchan_]
353 }
354
355 NetworkManager instproc reset ab {
356 #puts "$self ($class): reset $spec"
357 $self instvar session_
358 $self allocate $ab $session_
359 }
360
361 NetworkManager instproc data-net args {
362 if { $args == "" } {
363 set k 0
364 } else {
365 set k $args
366 }
367 $self instvar net_
368 return [$net_($k) data-net]
369 }
370
371 NetworkManager instproc ctrl-net args {
372 if { $args == "" } {
373 set k 0
374 } else {
375 set k $args
376 }
377 $self instvar net_
378 return [$net_($k) ctrl-net]
379 }
380
381 NetworkManager public loopback enable {
382 $self instvar nchan_ net_
383 set i 0
384 while { $i < $nchan_ } {
385 set net $net_($i)
386 set dn [$net data-net]
387 set cn [$net ctrl-net]
388 $dn loopback $enable
389 $cn loopback $enable
390 incr i
391 }
392 }
393
394 NetworkManager instproc install-key key {
395 return [$self set_key $key]
396 }
397
398 NetworkManager instproc crypt_all { dc cc } {
399 $self instvar net_
400 foreach n [array names net_] {
401 $net_($n) crypt $dc $cc
402 }
403 }
404
405 NetworkManager instproc destroy {} {
406 $self instvar net_
407
408 foreach chan [array names net_] {
409 delete $net_($chan)
410 }
411 $self next
412 }
413
414 NetworkManager instproc usingRLM {} {
415 $self instvar mmg_
416 return [info exists mmg_]
417 }
418
419 NetworkManager instproc notify-loss {src layer} {
420 $self instvar net_
421 $net_($layer) notify-loss $src
422 }
423
424 NetworkManager instproc crypt_format { key } {
425 set k [string first / $key]
426 if { $k < 0 } {
427 set fmt DES
428 } else {
429 set fmt [string range $key 0 [expr $k - 1]]
430 set key [string range $key [expr $k + 1] end]
431 }
432 return "$fmt $key"
433 }
434
435 NetworkManager instproc set_key key {
436 if { $key == "" } {
437 $self crypt_clear
438 return ""
439 }
440
441 $self instvar encrypt_
442 set L [$self crypt_format $key]
443 set fmt [lindex $L 0]
444 set key [lindex $L 1]
445 $self instvar key_
446 set key_ $key
447
448 $self instvar dc_ cc_ fmt_
449
450 #
451 # If the format changes, delete the crypt
452 # objects so we reallocate them below.
453 #
454 if { $fmt_ != $fmt } {
455 if [info exists dc_] {
456 delete $dc_
457 unset dc_
458 }
459 if [info exists cc_] {
460 delete $cc_
461 unset cc_
462 }
463 set fmt_ $fmt
464 }
465
466 if ![info exists dc_] {
467 set clist [Crypt/Data info subclass]
468 if { [lsearch -exact $clist Crypt/Data/$fmt] < 0 } {
469 return "no $fmt encryption support"
470 }
471 set dc_ [new Crypt/Data/$fmt]
472 set cc_ [new Crypt/Control/$fmt]
473 }
474 if [$dc_ key $key] {
475 $cc_ key $key
476 $self crypt_all $dc_ $cc_
477 set encrypt_ 1
478 return ""
479 } else {
480 $self crypt_clear
481 return "your key is cryptographically weak"
482 }
483 }
484
485 NetworkManager instproc crypt_clear {} {
486 $self instvar encrypt_ key_
487 $self crypt_all "" ""
488 set key_ ""
489 set encrypt_ 0
490 }
491
492
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.