Subject: libssh2_sftp_write now hangs eventually

libssh2_sftp_write now hangs eventually

From: Mark Riordan <mriordan_at_ipswitch.com>
Date: Wed, 3 Nov 2010 10:08:31 -0500

Daniel:

> I believe the problem was that the code didn't properly deal
> with the 32bit length field (that starts each SFTP packet)
> when the whole field could not be read at once.
>
> I've pushed a fix for this, please try again and if it still
> fails I'm interested in the return code and error message again!

Progress, but now it hangs. I've tried both to Solaris x86 and Ubuntu 10.04
x86,
with similar results. Eventually the write hangs, usually after only a few
writes.
(As you know, this is with the client running on Windows 2003R2.)

Here's typical output uploading to Ubuntu OpenSSH:

Not enabling compression.
Fingerprint: 8C D2 47 AC A6 9C 56 DA 60 7F A4 45 1A 4C 77 13 F1 B1 2C 0C
Authentication methods: publickey,password
libssh2_sftp_init()!
libssh2_sftp_open()!
libssh2_sftp_open() succeeded.
Using output buffer size of 32500 bytes
libssh2_sftp_write 1 sent 12000 bytes
libssh2_sftp_write 2 sent 4000 bytes
libssh2_sftp_write 3 sent 4000 bytes
libssh2_sftp_write 4 sent 4000 bytes
libssh2_sftp_write 5 sent 4000 bytes
libssh2_sftp_write 6 sent 4000 bytes
libssh2_sftp_write 7 sent 500 bytes
libssh2_sftp_write 8 sent 4000 bytes
libssh2_sftp_write 9 sent 8000 bytes
libssh2_sftp_write 10 sent 4000 bytes
(then it hangs)

Sometimes it hangs after write #2.

Naturally, if I enable tracing, the upload completes.
Thus, my 700+ MB trace logs aren't useful, so I'm not providing any.

Here's the tweaked upload code:

      hand = open(settings.localfile.c_str(), O_BINARY | O_RDONLY,
_S_IREAD);
      if (-1 == hand) {
         perror("opening local file");
         exit(2);
      }
      int nwrites = 0;
      char mem[32500];
      printf("Using output buffer size of %d bytes\n", sizeof(mem));
      do {
         /* loop until we fail */
         int nbytes = read(hand, mem, sizeof(mem));
         if (nbytes > 0) {
            filesize += nbytes;
            int offset = 0, bytes_to_send = nbytes;

            do {
               rc = libssh2_sftp_write(sftp_handle, mem + offset,
bytes_to_send);
               if (rc < 0) {
                  printf("libssh2_sftp_write failed with code %d\n", rc);
                  char *errmsg=NULL;
                  int errmsg_len=0;
                  rc = libssh2_session_last_error(session, &errmsg,
&errmsg_len, 0);
                  printf("libssh2_session_last_error() returned %s\n",
errmsg);
                  break;
               }
               ++nwrites;
               if (0 == (nwrites % 100) || settings.debug > 1) {
                  printf("libssh2_sftp_write %d sent %d bytes\n", nwrites,
rc);
               }
               offset += rc;
               bytes_to_send -= rc;
            } while (bytes_to_send > 0);
         } else {
            break;
         }
      } while (rc >= 0);

Thanks,
Mark

_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2010-11-03