On Mon, 12 Mar 2012, Matthew Booth wrote:

seems to be down to an unchecked error in _libssh2_channel_write():

       /* drain the incoming flow first, mostly to make sure we get all
        * pending window adjust packets */
       do
           rc = _libssh2_transport_read(session);
       while (rc > 0);

       if(channel->local.window_size <= 0)
           /* there's no room for data so we stop */
           return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);

In my case, _libssh2_transport_read is returning LIBSSH2_ERROR_SOCKET_RECV (don't know why yet). The result of this in the above code is that _libssh2_channel_write returns 0, throwing away the error information. My code spots a zero return, checks for eof, doesn't find one and goes round again: infinite loop.

I would just submit a patch which adds "if (rc<0) return rc;" immediately after the read loop, but it seems like the author has intentionally not done this here. Git commit 3c71ad4fce745876f7e7ad33b846518f2d50edf6 and its associated mailing list thread doesn't shed any light on why only EAGAIN is handled. Can anybody explain?

I think I only added code to handle the EAGAIN case since that was the particular case I was out to fix and I played safe and didn't modify the other cases.

But I agree that it looks wrong. I would probably suggest this change as a slight variation of your suggestion:

diff --git a/src/channel.c b/src/channel.c
index 8d6fb0a..9e29492 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2008,6 +2008,9 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int strea
             rc = _libssh2_transport_read(session);
         while (rc > 0);

+        if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
+            return rc;
+
         if(channel->local.window_size <= 0)
             /* there's no room for data so we stop */
             return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);

The existing code continues even if LIBSSH2_ERROR_EAGAIN was returned as long as there is window size to go with so we should probably continue doing so.

--

 / daniel.haxx.se
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to