Module Name:    src
Committed By:   drochner
Date:           Wed Mar  9 11:36:43 UTC 2011

Modified Files:
        src/sys/opencrypto: deflate.c deflate.h

Log Message:
-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


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/opencrypto/deflate.c
cvs rdiff -u -r1.8 -r1.9 src/sys/opencrypto/deflate.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/opencrypto/deflate.c
diff -u src/sys/opencrypto/deflate.c:1.19 src/sys/opencrypto/deflate.c:1.20
--- src/sys/opencrypto/deflate.c:1.19	Thu Feb 24 20:03:41 2011
+++ src/sys/opencrypto/deflate.c	Wed Mar  9 11:36:43 2011
@@ -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;
 }

Index: src/sys/opencrypto/deflate.h
diff -u src/sys/opencrypto/deflate.h:1.8 src/sys/opencrypto/deflate.h:1.9
--- src/sys/opencrypto/deflate.h:1.8	Thu Feb 24 20:03:41 2011
+++ src/sys/opencrypto/deflate.h	Wed Mar  9 11:36:43 2011
@@ -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_ */

Reply via email to