1 /*
2 ** COMPRESS functionality. RFC 8054.
3 */
4
5 #include "portable/system.h"
6
7 #include "inn/messages.h"
8 #include "nnrpd.h"
9
10 #if defined(HAVE_ZLIB)
11 # define ZBUFSIZE 65536
12 # define MEM_LEVEL 9
13 # define WINDOW_BITS (-15) /* Raw deflate. */
14 bool compression_layer_on = false;
15 bool tls_compression_on = false;
16 z_stream *zstream_in = NULL;
17 z_stream *zstream_out = NULL;
18 bool zstream_inflate_needed = false;
19 bool zstream_flush_needed = false;
20 unsigned char *zbuf_in = NULL;
21 unsigned char *zbuf_out = NULL;
22 size_t zbuf_in_size = NNTP_MAXLEN_COMMAND; /* Initial size of the input
23 * buffer. Can be reallocated. */
24 size_t zbuf_in_allocated = 0;
25 size_t zbuf_out_size = ZBUFSIZE; /* Initial size of the output buffer.
26 * Can be reallocated, when needed. */
27
28 /*
29 ** Wrappers for our memory management functions.
30 */
31 static voidpf
zalloc(voidpf opaque UNUSED,uInt items,uInt size)32 zalloc(voidpf opaque UNUSED, uInt items, uInt size)
33 {
34 return (voidpf) xcalloc(items, size);
35 }
36
37 static void
zfree(voidpf opaque UNUSED,voidpf address)38 zfree(voidpf opaque UNUSED, voidpf address)
39 {
40 free(address);
41 }
42
43
44 /*
45 ** The function called by nnrpd to initialize compression support. Calls
46 ** both deflateInit2 and inflateInit2, and then checks the result.
47 **
48 ** Returns false on error.
49 */
50 bool
zlib_init(void)51 zlib_init(void)
52 {
53 int result;
54 zstream_in = (z_stream *) xmalloc(sizeof(z_stream));
55 zstream_out = (z_stream *) xmalloc(sizeof(z_stream));
56
57 /* Allocate the buffer for compressed input data given to inflate(). */
58 zbuf_in = (unsigned char *) xmalloc(zbuf_in_size);
59
60 /* Allocate the buffer for compressed output data produced by deflate(). */
61 zbuf_out = (unsigned char *) xmalloc(zbuf_out_size);
62
63 zstream_in->zalloc = zalloc;
64 zstream_in->zfree = zfree;
65 zstream_in->opaque = Z_NULL;
66 zstream_in->next_in = Z_NULL;
67 zstream_in->avail_in = 0;
68
69 zstream_out->zalloc = zalloc;
70 zstream_out->zfree = zfree;
71 zstream_out->opaque = Z_NULL;
72
73 result = inflateInit2(zstream_in, WINDOW_BITS);
74
75 if (result != Z_OK) {
76 syslog(L_NOTICE, "inflateInit2() failed with error %d", result);
77 free(zstream_in);
78 free(zstream_out);
79 free(zbuf_in);
80 free(zbuf_out);
81 return false;
82 }
83
84 result = deflateInit2(zstream_out, Z_BEST_COMPRESSION, Z_DEFLATED,
85 WINDOW_BITS, MEM_LEVEL, Z_DEFAULT_STRATEGY);
86
87 if (result != Z_OK) {
88 syslog(L_NOTICE, "deflateInit2() failed with error %d", result);
89 inflateEnd(zstream_in);
90 free(zstream_in);
91 free(zstream_out);
92 free(zbuf_in);
93 free(zbuf_out);
94 return false;
95 }
96
97 return true;
98 }
99
100 #endif /* HAVE_ZLIB */
101