summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver <oliver@zerolag.com>2013-04-10 11:08:10 +0200
committerOliver <oliver@zerolag.com>2013-04-10 21:40:05 +0200
commit733df553cc598e16ba099432d1b6464f074b5a4c (patch)
treedb035a05155953c483f895d3abf6bf3a28d092e6
parent4f2ae72397484dbf365ef1b4898076fc9ffbd90a (diff)
downloadnet-ssh-733df553cc598e16ba099432d1b6464f074b5a4c.tar.gz
connection/channel+session: lower max packet size & allow manual size.
Per section 6.1 of RFC 4253 an SSH implementation MUST support a packet size of 32768 bytes, however, any size above this is not mandatory. Currently, the max packet size is 64Kb and can cause a channel open failure for hosts which only support the required 32Kb packet size. As a result, we now default to the required size of 32768 (0x8000) in order to avoid any errors with such hosts. Additionally, the user can now manually define the maximum packet and window size, should they choose to in the event that they wish to obtain performance gains from a larger packet/window size.
-rw-r--r--lib/net/ssh.rb7
-rw-r--r--lib/net/ssh/connection/channel.rb6
-rw-r--r--lib/net/ssh/connection/session.rb8
3 files changed, 15 insertions, 6 deletions
diff --git a/lib/net/ssh.rb b/lib/net/ssh.rb
index ef510bc..d03b2d7 100644
--- a/lib/net/ssh.rb
+++ b/lib/net/ssh.rb
@@ -66,7 +66,8 @@ module Net
:languages, :logger, :paranoid, :password, :port, :proxy,
:rekey_blocks_limit,:rekey_limit, :rekey_packet_limit, :timeout, :verbose,
:global_known_hosts_file, :user_known_hosts_file, :host_key_alias,
- :host_name, :user, :properties, :passphrase, :keys_only
+ :host_name, :user, :properties, :passphrase, :keys_only, :max_pkt_size,
+ :max_win_size
]
# The standard means of starting a new SSH connection. When used with a
@@ -133,6 +134,10 @@ module Net
# option is intended for situations where ssh-agent offers many different
# identites.
# * :logger => the logger instance to use when logging
+ # * :max_pkt_size => maximum size we tell the other side that is supported per
+ # packet.
+ # * :max_win_size => maximum size we tell the other side that is supported for
+ # the window.
# * :paranoid => either false, true, :very, or :secure specifying how
# strict host-key verification should be (in increasing order here)
# * :passphrase => the passphrase to use when loading a private key (default
diff --git a/lib/net/ssh/connection/channel.rb b/lib/net/ssh/connection/channel.rb
index a79419a..bf33903 100644
--- a/lib/net/ssh/connection/channel.rb
+++ b/lib/net/ssh/connection/channel.rb
@@ -107,15 +107,15 @@ module Net; module SSH; module Connection
# that time (see #do_open_confirmation).
#
# This also sets the default maximum packet size and maximum window size.
- def initialize(connection, type, local_id, &on_confirm_open)
+ def initialize(connection, type, local_id, max_pkt_size = 0x8000, max_win_size = 0x20000, &on_confirm_open)
self.logger = connection.logger
@connection = connection
@type = type
@local_id = local_id
- @local_maximum_packet_size = 0x10000
- @local_window_size = @local_maximum_window_size = 0x20000
+ @local_maximum_packet_size = max_pkt_size
+ @local_window_size = @local_maximum_window_size = max_win_size
@on_confirm_open = on_confirm_open
diff --git a/lib/net/ssh/connection/session.rb b/lib/net/ssh/connection/session.rb
index 13270da..548b2da 100644
--- a/lib/net/ssh/connection/session.rb
+++ b/lib/net/ssh/connection/session.rb
@@ -72,6 +72,9 @@ module Net; module SSH; module Connection
@channel_open_handlers = {}
@on_global_request = {}
@properties = (options[:properties] || {}).dup
+
+ @max_pkt_size = (options.has_key?(:max_pkt_size) ? options[:max_pkt_size] : 0x8000)
+ @max_win_size = (options.has_key?(:max_win_size) ? options[:max_win_size] : 0x20000)
end
# Retrieves a custom property from this instance. This can be used to
@@ -286,8 +289,8 @@ module Net; module SSH; module Connection
# channel.wait
def open_channel(type="session", *extra, &on_confirm)
local_id = get_next_channel_id
- channel = Channel.new(self, type, local_id, &on_confirm)
+ channel = Channel.new(self, type, local_id, @max_pkt_size, @max_win_size, &on_confirm)
msg = Buffer.from(:byte, CHANNEL_OPEN, :string, type, :long, local_id,
:long, channel.local_maximum_window_size,
:long, channel.local_maximum_packet_size, *extra)
@@ -503,7 +506,8 @@ module Net; module SSH; module Connection
info { "channel open #{packet[:channel_type]}" }
local_id = get_next_channel_id
- channel = Channel.new(self, packet[:channel_type], local_id)
+
+ channel = Channel.new(self, packet[:channel_type], local_id, @max_pkt_size, @max_win_size)
channel.do_open_confirmation(packet[:remote_id], packet[:window_size], packet[:packet_size])
callback = channel_open_handlers[packet[:channel_type]]