Class: SwitchTower::Gateway

Inherits:
Object
  • Object
show all
Defined in:
lib/switchtower/gateway.rb

Overview

Black magic. It uses threads and Net::SSH to set up a connection to a gateway server, through which connections to other servers may be tunnelled.

It is used internally by Actor, but may be useful on its own, as well.

Usage:

config = SwitchTower::Configuration.new
gateway = SwitchTower::Gateway.new('gateway.example.com', config)

sess1 = gateway.connect_to('hidden.example.com')
sess2 = gateway.connect_to('other.example.com')

Constant Summary collapse

MAX_PORT =
65535
MIN_PORT =
1024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, config) ⇒ Gateway

:nodoc:



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
# File 'lib/switchtower/gateway.rb', line 31

def initialize(server, config) #:nodoc:
  @config = config
  @pending_forward_requests = {}
  @mutex = Mutex.new
  @next_port = MAX_PORT
  @terminate_thread = false

  waiter = ConditionVariable.new

  @thread = Thread.new do
    @config.logger.trace "starting connection to gateway #{server}"
    SSH.connect(server, @config) do |@session|
      @config.logger.trace "gateway connection established"
      @mutex.synchronize { waiter.signal }
      connection = @session.registry[:connection][:driver]
      loop do
        break if @terminate_thread
        sleep 0.1 unless connection.reader_ready?
        connection.process true
        Thread.new { process_next_pending_connection_request }
      end
    end
  end

  @mutex.synchronize { waiter.wait(@mutex) }
end

Instance Attribute Details

#sessionObject (readonly)

The Net::SSH session representing the gateway connection.



26
27
28
# File 'lib/switchtower/gateway.rb', line 26

def session
  @session
end

#threadObject (readonly)

The thread inside which the gateway connection itself is running.



23
24
25
# File 'lib/switchtower/gateway.rb', line 23

def thread
  @thread
end

Instance Method Details

#connect_to(server) ⇒ Object

Connects to the given server by opening a forwarded port from the local host to the server, via the gateway, and then opens and returns a new Net::SSH connection via that port.



75
76
77
78
79
80
81
# File 'lib/switchtower/gateway.rb', line 75

def connect_to(server)
  @mutex.synchronize do
    @pending_forward_requests[server] = ConditionVariable.new
    @pending_forward_requests[server].wait(@mutex)
    @pending_forward_requests.delete(server)
  end
end

#shutdown!Object

Shuts down all forwarded connections and terminates the gateway.



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/switchtower/gateway.rb', line 59

def shutdown!
  # cancel all active forward channels
  @session.forward.active_locals.each do |lport, host, port|
    @session.forward.cancel_local(lport)
  end

  # terminate the gateway thread
  @terminate_thread = true

  # wait for the gateway thread to stop
  @thread.join
end