From 733df553cc598e16ba099432d1b6464f074b5a4c Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 10 Apr 2013 11:08:10 +0200 Subject: 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. --- lib/net/ssh.rb | 7 ++++++- lib/net/ssh/connection/channel.rb | 6 +++--- lib/net/ssh/connection/session.rb | 8 ++++++-- 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]] -- cgit v1.2.1