summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDelano Mandelbaum <delano.mandelbaum@gmail.com>2011-08-17 18:07:04 -0700
committerDelano Mandelbaum <delano.mandelbaum@gmail.com>2011-08-17 18:07:04 -0700
commit6cb111cb606ff237d4fe8c3b5237550bc3459fdb (patch)
treef99cf1e32bd78c1bec9531335eac91d5aab57679
parente2aceae24948448b856af999054e73d9fee4632c (diff)
parent9b80fd31762ab99fd5ff9fe3262f0665a040e2c9 (diff)
downloadnet-ssh-6cb111cb606ff237d4fe8c3b5237550bc3459fdb.tar.gz
Merge pull request #23 from imbriaco/master
Allow a local UNIX domain socket to be forwarded to a remote TCP socket.
-rw-r--r--lib/net/ssh/service/forward.rb26
-rw-r--r--test/manual/test_forward.rb40
2 files changed, 57 insertions, 9 deletions
diff --git a/lib/net/ssh/service/forward.rb b/lib/net/ssh/service/forward.rb
index fa3e4f0..7d88487 100644
--- a/lib/net/ssh/service/forward.rb
+++ b/lib/net/ssh/service/forward.rb
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
require 'net/ssh/loggable'
module Net; module SSH; module Service
@@ -53,22 +54,31 @@ module Net; module SSH; module Service
raise ArgumentError, "expected 3 or 4 parameters, got #{args.length}"
end
- bind_address = "127.0.0.1"
- bind_address = args.shift if args.first.is_a?(String) && args.first =~ /\D/
+ local_port_type = :long
+
+ socket = begin
+ if args.first.class == UNIXServer
+ local_port_type = :string
+ args.shift
+ else
+ bind_address = "127.0.0.1"
+ bind_address = args.shift if args.first.is_a?(String) && args.first =~ /\D/
+ local_port = args.shift.to_i
+ local_port_type = :long
+ TCPServer.new(bind_address, local_port)
+ end
+ end
- local_port = args.shift.to_i
remote_host = args.shift
remote_port = args.shift.to_i
- socket = TCPServer.new(bind_address, local_port)
-
@local_forwarded_ports[[local_port, bind_address]] = socket
session.listen_to(socket) do |server|
client = server.accept
- debug { "received connection on #{bind_address}:#{local_port}" }
+ debug { "received connection on #{socket}" }
- channel = session.open_channel("direct-tcpip", :string, remote_host, :long, remote_port, :string, bind_address, :long, local_port) do |achannel|
+ channel = session.open_channel("direct-tcpip", :string, remote_host, :long, remote_port, :string, bind_address, local_port_type, local_port) do |achannel|
achannel.info { "direct channel established" }
end
@@ -285,4 +295,4 @@ module Net; module SSH; module Service
end
end
-end; end; end \ No newline at end of file
+end; end; end
diff --git a/test/manual/test_forward.rb b/test/manual/test_forward.rb
index 46ddb25..34758da 100644
--- a/test/manual/test_forward.rb
+++ b/test/manual/test_forward.rb
@@ -18,6 +18,7 @@ require 'common'
require 'net/ssh/buffer'
require 'net/ssh'
require 'timeout'
+require 'tempfile'
class TestForward < Test::Unit::TestCase
@@ -120,7 +121,44 @@ class TestForward < Test::Unit::TestCase
session.loop(0.1) { client_done.empty? }
assert_equal "Broken pipe", "#{server_exc.pop}" unless server_exc.empty?
end
+
+ def create_local_socket(&blk)
+ tempfile = Tempfile.new("net_ssh_forward_test")
+ path = tempfile.path
+ tempfile.delete
+ yield UNIXServer.open(path)
+ File.delete(path)
+ end
+ def test_forward_local_unix_socket_to_remote_port
+ session = Net::SSH.start(*ssh_start_params)
+ server_exc = Queue.new
+ server = start_server_sending_lot_of_data(server_exc)
+ remote_port = server.addr[1]
+ client_data = nil
+
+ create_local_socket do |local_socket|
+ session.forward.local(local_socket, localhost, remote_port)
+ client_done = Queue.new
+
+ Thread.start do
+ begin
+ client = UNIXSocket.new(local_socket.path)
+ client_data = client.recv(1024)
+ client.close
+ sleep(0.2)
+ ensure
+ client_done << true
+ end
+ end
+
+ session.loop(0.1) { client_done.empty? }
+ end
+
+ assert_not_nil(client_data, "client should have received data")
+ assert(client_data.match(/item\d/), 'client should have received the string item')
+ end
+
def test_loop_should_not_abort_when_server_side_of_forward_is_closed
session = Net::SSH.start(*ssh_start_params)
server = start_server_closing_soon
@@ -182,4 +220,4 @@ class TestForward < Test::Unit::TestCase
assert_equal "This is a small message!", client_done.pop
end
end
-end \ No newline at end of file
+end