Version 2 of bandwidth throttling proxy

Updated 2014-08-16 07:20:44 by vkvalli
 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