Subject: Re: [libssh2] libssh2-0.16 hanging on scp copy

Re: [libssh2] libssh2-0.16 hanging on scp copy

From: Daniel Stenberg <>
Date: Thu, 9 Aug 2007 23:57:31 +0200 (CEST)

On Thu, 9 Aug 2007, Daniel Stenberg wrote:

> Me too, and I'll offer what I've learned so far (no fix yet but I'll continue
> tomorrow):
> src/transport.c:311
> This is wrong. It checks if amount of already read data is less than
> 'minimum' and if so it reads more. In my case, I can get it to reach there
> in the middle of a transfer with 'remainbuf' to be 4 and 'minimum' to be 4
> as well. (Thus, the following block is not executed.)

Ok friends, I'll need some help and eyes on this.

As I mentioned above, the check is bad and the patch below[1] is what I think
will rectify this. Do note that this is almost a revertion of the
src/transport.c 1.6 commit by me: "Eberhard Mattes' fix for
libssh2_packet_read() for when reading very small chunks at a time.".

But... with this applied I still get a hang repeatedly! That flaw was not the
only one lurking.

This second hang (busy-loop) occurs when select() in scp_nonblock.c returns 1
because the socket is *writeable* but not readable (I edited the example
somewhat to give me this info). It will then make the loop continue to
libssh2_channel_read() which will returns swiftly with LIBSSH2_ERROR_EAGAIN
since it couldn't recv() anything from the socket and back to select() again
that returns 1...

Why on earth does it suddenly turn writable? It seems to have at various times
but I've not yet managed to get scp_nonblock to copy my 85MB test file over
localhost! ;-O

Anyway, I'll sleep on it now but if you have any input or suggestions, please
speak up!

[1] =

--- src/transport.c 6 Aug 2007 20:48:07 -0000 1.10
+++ src/transport.c 9 Aug 2007 21:42:54 -0000
@@ -267,7 +267,6 @@
      int numdecrypt;
      unsigned char block[MAX_BLOCKSIZE];
      int blocksize;
- int minimum;
      int encrypted = 1;

@@ -293,7 +292,6 @@
              blocksize = 5; /* not strictly true, but we can use 5 here to
                                     make the checks below work fine still */
- minimum = p->total_num ? p->total_num - p->data_num : blocksize;

          /* read/use a whole big chunk into a temporary area stored in
             the LIBSSH2_SESSION struct. We will decrypt data from that
@@ -308,8 +306,8 @@
          /* if remainbuf turns negative we have a bad internal error */
          assert(remainbuf >= 0);

- if (remainbuf < minimum) {
- /* If we have less than a minimum left, it is too
+ if (remainbuf < blocksize) {
+ /* If we have less than a blocksize left, it is too
                 little data to deal with,
              ssize_t nread;

This email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>
libssh2-devel mailing list
Received on 2007-08-09