Class: TCPProxy
- Inherits:
-
Object
- Object
- TCPProxy
- Defined in:
- lib/tcp_proxy.rb
Defined Under Namespace
Classes: Connection
Instance Attribute Summary collapse
-
#connections ⇒ Object
readonly
Returns the value of attribute connections.
Instance Method Summary collapse
- #accept_connections ⇒ Object
- #allow ⇒ Object
- #block ⇒ Object
- #close ⇒ Object
- #drop_all ⇒ Object
- #forward_data ⇒ Object
-
#initialize(host, from_port, to_port) ⇒ TCPProxy
constructor
A new instance of TCPProxy.
-
#thread_main ⇒ Object
Inside the background thread —————————————-.
Constructor Details
#initialize(host, from_port, to_port) ⇒ TCPProxy
Returns a new instance of TCPProxy.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/tcp_proxy.rb', line 4 def initialize(host, from_port, to_port) @ins = TCPServer.new(host, from_port) @host = host @from_port, @to_port = from_port, to_port # Active connections and mutex to protect access to it. @connections = [] @connections_m = Mutex.new # Are we currently accepting new connections? @accept_new = true @thread = Thread.start(&method(:thread_main)) end |
Instance Attribute Details
#connections ⇒ Object (readonly)
Returns the value of attribute connections.
2 3 4 |
# File 'lib/tcp_proxy.rb', line 2 def connections @connections end |
Instance Method Details
#accept_connections ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/tcp_proxy.rb', line 114 def accept_connections loop do in_sock = @ins.accept_nonblock out_sock = TCPSocket.new(@host, @to_port) @connections_m.synchronize { @connections << Connection.new(in_sock, out_sock) } end rescue Errno::EAGAIN # No more connections pending, stop accepting new connections end |
#allow ⇒ Object
37 38 39 |
# File 'lib/tcp_proxy.rb', line 37 def allow @accept_new = true end |
#block ⇒ Object
34 35 36 |
# File 'lib/tcp_proxy.rb', line 34 def block @accept_new = false end |
#close ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/tcp_proxy.rb', line 20 def close @shutdown = true @thread.join @thread = nil # Since the thread is stopped now, we can be sure no new connections are # accepted. This is why we access the collection without locking. @connections.each do |connection| connection.close end @ins.close end |
#drop_all ⇒ Object
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/tcp_proxy.rb', line 41 def drop_all # Copy the connections and then empty the collection connections = @connections_m.synchronize { @connections.tap { @connections = [] } } connections.each do |conn| conn.close end end |
#forward_data ⇒ Object
126 127 128 129 130 131 |
# File 'lib/tcp_proxy.rb', line 126 def forward_data connections = @connections_m.synchronize { @connections.dup } connections.each do |conn| conn.pump_synchronized end end |
#thread_main ⇒ Object
Inside the background thread —————————————-
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/tcp_proxy.rb', line 54 def thread_main loop do accept_connections if @accept_new forward_data break if @shutdown end rescue Exception => ex p [:uncaught, ex] ex.backtrace.each do |line| puts line end raise end |