[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[patch]: Stop connector socket-to-channel EOF flooding
[Thread Prev] | [Thread Next]
[Date Prev] | [Date Next]
- Subject: [patch]: Stop connector socket-to-channel EOF flooding
- From: g4-lisz@xxxxxxxxxxxx
- Reply-to: libssh@xxxxxxxxxx
- Date: Mon, 1 Apr 2019 13:29:15 +0200
- To: libssh@xxxxxxxxxx
Hi there, I'm using connectors for a direct-tcp client. So this creates two connectors FD in --> channel out and vice versa. Now when the socket forwarding peer (not the ssh server) closes the connection, i.e. reading on the socket returns 0 = EOF, we end up in some loop with sending EOFs on the channel, until finally the client receives a channel close message. This is the debug output of OpenSSH server (-d -d): debug1: server_input_channel_open: confirm direct-tcpip debug1: Received SSH2_MSG_UNIMPLEMENTED for 8 debug1: channel 0: connected to 89.19.236.143 port 1022 debug2: channel 0: rcvd adjust 1216039 debug2: channel 0: rcvd eof debug2: channel 0: output open -> drain debug2: channel 0: obuf empty debug2: channel 0: close_write debug2: channel 0: output drain -> closed debug2: channel 0: rcvd eof debug2: channel 0: rcvd eof debug2: channel 0: rcvd eof debug2: channel 0: rcvd eof [...] debug2: channel 0: read<=0 rfd 8 len 0 debug2: channel 0: read failed debug2: channel 0: close_read debug2: channel 0: input open -> drain debug2: channel 0: ibuf empty debug2: channel 0: send eof debug2: channel 0: input drain -> closed debug2: channel 0: send close debug2: channel 0: rcvd eof The reason is in connector.c where ssh_connector_channel_write_wontblock_cb() functions also calls the ssh_connector_fd_in_cb(). So each time when "channel write won't block" it tries to read from from the socket, even when it already had been closed by the peer (EOF) . And sending an channel EOF triggers the channel's CBs again. In the connector code, EOF of the input socket is not really handled in a special way. It's more or less ignored. To change this, probably a lot of code had to be reworked, with the risk of breaking some other stuff... I have a very simple patch, which forces the EOF loop to end as soon as possible. It's more a workaround than a real fix. Please comment. Cheers, Till
From 823105d6267273be888505236725739949f5d2a9 Mon Sep 17 00:00:00 2001 From: Till Wimmer <g4-lisz@xxxxxxxxxxxx> Date: Mon, 1 Apr 2019 13:26:08 +0200 Subject: [PATCH] Stop connector socket-to-channel EOF flooding Signed-off-by: Till Wimmer <g4-lisz@xxxxxxxxxxxx> --- src/connector.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/connector.c b/src/connector.c index 0062785..1084d41 100644 --- a/src/connector.c +++ b/src/connector.c @@ -267,8 +267,13 @@ static void ssh_connector_fd_in_cb(ssh_connector connector) if (connector->out_channel != NULL) { if (r == 0) { - rc = ssh_channel_send_eof(connector->out_channel); - (void)rc; /* TODO Handle rc? */ + SSH_LOG(SSH_LOG_TRACE, "input fd %d is EOF", connector->in_fd); + if(connector->out_channel->local_eof == 0) { + rc = ssh_channel_send_eof(connector->out_channel); + (void)rc; /* TODO Handle rc? */ + } + connector->in_available = 1; /* Don't poll on it */ + return; } else if (r> 0) { /* loop around ssh_channel_write in case our window reduced due to a race */ while (total != r){ @@ -289,7 +294,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector) } } else if (connector->out_fd != SSH_INVALID_SOCKET) { if (r == 0){ - close (connector->out_fd); + close(connector->out_fd); connector->out_fd = SSH_INVALID_SOCKET; } else { /* -- 2.7.4
Re: [patch]: Stop connector socket-to-channel EOF flooding | g4-lisz@xxxxxxxxxxxx |