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