1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#--
# =============================================================================
# Copyright (c) 2004,2005 Jamis Buck (jamis@37signals.com)
# All rights reserved.
#
# This source file is distributed as part of the Net::SSH Secure Shell Client
# library for Ruby. This file (and the library as a whole) may be used only as
# allowed by either the BSD license, or the Ruby license (or, by association
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
# distribution for the texts of these licenses.
# -----------------------------------------------------------------------------
# net-ssh website : http://net-ssh.rubyforge.org
# project website: http://rubyforge.org/projects/net-ssh
# =============================================================================
#++
require 'socket'
module Net
module SSH
module Service
module Forward
# A helper class for managing ports forwarded from a remote host to
# the local host.
class RemoteNetworkHandler
# Instantiate a new RemoteNetworkHandler instance that will forward
# data to the given local port and host address.
def initialize( log, block_size, local_port, local_host='127.0.0.1' )
@log = log
@block_size = block_size
@local_port = local_port
@local_host = local_host
end
# Opens a new socket to the local host and port given when the
# handler was created, and forwards data from the channel to that
# connection.
def on_open( channel, c_addr, c_port, o_addr, o_port )
@client = TCPSocket.new( @local_host, @local_port )
Thread.new do
begin
loop do
break if channel[:eof]
data = ""
while IO.select([@client],nil,nil,0.01)
data << @client.recv(@block_size)
end
channel.send_data data unless data.empty?
end
rescue Exception => e
@log.error "error while forwarding remote port: " +
"#{e.class}: #{e.message}\n " +
e.backtrace.join( "\n " )
ensure
channel.close
end
end
end
# Invoked when the channel indicates that the end is near.
def on_eof( channel )
channel[:eof] = true
end
# Invoked when the channel is closed.
def on_close( channel )
@client.shutdown
end
# Invoked when data is received over the channel.
def on_receive( channel, data )
@client.send data, 0
end
end
end
end
end
end
|