Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/opencrypto -start to make the GZIP code similar to DEFLA...



details:   https://anonhg.NetBSD.org/src/rev/73c1a528cb87
branches:  trunk
changeset: 763051:73c1a528cb87
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Mar 09 11:36:43 2011 +0000

description:
-start to make the GZIP code similar to DEFLATE: make error handling
 work the same way, grow output buffer exponentially and kill
 reallocation of metadata
-minor cleanup, make definitions private which are implementation
 details of deflate.gzip

diffstat:

 sys/opencrypto/deflate.c |  92 ++++++++++++++++++++---------------------------
 sys/opencrypto/deflate.h |  10 +----
 2 files changed, 41 insertions(+), 61 deletions(-)

diffs (231 lines):

diff -r 602b33f7eecf -r 73c1a528cb87 sys/opencrypto/deflate.c
--- a/sys/opencrypto/deflate.c  Wed Mar 09 10:10:19 2011 +0000
+++ b/sys/opencrypto/deflate.c  Wed Mar 09 11:36:43 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: deflate.c,v 1.19 2011/02/24 20:03:41 drochner Exp $ */
+/*     $NetBSD: deflate.c,v 1.20 2011/03/09 11:36:43 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/deflate.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $  */
 /* $OpenBSD: deflate.c,v 1.3 2001/08/20 02:45:22 hugh Exp $ */
 
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.19 2011/02/24 20:03:41 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.20 2011/03/09 11:36:43 drochner Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -46,6 +46,12 @@
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/deflate.h>
 
+#define ZBUF 10
+
+struct deflate_buf {
+       u_int8_t *out;
+       u_int32_t size;
+};
 
 int window_inflate = -1 * MAX_WBITS;
 int window_deflate = -12;
@@ -225,50 +231,37 @@
        z_stream zbuf;
        u_int8_t *output;
        u_int32_t count, result;
-       int error, i = 0, j;
-       struct deflate_buf *buf, *tmp;
-       size_t nbufs;
+       int error, i, j;
+       struct deflate_buf buf[ZBUF];
        u_int32_t crc;
        u_int32_t isize, icrc;
 
        DPRINTF(("gzip_global: decomp %d, size %d\n", decomp, size));
 
-       nbufs = ZBUF;
-       buf = malloc(nbufs*sizeof(struct deflate_buf), M_CRYPTO_DATA, M_NOWAIT);
-       if (buf == NULL) {
-               DPRINTF(("gzip_global.%d: failed to malloc %d\n",
-                               __LINE__, nbufs*sizeof(struct deflate_buf)));
-               return 0;
-       }
-
        memset(&zbuf, 0, sizeof(z_stream));
        zbuf.zalloc = ocf_zalloc;
        zbuf.zfree = ocf_zfree;
        zbuf.opaque = Z_NULL;
 
-       crc = crc32(0, NULL, 0);        /* get initial crc value */
-
-       zbuf.avail_in = size;   /* Total length of data to be processed */
-       zbuf.next_in = data;    /* data that is going to be processed */
-
        if (!decomp) {
                /* compress */
-               DPRINTF(("gzip_global: compress[%d] malloc %d + %d + %d = %d\n",
-                               i, size, sizeof(gzip_header), GZIP_TAIL_SIZE,
+               DPRINTF(("gzip_global: compress malloc %d + %d + %d = %d\n",
+                               size, sizeof(gzip_header), GZIP_TAIL_SIZE,
                                size + sizeof(gzip_header) + GZIP_TAIL_SIZE));
 
                buf[0].size = size;
-
-               crc = crc32(crc, data, size);
+               crc = crc32(0, data, size);
                DPRINTF(("gzip_compress: size %d, crc 0x%x\n", size, crc));
+               zbuf.avail_in = size;   /* Total length of data to be processed */
+               zbuf.next_in = data;    /* data that is going to be processed */
        } else {
                /* decompress */
                /* check the gzip header */
-               if (zbuf.avail_in <= 0) {
+               if (size <= sizeof(gzip_header) + GZIP_TAIL_SIZE) {
                        /* Not enough data for the header & tail */
                        DPRINTF(("gzip_global: not enough data (%d)\n",
                                        size));
-                       goto bad2;
+                       return 0;
                }
 
                /* XXX this is pretty basic,
@@ -281,7 +274,7 @@
                if (memcmp(data, gzip_header, sizeof(gzip_header)) != 0) {
                        DPRINTF(("gzip_global: unsupported gzip header (%02x%02x)\n",
                                        data[0], data[1]));
-                       goto bad2;
+                       return 0;
                } else {
                        DPRINTF(("gzip_global.%d: gzip header ok\n",__LINE__));
                }
@@ -299,6 +292,7 @@
                                data[size-1]));
 
                buf[0].size = isize;
+               crc = crc32(0, NULL, 0);        /* get initial crc value */
 
                /* skip over the gzip header */
                zbuf.next_in = data + sizeof(gzip_header);
@@ -309,7 +303,7 @@
 
        buf[0].out = malloc(buf[0].size, M_CRYPTO_DATA, M_NOWAIT);
        if (buf[0].out == NULL)
-               goto bad2;
+               return 0;
        zbuf.next_out = buf[0].out;
        zbuf.avail_out = buf[0].size;
        DPRINTF(("zbuf avail_in %d, avail_out %d\n",
@@ -322,7 +316,7 @@
 
        if (error != Z_OK) {
                printf("deflateInit2() failed\n");
-               goto bad;
+               goto bad2;
        }
        for (;;) {
                DPRINTF(("pre: %s in:%d out:%d\n", decomp ? "deflate()" : "inflate()", 
@@ -331,37 +325,32 @@
                                 deflate(&zbuf, Z_FINISH);
                DPRINTF(("post: %s in:%d out:%d\n", decomp ? "deflate()" : "inflate()", 
                                zbuf.avail_in, zbuf.avail_out));
-               if (error != Z_OK && error != Z_STREAM_END) {
-                       printf("deflate() or inflate() failed, error=%d\n", error);
+               if (error == Z_STREAM_END) /* success */
+                       break;
+               /*
+                * XXX compensate for a zlib problem:
+                * -sys/net/zlib.c has a bug which makes that Z_BUF_ERROR is
+                *  set after successful decompression under rare conditions.
+                */
+               else if (decomp && error == Z_BUF_ERROR
+                        && zbuf.avail_in == 0 && zbuf.avail_out != 0)
+                               break;
+               else if (error != Z_OK)
                        goto bad;
-               } else if (zbuf.avail_in == 0 && zbuf.avail_out != 0) {
-                       DPRINTF(("gzip_global: avail_in == 0, ending\n"));
-                       goto end;
-               } else if (zbuf.avail_in == 0 && zbuf.avail_out == 0) {
-                       DPRINTF(("gzip_global: avail_in == 0, avail_out == 0, ending\n"));
-                       goto end;
-               } else if (zbuf.avail_out == 0) {
-                       if (i == nbufs) {
-                               nbufs += ZBUF;
-                               tmp = realloc(buf,nbufs*sizeof(struct deflate_buf),
-                                                         M_CRYPTO_DATA, M_NOWAIT);
-                               if (tmp == NULL)
-                                       goto bad;
-                               buf = tmp;
-                       }
+               else if (zbuf.avail_out == 0) {
                        /* we need more output space, allocate size */
-                       buf[i].out = malloc(size, M_CRYPTO_DATA, M_NOWAIT);
+                       int nextsize = buf[i-1].size * 2;
+                       if (i == ZBUF || nextsize > 1000000)
+                               goto bad;
+                       buf[i].out = malloc(nextsize, M_CRYPTO_DATA, M_NOWAIT);
                        if (buf[i].out == NULL)
                                goto bad;
                        zbuf.next_out = buf[i].out;
-                       buf[i].size = size;
-                       zbuf.avail_out = buf[i].size;
+                       zbuf.avail_out = buf[i].size = nextsize;
                        i++;
-               } else
-                       goto bad;
+               }
        }
 
-end:
        if (decomp) {
                count = result = zbuf.total_out;
        } else {
@@ -403,7 +392,6 @@
                        count = 0;
                }
        }
-       free(buf, M_CRYPTO_DATA);
 
        if (!decomp) {
                /* fill in CRC and ISIZE */
@@ -420,6 +408,7 @@
                                output[4]));
        } else {
                if (crc != icrc || result != isize) {
+                       DPRINTF(("gzip_global: crc/size mismatch\n"));
                        free(*out, M_CRYPTO_DATA);
                        *out = NULL;
                        return 0;
@@ -437,6 +426,5 @@
        *out = NULL;
        for (j = 0; j < i; j++)
                free(buf[j].out, M_CRYPTO_DATA);
-       free(buf, M_CRYPTO_DATA);
        return 0;
 }
diff -r 602b33f7eecf -r 73c1a528cb87 sys/opencrypto/deflate.h
--- a/sys/opencrypto/deflate.h  Wed Mar 09 10:10:19 2011 +0000
+++ b/sys/opencrypto/deflate.h  Wed Mar 09 11:36:43 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: deflate.h,v 1.8 2011/02/24 20:03:41 drochner Exp $ */
+/*     $NetBSD: deflate.h,v 1.9 2011/03/09 11:36:43 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/deflate.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $  */
 /* $OpenBSD: deflate.h,v 1.3 2002/03/14 01:26:51 millert Exp $ */
 
@@ -42,16 +42,8 @@
 #define Z_METHOD       8
 #define Z_MEMLEVEL     8
 #define MINCOMP                2       /* won't be used, but must be defined */
-#define ZBUF           10
 
 u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **, int);
 u_int32_t gzip_global(u_int8_t *, u_int32_t, int, u_int8_t **, int);
-void *z_alloc(void *, u_int, u_int);
-void z_free(void *, void *);
-
-struct deflate_buf {
-       u_int8_t *out;
-       u_int32_t size;
-};
 
 #endif /* _CRYPTO_DEFLATE_H_ */



Home | Main Index | Thread Index | Old Index