File: remote-network-handler.rb

package info (click to toggle)
libnet-ssh-ruby 1.1.2-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 3,472 kB
  • ctags: 2,465
  • sloc: ruby: 10,848; makefile: 17
file content (83 lines) | stat: -rw-r--r-- 2,808 bytes parent folder | download | duplicates (3)
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