From 5c14f0e6ecfe73da86d3ad20edd60c4756037935 Mon Sep 17 00:00:00 2001 From: Salvador Date: Wed, 16 Oct 2013 13:31:31 +0200 Subject: [PATCH 09/11] _libssh2_channel_read: Honour window_size_initial _libssh2_channel_read was using an arbitrary hard-coded limit to trigger the window adjusting code. The adjustment used was also hard-coded and arbitrary, 15MB actually, which would limit the usability of libssh2 on systems with little RAM. This patch, uses the window_size parameter passed to libssh2_channel_open_ex (stored as remote.window_size_initial) plus the buflen as the base for the trigger and the adjustment calculation. The memory usage when using the default window size is reduced from 22MB to 256KB per channel (actually, if compression is used, these numbers should be incremented by ~50% to account for the errors between the decompressed packet sizes and the predicted sizes). My tests indicate that this change does not impact the performance of transfers across localhost or a LAN, being it on par with that of OpenSSH. On the other hand, it will probably slow down transfers on networks with high bandwidth*delay when the default window size (LIBSSH2_CHANNEL_WINDOW_DEFAULT=256KB) is used. Signed-off-by: Salvador Fandino [upstream commit 1b3307dda0c58d9023a657747592ac86703b1ff4] Signed-off-by: Kamil Dudka --- src/channel.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/channel.c b/src/channel.c index 82f6980..36c75d2 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1758,14 +1758,17 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, stream_id); /* expand the receiving window first if it has become too narrow */ - if((channel->read_state == libssh2_NB_state_jump1) || - (channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30))) { + if( (channel->read_state == libssh2_NB_state_jump1) || + (channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) { + + uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size; + if (adjustment < LIBSSH2_CHANNEL_MINADJUST) + adjustment = LIBSSH2_CHANNEL_MINADJUST; /* the actual window adjusting may not finish so we need to deal with this special state here */ channel->read_state = libssh2_NB_state_jump1; - rc = _libssh2_channel_receive_window_adjust(channel, - (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), + rc = _libssh2_channel_receive_window_adjust(channel, adjustment, 0, NULL); if (rc) return rc; -- 1.7.1