mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 18:50:28 +09:00
Emit channel_write_wontblock when remote window becomes non-zero.
Signed-off-by: Tom Deseyn <tom.deseyn@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
@@ -512,6 +512,8 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
|||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
int rc;
|
int rc;
|
||||||
|
bool was_empty;
|
||||||
|
|
||||||
(void)user;
|
(void)user;
|
||||||
(void)type;
|
(void)type;
|
||||||
|
|
||||||
@@ -535,8 +537,21 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
|||||||
channel->remote_channel,
|
channel->remote_channel,
|
||||||
channel->remote_window);
|
channel->remote_window);
|
||||||
|
|
||||||
|
was_empty = channel->remote_window == 0;
|
||||||
|
|
||||||
channel->remote_window += bytes;
|
channel->remote_window += bytes;
|
||||||
|
|
||||||
|
/* Writing to the channel is non-blocking until the receive window is empty.
|
||||||
|
When the receive window becomes non-zero again, call channel_write_wontblock_function. */
|
||||||
|
if (was_empty && bytes > 0) {
|
||||||
|
ssh_callbacks_execute_list(channel->callbacks,
|
||||||
|
ssh_channel_callbacks,
|
||||||
|
channel_write_wontblock_function,
|
||||||
|
session,
|
||||||
|
channel,
|
||||||
|
channel->remote_window);
|
||||||
|
}
|
||||||
|
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1510,7 +1525,7 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
"Remote window is %" PRIu32 " bytes. going to write %" PRIu32 " bytes",
|
"Remote window is %" PRIu32 " bytes. going to write %" PRIu32 " bytes",
|
||||||
channel->remote_window,
|
channel->remote_window,
|
||||||
len);
|
len);
|
||||||
/* What happens when the channel window is zero? */
|
/* When the window is zero, wait for it to grow */
|
||||||
if(channel->remote_window == 0) {
|
if(channel->remote_window == 0) {
|
||||||
/* nothing can be written */
|
/* nothing can be written */
|
||||||
SSH_LOG(SSH_LOG_DEBUG,
|
SSH_LOG(SSH_LOG_DEBUG,
|
||||||
@@ -1524,6 +1539,7 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
goto out;
|
goto out;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* When the window is non-zero, accept data up to the window size */
|
||||||
effectivelen = MIN(len, channel->remote_window);
|
effectivelen = MIN(len, channel->remote_window);
|
||||||
} else {
|
} else {
|
||||||
effectivelen = len;
|
effectivelen = len;
|
||||||
|
|||||||
25
src/packet.c
25
src/packet.c
@@ -1394,34 +1394,9 @@ error:
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssh_packet_socket_controlflow_callback(int code, void *userdata)
|
|
||||||
{
|
|
||||||
ssh_session session = userdata;
|
|
||||||
struct ssh_iterator *it;
|
|
||||||
ssh_channel channel;
|
|
||||||
|
|
||||||
if (code == SSH_SOCKET_FLOW_WRITEWONTBLOCK) {
|
|
||||||
SSH_LOG(SSH_LOG_TRACE, "sending channel_write_wontblock callback");
|
|
||||||
|
|
||||||
/* the out pipe is empty so we can forward this to channels */
|
|
||||||
it = ssh_list_get_iterator(session->channels);
|
|
||||||
while (it != NULL) {
|
|
||||||
channel = ssh_iterator_value(ssh_channel, it);
|
|
||||||
ssh_callbacks_execute_list(channel->callbacks,
|
|
||||||
ssh_channel_callbacks,
|
|
||||||
channel_write_wontblock_function,
|
|
||||||
session,
|
|
||||||
channel,
|
|
||||||
channel->remote_window);
|
|
||||||
it = it->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){
|
void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){
|
||||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
session->socket_callbacks.data=ssh_packet_socket_callback;
|
||||||
session->socket_callbacks.connected=NULL;
|
session->socket_callbacks.connected=NULL;
|
||||||
session->socket_callbacks.controlflow = ssh_packet_socket_controlflow_callback;
|
|
||||||
session->socket_callbacks.userdata=session;
|
session->socket_callbacks.userdata=session;
|
||||||
ssh_socket_set_callbacks(s,&session->socket_callbacks);
|
ssh_socket_set_callbacks(s,&session->socket_callbacks);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user