I've been encountering an issue in my application where it reliably gets into an infinite loop part way through a very large data transfer. The application is exclusively sending data during the transfer. The problem seems to relate to a transport error which I haven't yet gotten to the bottom of. However, the infinite loop 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?

Thanks,

Matt
--
Matthew Booth, RHCA, RHCSS
Red Hat Engineering, Virtualisation Team

GPG ID:  D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to