class LocalTunnel::TunnelConn

Public Class Methods

new(rhost, rport, lport, id:, logger: nil) click to toggle source
# File lib/local_tunnel.rb, line 21
def initialize(rhost, rport, lport, id:, logger: nil)
  @rhost = rhost
  @rport = rport
  @lhost = 'localhost'
  @lport = lport
  @lrcount = 0
  @rlcount = 0
  @id = id
  @logger = logger || self.class.logger.dup
end

Private Class Methods

logger() click to toggle source
# File lib/local_tunnel.rb, line 147
def logger
  @logger ||= LocalTunnel.logger.dup
end
logger=(value) click to toggle source
# File lib/local_tunnel.rb, line 151
def logger=(value)
  @logger = value
end

Public Instance Methods

lconnect() click to toggle source
# File lib/local_tunnel.rb, line 136
def lconnect
  TCPSocket.new(@lhost, @lport)
end
rconnect() click to toggle source
# File lib/local_tunnel.rb, line 132
def rconnect
  TCPSocket.new(@rhost, @rport)
end
start() click to toggle source
# File lib/local_tunnel.rb, line 32
def start
  @rconn = rconnect
  @lconn = lconnect
  bail = false

  @lrthr = Thread.new do
    buf = String.new(capacity: 1024)
    until bail
      begin
        logger.debug(format("%03d lr: attempting read", @id))
        @lconn.readpartial(1024, buf)
      rescue Errno::ECONNRESET
        logger.debug(format("%03d lr: read failed, connection reset by peer", @id))
        @lconn.close
        bail = true
        break
      rescue EOFError
        logger.debug(format("%03d lr: read failed, reconnecting", @id))
        @lconn.close
        @lconn = lconnect
        retry
      end
      logger.debug(format("%03d lr:   read #{buf.size}", @id))

      begin
        logger.debug(format("%03d lr: attempting write", @id))
        s = @rconn.write(buf)
      rescue Errno::ECONNRESET
        logger.debug(format("%03d lr: write failed, connection reset by peer", @id))
        @lconn.close
        bail = true
        break
      rescue IOError
        logger.debug(format("%03d lr: write failed, reconnecting", @id))
        @rconn.close
        @rconn = rconnect
        retry
      end
      logger.debug(format("%03d lr:   write #{s}", @id))

      @lrcount += buf.size
      logger.debug(format("%03d lr:   total #{@lrcount}", @id))
      buf.clear
    end
  end

  @rlthr = Thread.new do
    buf = String.new(capacity: 1024)
    until bail
      begin
        logger.debug(format("%03d rl: attempting read", @id))
        @rconn.readpartial(1024, buf)
      rescue Errno::ECONNRESET
        logger.debug(format("%03d rl: read failed, connection reset by peer", @id))
        @lconn.close
        bail = true
        break
      rescue EOFError
        logger.debug(format("%03d rl: read failed, reconnecting", @id))
        @rconn.close
        @rconn = rconnect
        retry
      end
      logger.debug(format("%03d rl:   read #{buf.size}", @id))

      begin
        logger.debug(format("%03d rl: attempting write", @id))
        s = @lconn.write(buf)
      rescue Errno::ECONNRESET
        logger.debug(format("%03d rl: write failed, connection reset by peer", @id))
        @lconn.close
        bail = true
        break
      rescue IOError
        logger.debug(format("%03d rl: write failed, reconnecting", @id))
        @lconn.close
        @lconn = lconnect
        retry
      end
      logger.debug(format("%03d rl:   write #{s}", @id))

      @rlcount += buf.size
      logger.debug(format("%03d rl:   total #{@rlcount}", @id))
      buf.clear
    end
  end

  self
end
stop() click to toggle source
# File lib/local_tunnel.rb, line 127
def stop
  [@lrthr, @rlthr].compact.each(&:kill)
  self
end
wait() click to toggle source
# File lib/local_tunnel.rb, line 122
def wait
  [@lrthr, @rlthr].each(&:join)
  self
end

Private Instance Methods

logger() click to toggle source
# File lib/local_tunnel.rb, line 142
def logger
  @logger
end