vkvalli 16-Aug-2014: This program acts as a bandwidth throttling proxy.
package require TclOO
set debug_level 3
proc debug {level msg} {
global debug_level
if {$debug_level > $level} {
puts $msg
}
}
oo::class create handler {}
oo::define handler {
method initialize {lchan1 rchan1} {
my variable lchan
my variable rchan
my variable lbuffer
set lchan $lchan1
set rchan $rchan1
fconfigure $lchan -translation binary -buffering none -blocking 0
fconfigure $rchan -translation binary -buffering none -blocking 0
fileevent $lchan readable [list [self] local_read ]
fileevent $rchan readable [list [self] remote_read ]
my timer start
# dumper register [self]
debug 1 "handler [self] created"
}
method finalize {} {
my variable lchan
my variable rchan
my variable lbuffer
my timer stop
catch {close $lchan}
catch {close $rchan}
# dumper deregister [self]
after 0 [self] destroy
}
method local_read {} {
my variable lchan
my variable rchan
if [eof $lchan] {
my finalize
return
}
set data [read $lchan]
if [catch {puts -nonewline $rchan $data}] {
my finalize
}
}
method remote_read {} {
my variable lchan
my variable rchan
my variable limit
if [eof $rchan] {
my finalize
}
if {$limit > 0} {
set data [read $rchan $limit]
incr limit -[string length $data]
if [eof $lchan] {
my finalize
return
}
if [catch {puts -nonewline $lchan $data}] {
my finalize
return
}
}
}
method timer {mode} {
global period
my variable timer_id
switch $mode {
start {
my limit_reset
set timer_id [after $period [list [self] timer start] ]
}
stop {
after cancel $timer_id
}
}
}
method limit_reset {} {
my variable limit
global lbuflength
set limit $lbuflength
}
}
if {[llength $argv] < 4} {
puts "usage: args: lport rhost rport bandwidth"
exit
}
set lport [lindex $argv 0]
set rhost [lindex $argv 1]
set rport [lindex $argv 2]
set bwidth [lindex $argv 3]
set period [lindex $argv 4]
if {$period eq ""} {
set period 50
}
set lbuflength [expr ($bwidth * $period ) / 1000 ]
proc accept {sock addr p} {
global rhost rport
set conn [socket -async $rhost $rport]
set obj_name handler_$sock
handler create $obj_name
$obj_name initialize $sock $conn
}
set server [socket -server accept $lport]
vwait forever