summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2009-01-31 22:08:47 -0700
committerJamis Buck <jamis@37signals.com>2009-01-31 22:08:47 -0700
commitf09d124a2b4cbf6e03549f1bb32cace57601738c (patch)
treec427edfcc97c3f37df100a0019a75a169b83c52a
parent07ba76a53e659414d9b9dae17bce8e16d394f333 (diff)
downloadnet-ssh-f09d124a2b4cbf6e03549f1bb32cace57601738c.tar.gz
Ignore requests for non-existent channels
This works around a bug in some ssh servers, where channel requests are sent to channels after the channels have been closed.
-rw-r--r--CHANGELOG.rdoc2
-rw-r--r--lib/net/ssh/connection/session.rb12
-rw-r--r--test/connection/test_session.rb7
3 files changed, 19 insertions, 2 deletions
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc
index a78ad4b..9f208dd 100644
--- a/CHANGELOG.rdoc
+++ b/CHANGELOG.rdoc
@@ -1,5 +1,7 @@
=== unreleased
+* Ignore requests for non-existent channels (workaround ssh server bug) [Jamis Buck]
+
* Add terminate! method for hard shutdown scenarios [Jamis Buck]
* Revert to pre-2.0.7 key-loading behavior by default, but load private-key if public-key doesn't exist [Jamis Buck]
diff --git a/lib/net/ssh/connection/session.rb b/lib/net/ssh/connection/session.rb
index eb9b259..4dd32f7 100644
--- a/lib/net/ssh/connection/session.rb
+++ b/lib/net/ssh/connection/session.rb
@@ -46,6 +46,16 @@ module Net; module SSH; module Connection
# The list of callbacks for pending requests. See #send_global_request.
attr_reader :pending_requests #:nodoc:
+ class NilChannel
+ def initialize(session)
+ @session = session
+ end
+
+ def method_missing(sym, *args)
+ @session.lwarn { "ignoring request #{sym.inspect} for non-existent (closed?) channel; probably ssh server bug" }
+ end
+ end
+
# Create a new connection service instance atop the given transport
# layer. Initializes the listeners to be only the underlying socket object.
def initialize(transport, options={})
@@ -55,7 +65,7 @@ module Net; module SSH; module Connection
@options = options
@channel_id_counter = -1
- @channels = {}
+ @channels = Hash.new(NilChannel.new(self))
@listeners = { transport.socket => nil }
@pending_requests = []
@channel_open_handlers = {}
diff --git a/test/connection/test_session.rb b/test/connection/test_session.rb
index ba9c34f..05c3ad8 100644
--- a/test/connection/test_session.rb
+++ b/test/connection/test_session.rb
@@ -257,6 +257,11 @@ module Connection
process_times(2)
end
+ def test_channel_request_for_nonexistant_channel_should_be_ignored
+ transport.return(CHANNEL_REQUEST, :long, 14, :string, "testing", :bool, false)
+ assert_nothing_raised { process_times(2) }
+ end
+
def test_channel_request_packet_should_be_routed_to_corresponding_channel
channel_at(14).expects(:do_request).with("testing", false, Net::SSH::Buffer.new)
transport.return(CHANNEL_REQUEST, :long, 14, :string, "testing", :bool, false)
@@ -480,4 +485,4 @@ module Connection
end
end
-end \ No newline at end of file
+end