> [libssh2] 2.676521 Failure Event: -29 - compress/decompression failure
> [libssh2] 2.676537 Failure Event: -1 - transport read
> [libssh2] 2.676547 Failure Event: -21 - Read part of packet
> [libssh2] 2.676558 Failure Event: -1 - Timeout waiting for status message
> 
> And there, I think, is a sign of the issue:
> 
>   [libssh2] 2.676521 Failure Event: -29 - compress/decompression failure
> 
> The question is, though: why did the decompression fail?  And why does it 
> fail at this point, when reading file data (as opposed to earlier, when 
> decompressing the rest of the messages on that subsystem/channel)?
> 
> I'll keep poking at this to see if I can find any additional clues...

I patched the src/comp.c file (see first attached patch) to try to get 
more information; in my particular use case, I saw:

  [libssh2] 3.316516 Transport: unhandled zlib error -5

According to the zlib.h header, a return value of -5 is Z_BUF_ERROR, which 
indicates (in the case of calling the inflate() zlib function) that there 
isn't enough space in the output buffer for the decompressor to make any 
progress.

That being the case, I tried increasing the size of the output buffers 
used for zlib decompression (see second attached patch), and things looked 
much better.  I'm not sure of just what the best increase in output buffer 
sizes/growth factors should be, though.

Cheers,
TJ

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   We are ashamed of everything that is real about us; ashamed of
   ourselves, of our relatives, of our incomes, of our accents, of
   our opinions, of our experience, just as we are ashamed of our
   naked skins.

        -George Bernard Shaw

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- src/comp.c.orig	2010-08-31 15:55:38.000000000 -0700
+++ src/comp.c	2010-08-31 15:54:43.000000000 -0700
@@ -208,6 +208,8 @@
         }
         if (status != Z_OK) {
             LIBSSH2_FREE(session, out);
+            _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+                           "unhandled zlib error %d", status);
             return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
                                   "compress/decompression failure");
         }
@@ -276,6 +278,8 @@
                 }
                 if (status != Z_OK) {
                     LIBSSH2_FREE(session, out);
+                    _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+                                   "unhandled zlib error %d", status);
                     return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
                                           "compress/decompression failure");
                 }
--- src/comp.c.orig	2010-08-31 15:55:38.000000000 -0700
+++ src/comp.c	2010-08-31 16:00:12.000000000 -0700
@@ -167,7 +167,7 @@
     /* A short-term alloc of a full data chunk is better than a series of
        reallocs */
     char *out;
-    int out_maxlen = compress ? (src_len + 4) : (2 * src_len);
+    int out_maxlen = compress ? (src_len + 4) : (8 * src_len);
     int limiter = 0;
 
     /* If strm is null, then we have not yet been initialized. */
@@ -208,6 +208,8 @@
         }
         if (status != Z_OK) {
             LIBSSH2_FREE(session, out);
+            _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+                           "unhandled zlib error %d", status);
             return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
                                   "compress/decompression failure");
         }
@@ -216,7 +218,7 @@
             char *newout;
 
             out_maxlen +=
-                compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
+                compress ? (strm->avail_in + 4) : (8 * strm->avail_in);
 
             if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
                 LIBSSH2_FREE(session, out);
@@ -234,14 +236,14 @@
             out = newout;
             strm->next_out = (unsigned char *) out + out_ofs;
             strm->avail_out +=
-                compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
+                compress ? (strm->avail_in + 4) : (8 * strm->avail_in);
         } else
             while (!strm->avail_out) {
                 /* Done with input, might be a byte or two in internal buffer
                  * during compress.  Or potentially many bytes if it's a
                  * decompress
                  */
-                int grow_size = compress ? 8 : 1024;
+                int grow_size = compress ? 8 : 2048;
                 char *newout;
 
                 if (out_maxlen >= (int) payload_limit) {
@@ -276,6 +278,8 @@
                 }
                 if (status != Z_OK) {
                     LIBSSH2_FREE(session, out);
+                    _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+                                   "unhandled zlib error %d", status);
                     return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
                                           "compress/decompression failure");
                 }
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to