Class: HrrRbSsh::Connection::Channel::ChannelType::DirectTcpip

Inherits:
HrrRbSsh::Connection::Channel::ChannelType show all
Includes:
Loggable
Defined in:
lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb

Constant Summary collapse

NAME =
'direct-tcpip'

Instance Attribute Summary

Attributes included from Loggable

#log_key, #logger

Instance Method Summary collapse

Methods included from Loggable

#log_debug, #log_error, #log_fatal, #log_info, #log_warn

Methods included from SubclassWithoutPreferenceListable

#[], #inherited, #list_supported

Constructor Details

#initialize(connection, channel, message, socket = nil, logger: nil) ⇒ DirectTcpip

Returns a new instance of DirectTcpip.



15
16
17
18
19
20
21
22
23
# File 'lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb', line 15

def initialize connection, channel, message, socket=nil, logger: nil
  self.logger = logger
  @connection = connection
  @channel = channel
  @host_to_connect       = message[:'host to connect']
  @port_to_connect       = message[:'port to connect']
  @originator_IP_address = message[:'originator IP address']
  @originator_port       = message[:'originator port']
end

Instance Method Details

#closeObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb', line 31

def close
  begin
    if @sender_thread_finished && @receiver_thread_finished
      log_info { "closing direct-tcpip" }
      @socket.close
      log_info { "closing channel IOs" }
      @channel.io.each{ |io| io.close rescue nil }
      log_info { "channel IOs closed" }
      @channel.close from=:channel_type_instance
      log_info { "direct-tcpip closed" }
    end
  rescue => e
    log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
  end
end

#receiver_threadObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb', line 76

def receiver_thread
  Thread.new(@socket){ |s|
    begin
      loop do
        begin
          s.write @channel.io[0].readpartial(10240)
        rescue EOFError
          log_info { "io is EOF" }
          s.close_write
          break
        rescue IOError
          log_info { "socket is closed" }
          break
        rescue => e
          log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
          s.close_write
          break
        end
      end
      log_info { "finishing receiver thread" }
      @receiver_thread_finished = true
      close
    ensure
      log_info { "receiver thread finished" }
    end
  }
end

#sender_threadObject



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
# File 'lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb', line 47

def sender_thread
  Thread.new(@socket){ |s|
    begin
      loop do
        begin
          @channel.io[1].write s.readpartial(10240)
        rescue EOFError
          log_info { "socket is EOF" }
          @channel.io[1].close rescue nil
          break
        rescue IOError
          log_info { "socket is closed" }
          @channel.io[1].close rescue nil
          break
        rescue => e
          log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
          @channel.io[1].close rescue nil
          break
        end
      end
      log_info { "finishing sender thread" }
      @sender_thread_finished = true
      close
    ensure
      log_info { "sender thread finished" }
    end
  }
end

#startObject



25
26
27
28
29
# File 'lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb', line 25

def start
  @socket = TCPSocket.new @host_to_connect, @port_to_connect
  @sender_thread = sender_thread
  @receiver_thread = receiver_thread
end