aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2010-10-01 18:38:08 +0200
committerAris Adamantiadis <aris@0xbadc0de.be>2010-10-01 18:38:08 +0200
commit5675fbe73eb21792d012f60c0e5b38aedf8963bb (patch)
tree99c384f7dc3dc98b3c6c4e6093a03130d527855a
parent5b1c985a0e7df03aefffa13bc6c765859819a180 (diff)
downloadlibssh-5675fbe73eb21792d012f60c0e5b38aedf8963bb.tar.gz
libssh-5675fbe73eb21792d012f60c0e5b38aedf8963bb.tar.xz
libssh-5675fbe73eb21792d012f60c0e5b38aedf8963bb.zip
Fix the behaviour of channel window handling
-rw-r--r--src/channels.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/src/channels.c b/src/channels.c
index 90fee25e..cd63d284 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -303,38 +303,53 @@ ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
return channel;
}
+/**
+ * @internal
+ * @brief grows the local window and send a packet to the other party
+ * @param session SSH session
+ * @param channel SSH channel
+ * @param minimumsize The minimum acceptable size for the new window.
+ */
static int grow_window(ssh_session session, ssh_channel channel, int minimumsize) {
uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;
enter_function();
-
+ if(new_window <= channel->local_window){
+ ssh_log(session,SSH_LOG_PROTOCOL,
+ "growing window (channel %d:%d) to %d bytes : not needed (%d bytes)",
+ channel->local_channel, channel->remote_channel, new_window,
+ channel->local_window);
+ leave_function();
+ return SSH_OK;
+ }
+ /* WINDOW_ADJUST packet needs a relative increment rather than an absolute
+ * value, so we give here the missing bytes needed to reach new_window
+ */
if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_WINDOW_ADJUST) < 0 ||
buffer_add_u32(session->out_buffer, htonl(channel->remote_channel)) < 0 ||
- buffer_add_u32(session->out_buffer, htonl(new_window)) < 0) {
+ buffer_add_u32(session->out_buffer, htonl(new_window - channel->local_window)) < 0) {
goto error;
}
if (packet_send(session) == SSH_ERROR) {
- /* FIXME should we fail here or not? */
- leave_function();
- return 1;
+ goto error;
}
ssh_log(session, SSH_LOG_PROTOCOL,
"growing window (channel %d:%d) to %d bytes",
channel->local_channel,
channel->remote_channel,
- channel->local_window + new_window);
+ new_window);
- channel->local_window += new_window;
+ channel->local_window = new_window;
leave_function();
- return 0;
+ return SSH_OK;
error:
buffer_reinit(session->out_buffer);
leave_function();
- return -1;
+ return SSH_ERROR;
}
/**
@@ -1996,8 +2011,7 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
channel->local_window);
if (count > buffer_get_rest_len(stdbuf) + channel->local_window) {
- if (grow_window(session, channel,
- count - buffer_get_rest_len(stdbuf)) < 0) {
+ if (grow_window(session, channel, count) < 0) {
leave_function();
return -1;
}
@@ -2019,7 +2033,9 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
}
ssh_handle_packets(session,-1);
}
-
+ /* XXX This is probably not the good moment to increase the window,
+ * but since the function is deprecated I won't fix it
+ */
if(channel->local_window < WINDOWLIMIT) {
if (grow_window(session, channel, 0) < 0) {
leave_function();
@@ -2099,8 +2115,7 @@ int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_std
channel->local_window);
if (count > buffer_get_rest_len(stdbuf) + channel->local_window) {
- if (grow_window(session, channel,
- count - buffer_get_rest_len(stdbuf)) < 0) {
+ if (grow_window(session, channel, count - buffer_get_rest_len(stdbuf)) < 0) {
leave_function();
return -1;
}
@@ -2127,7 +2142,7 @@ int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_std
ssh_handle_packets(session,-1);
}
-
+ /* Authorize some buffering while userapp is busy */
if (channel->local_window < WINDOWLIMIT) {
if (grow_window(session, channel, 0) < 0) {
leave_function();