[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch]: Stop connector socket-to-channel EOF flooding


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


Archive administrator: postmaster@lists.cynapses.org