diff options
author | Tom Deseyn <tom.deseyn@gmail.com> | 2021-01-05 16:15:24 +0100 |
---|---|---|
committer | Anderson Toshiyuki Sasaki <ansasaki@redhat.com> | 2021-01-11 20:38:24 +0100 |
commit | 44dfee778fb042d0d13a64c4d42ea0cb285ca2ae (patch) | |
tree | dd5009d33412e175902517401621453d39b8ab68 /src | |
parent | 710815674a907116c1864dd29c804039cd392616 (diff) | |
download | libssh-44dfee778fb042d0d13a64c4d42ea0cb285ca2ae.tar.gz libssh-44dfee778fb042d0d13a64c4d42ea0cb285ca2ae.tar.xz libssh-44dfee778fb042d0d13a64c4d42ea0cb285ca2ae.zip |
channesl: Fix delayed close
If the SSH2_MSG_CHANNEL_CLOSE was previously received, change the
channel state to SSH_STATE_CHANNEL_CLOSED in
ssh_channel_read_timeout() after reading all data available.
Fixes T31
Signed-off-by: Tom Deseyn <tom.deseyn@gmail.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/channels.c b/src/channels.c index 6747a841..262ff64a 100644 --- a/src/channels.c +++ b/src/channels.c @@ -648,6 +648,23 @@ SSH_PACKET_CALLBACK(channel_rcv_eof) { return SSH_PACKET_USED; } +static bool ssh_channel_has_unread_data(ssh_channel channel) +{ + if (channel == NULL) { + return false; + } + + if ((channel->stdout_buffer && + ssh_buffer_get_len(channel->stdout_buffer) > 0) || + (channel->stderr_buffer && + ssh_buffer_get_len(channel->stderr_buffer) > 0)) + { + return true; + } + + return false; +} + SSH_PACKET_CALLBACK(channel_rcv_close) { ssh_channel channel; (void)user; @@ -665,14 +682,12 @@ SSH_PACKET_CALLBACK(channel_rcv_close) { channel->local_channel, channel->remote_channel); - if ((channel->stdout_buffer && - ssh_buffer_get_len(channel->stdout_buffer) > 0) || - (channel->stderr_buffer && - ssh_buffer_get_len(channel->stderr_buffer) > 0)) { - channel->delayed_close = 1; - } else { + if (!ssh_channel_has_unread_data(channel)) { channel->state = SSH_CHANNEL_STATE_CLOSED; - } + } else { + channel->delayed_close = 1; + } + if (channel->remote_eof == 0) { SSH_LOG(SSH_LOG_PACKET, "Remote host not polite enough to send an eof before close"); @@ -1604,11 +1619,8 @@ int ssh_channel_is_eof(ssh_channel channel) { if(channel == NULL) { return SSH_ERROR; } - if ((channel->stdout_buffer && - ssh_buffer_get_len(channel->stdout_buffer) > 0) || - (channel->stderr_buffer && - ssh_buffer_get_len(channel->stderr_buffer) > 0)) { - return 0; + if (ssh_channel_has_unread_data(channel)) { + return 0; } return (channel->remote_eof != 0); @@ -2812,7 +2824,6 @@ static int ssh_channel_read_termination(void *s){ return 0; } -/* TODO FIXME Fix the delayed close thing */ /* TODO FIXME Fix the blocking behaviours */ /** @@ -2957,6 +2968,10 @@ int ssh_channel_read_timeout(ssh_channel channel, if (channel->counter != NULL) { channel->counter->in_bytes += len; } + /* Try completing the delayed_close */ + if (channel->delayed_close && !ssh_channel_has_unread_data(channel)) { + channel->state = SSH_CHANNEL_STATE_CLOSED; + } /* Authorize some buffering while userapp is busy */ if (channel->local_window < WINDOWLIMIT) { if (grow_window(session, channel, 0) < 0) { |