Subject: nonblocking setting _INBOUND, but no data expected

nonblocking setting _INBOUND, but no data expected

From: John-Mark Gurney <jmg_at_funkthat.com>
Date: Thu, 15 Oct 2020 12:18:17 -0700

I've run into an issue where libssh2 (6c7769dcc42) is setting the
_INBOUND flag, BUT, I'm not expecting anymore data (and I don't think
libssh2 is either). Complicating maters is that there is data to be read
on the socket. This means that my program gets into a busy loop.

Short overview of the program is that it's using sftp to read/write
parts of a file as requested, effectively using sftp as a remote file
store...

I can publish the code that triggers it, and I have slightly modfied
sftp code so that it doesn't do read ahead (which may be prt of the
issue, and I will create a PR to allow disabling read ahead), as in my
applciation, reading extra data is not wanted as it will likely waste
bandwidth. Also my code is a WIP, so I'd like to get things a bit
farther before publishing...

But the trace is pretty self explanitory in that you see it setting the
flag (I added the code), but then proceeding to do additional reads, but
not clearing the flag after the reads:
[libssh2] 10.834965 SFTP: recv packet
[libssh2] 10.834980 Conn: channel_read() wants 4 bytes from channel 0/0 stream #0
[libssh2] 10.835002 Socket: setting INBOUND flag, nread: -35
[libssh2] 10.835022 Conn: channel_read() got 4 of data from 0/0/0
[libssh2] 10.835038 SFTP: Data begin - Packet Length: 30009
[libssh2] 10.835058 Conn: channel_read() wants 30009 bytes from channel 0/0 stream #0
[libssh2] 10.835080 Socket: setting INBOUND flag, nread: -35
[libssh2] 10.835099 Conn: channel_read() got 16380 of data from 0/0/0 [ul]
[libssh2] 10.835137 Conn: channel_read() got 13629 of data from 0/0/0 [ul]
[libssh2] 10.835171 SFTP: Received packet type 103 (len 30009)
[libssh2] 10.835186 SFTP: Received packet id 1229
debug: sftp_read ret: 111232
debug: sftp_read: 19791872(131072), rem: 0
debug: sftp_read ret: 0
debug: cmd complete: seq: 35026, cmd: 1
debug: selecting: inbound , read: sockfd: 1, popfd: 1, write: sockfd: 0
debug: select: 1, read: sockfd: 1, popfd: 0, write: sockfd: 0
debug: selecting: inbound , read: sockfd: 1, popfd: 1, write: sockfd: 0
debug: select: 1, read: sockfd: 1, popfd: 0, write: sockfd: 0
debug: selecting: inbound , read: sockfd: 1, popfd: 1, write: sockfd: 0
debug: select: 1, read: sockfd: 1, popfd: 0, write: sockfd: 0
debug: selecting: inbound , read: sockfd: 1, popfd: 1, write: sockfd: 0
debug: select: 1, read: sockfd: 1, popfd: 0, write: sockfd: 0
[continued to repeat till I stop the program]

the diff adding the above is:
diff --git a/src/transport.c b/src/transport.c
index 0723b77..dbee285 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -376,6 +376,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
                 if((nread < 0) && (nread == -EAGAIN)) {
                     session->socket_block_directions |=
                         LIBSSH2_SESSION_BLOCK_INBOUND;
+ _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
+ "setting INBOUND flag, nread: %d", nread);
                     return LIBSSH2_ERROR_EAGAIN;
                 }
                 _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,

It seems like the flag should always be cleared when the function
channel_read successfully reads data... But from looking at the
code, this doesn't look safe to do in _libssh2_channel_read...

Thoughts/comments?

-- 
  John-Mark Gurney				Voice: +1 415 225 5579
     "All that I will do, has been done, All that I have, has not."
_______________________________________________
libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2020-10-15