Tor 0.4.9.3-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
compress.c
Go to the documentation of this file.
1/* Copyright (c) 2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4/* See LICENSE for licensing information */
5
6/**
7 * \file compress.c
8 * \brief Common compression API implementation.
9 *
10 * This file provides a unified interface to all the compression libraries Tor
11 * knows how to use.
12 **/
13
14#include "orconfig.h"
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19#include "lib/cc/torint.h"
20
21#ifdef HAVE_NETINET_IN_H
22#include <netinet/in.h>
23#endif
24
25#include "lib/log/log.h"
26#include "lib/log/util_bug.h"
27#include "lib/arch/bytes.h"
28#include "lib/ctime/di_ops.h"
35#include "lib/intmath/cmp.h"
36#include "lib/malloc/malloc.h"
37#include "lib/subsys/subsys.h"
38#include "lib/thread/threads.h"
39
40/** Total number of bytes allocated for compression state overhead. */
42
43/** @{ */
44/* These macros define the maximum allowable compression factor. Anything of
45 * size greater than CHECK_FOR_COMPRESSION_BOMB_AFTER is not allowed to
46 * have an uncompression factor (uncompressed size:compressed size ratio) of
47 * any greater than MAX_UNCOMPRESSION_FACTOR.
48 *
49 * Picking a value for MAX_UNCOMPRESSION_FACTOR is a trade-off: we want it to
50 * be small to limit the attack multiplier, but we also want it to be large
51 * enough so that no legitimate document --even ones we might invent in the
52 * future -- ever compresses by a factor of greater than
53 * MAX_UNCOMPRESSION_FACTOR. Within those parameters, there's a reasonably
54 * large range of possible values. IMO, anything over 8 is probably safe; IMO
55 * anything under 50 is probably sufficient.
56 */
57#define MAX_UNCOMPRESSION_FACTOR 25
58#define CHECK_FOR_COMPRESSION_BOMB_AFTER (1024*64)
59/** @} */
60
61/** Return true if uncompressing an input of size <b>in_size</b> to an input of
62 * size at least <b>size_out</b> looks like a compression bomb. */
63MOCK_IMPL(int,
64tor_compress_is_compression_bomb,(size_t size_in, size_t size_out))
65{
66 if (size_in == 0 || size_out < CHECK_FOR_COMPRESSION_BOMB_AFTER)
67 return 0;
68
69 double compression_factor = (double)size_out / size_in;
70 if (compression_factor > MAX_UNCOMPRESSION_FACTOR) {
71 log_warn(LD_GENERAL,
72 "Detected possible compression bomb with "
73 "input size = %"TOR_PRIuSZ" and output size = %"TOR_PRIuSZ" "
74 "(compression factor = %.2f)",
75 size_in, size_out, compression_factor);
76 return 1;
77 }
78
79 return 0;
80}
81
82/** Guess the size that <b>in_len</b> will be after compression or
83 * decompression. */
84static size_t
86 compression_level_t compression_level,
87 size_t in_len)
88{
89 // ignore these for now.
90 (void)compression_level;
91 if (method == NO_METHOD) {
92 /* Guess that we'll need an extra byte, to avoid a needless realloc
93 * for nul-termination */
94 return (in_len < SIZE_MAX) ? in_len + 1 : in_len;
95 }
96
97 /* Always guess a factor of 2. */
98 if (compress) {
99 in_len /= 2;
100 } else {
101 if (in_len < SIZE_T_CEILING/2)
102 in_len *= 2;
103 }
104 return MAX(in_len, 1024);
105}
106
107/** Internal function to implement tor_compress/tor_uncompress, depending on
108 * whether <b>compress</b> is set. All arguments are as for tor_compress or
109 * tor_uncompress. */
110static int
111tor_compress_impl(int compress,
112 char **out, size_t *out_len,
113 const char *in, size_t in_len,
114 compress_method_t method,
115 compression_level_t compression_level,
116 int complete_only,
117 int protocol_warn_level)
118{
119 tor_compress_state_t *stream;
120 int rv;
121
122 stream = tor_compress_new(compress, method, compression_level);
123
124 if (stream == NULL) {
125 log_warn(LD_GENERAL, "NULL stream while %scompressing",
126 compress?"":"de");
127 log_debug(LD_GENERAL, "method: %d level: %d at len: %lu",
128 method, compression_level, (unsigned long)in_len);
129 return -1;
130 }
131
132 size_t in_len_orig = in_len;
133 size_t out_remaining, out_alloc;
134 char *outptr;
135
136 out_remaining = out_alloc =
137 guess_compress_size(compress, method, compression_level, in_len);
138 *out = outptr = tor_malloc(out_remaining);
139
140 const int finish = complete_only || compress;
141
142 while (1) {
143 switch (tor_compress_process(stream,
144 &outptr, &out_remaining,
145 &in, &in_len, finish)) {
146 case TOR_COMPRESS_DONE:
147 if (in_len == 0 || compress) {
148 goto done;
149 } else {
150 // More data is present, and we're decompressing. So we may need to
151 // reinitialize the stream if we are handling multiple concatenated
152 // inputs.
153 tor_compress_free(stream);
154 stream = tor_compress_new(compress, method, compression_level);
155 if (stream == NULL) {
156 log_warn(LD_GENERAL, "NULL stream while %scompressing",
157 compress?"":"de");
158 goto err;
159 }
160 }
161 break;
162 case TOR_COMPRESS_OK:
163 if (compress || complete_only) {
164 log_fn(protocol_warn_level, LD_PROTOCOL,
165 "Unexpected %s while %scompressing",
166 complete_only?"end of input":"result",
167 compress?"":"de");
168 log_debug(LD_GENERAL, "method: %d level: %d at len: %lu",
169 method, compression_level, (unsigned long)in_len);
170 goto err;
171 } else {
172 if (in_len == 0) {
173 goto done;
174 }
175 }
176 break;
177 case TOR_COMPRESS_BUFFER_FULL: {
178 if (!compress && outptr < *out+out_alloc) {
179 // A buffer error in this case means that we have a problem
180 // with our input.
181 log_fn(protocol_warn_level, LD_PROTOCOL,
182 "Possible truncated or corrupt compressed data");
183 goto err;
184 }
185 if (out_alloc >= SIZE_T_CEILING / 2) {
186 log_warn(LD_GENERAL, "While %scompressing data: ran out of space.",
187 compress?"":"un");
188 goto err;
189 }
190 if (!compress &&
191 tor_compress_is_compression_bomb(in_len_orig, out_alloc)) {
192 // This should already have been caught down in the backend logic.
193 // LCOV_EXCL_START
195 goto err;
196 // LCOV_EXCL_STOP
197 }
198 const size_t offset = outptr - *out;
199 out_alloc *= 2;
200 *out = tor_realloc(*out, out_alloc);
201 outptr = *out + offset;
202 out_remaining = out_alloc - offset;
203 break;
204 }
205 case TOR_COMPRESS_ERROR:
206 log_fn(protocol_warn_level, LD_GENERAL,
207 "Error while %scompressing data: bad input?",
208 compress?"":"un");
209 goto err; // bad data.
210
211 // LCOV_EXCL_START
212 default:
214 goto err;
215 // LCOV_EXCL_STOP
216 }
217 }
218 done:
219 *out_len = outptr - *out;
220 if (compress && tor_compress_is_compression_bomb(*out_len, in_len_orig)) {
221 log_warn(LD_BUG, "We compressed something and got an insanely high "
222 "compression factor; other Tors would think this was a "
223 "compression bomb.");
224 goto err;
225 }
226 if (!compress) {
227 // NUL-terminate our output.
228 if (out_alloc == *out_len)
229 *out = tor_realloc(*out, out_alloc + 1);
230 (*out)[*out_len] = '\0';
231 }
232 rv = 0;
233 goto out;
234
235 err:
236 tor_free(*out);
237 *out_len = 0;
238 rv = -1;
239 goto out;
240
241 out:
242 tor_compress_free(stream);
243 return rv;
244}
245
246/** Given <b>in_len</b> bytes at <b>in</b>, compress them into a newly
247 * allocated buffer, using the method described in <b>method</b>. Store the
248 * compressed string in *<b>out</b>, and its length in *<b>out_len</b>.
249 * Return 0 on success, -1 on failure.
250 */
251int
252tor_compress(char **out, size_t *out_len,
253 const char *in, size_t in_len,
254 compress_method_t method)
255{
256 return tor_compress_impl(1, out, out_len, in, in_len, method,
257 BEST_COMPRESSION,
258 1, LOG_WARN);
259}
260
261/** Given zero or more compressed strings of total length <b>in_len</b> bytes
262 * at <b>in</b>, uncompress them into a newly allocated buffer, using the
263 * method described in <b>method</b>. Store the uncompressed string in
264 * *<b>out</b>, and its length in *<b>out_len</b>. Return 0 on success, -1 on
265 * failure.
266 *
267 * If any bytes are written to <b>out</b>, an extra byte NUL is always
268 * written at the end, but not counted in <b>out_len</b>. This is a
269 * safety feature to ensure that the output can be treated as a
270 * NUL-terminated string -- though of course, callers should check
271 * out_len anyway.
272 *
273 * If <b>complete_only</b> is true, we consider a truncated input as a
274 * failure; otherwise we decompress as much as we can. Warn about truncated
275 * or corrupt inputs at <b>protocol_warn_level</b>.
276 */
277int
278tor_uncompress(char **out, size_t *out_len,
279 const char *in, size_t in_len,
280 compress_method_t method,
281 int complete_only,
282 int protocol_warn_level)
283{
284 return tor_compress_impl(0, out, out_len, in, in_len, method,
285 BEST_COMPRESSION,
286 complete_only, protocol_warn_level);
287}
288
289/** Try to tell whether the <b>in_len</b>-byte string in <b>in</b> is likely
290 * to be compressed or not. If it is, return the likeliest compression method.
291 * Otherwise, return UNKNOWN_METHOD.
292 */
294detect_compression_method(const char *in, size_t in_len)
295{
296 if (in_len > 2 && fast_memeq(in, "\x1f\x8b", 2)) {
297 return GZIP_METHOD;
298 } else if (in_len > 2 && (in[0] & 0x0f) == 8 &&
299 (tor_ntohs(get_uint16(in)) % 31) == 0) {
300 return ZLIB_METHOD;
301 } else if (in_len > 2 &&
302 fast_memeq(in, "\x5d\x00\x00", 3)) {
303 return LZMA_METHOD;
304 } else if (in_len > 3 &&
305 fast_memeq(in, "\x28\xb5\x2f\xfd", 4)) {
306 return ZSTD_METHOD;
307 } else {
308 return UNKNOWN_METHOD;
309 }
310}
311
312/** Return 1 if a given <b>method</b> is supported; otherwise 0. */
313int
315{
316 switch (method) {
317 case GZIP_METHOD:
318 case ZLIB_METHOD:
320 case LZMA_METHOD:
322 case ZSTD_METHOD:
324 case NO_METHOD:
325 return 1;
326 case UNKNOWN_METHOD:
327 default:
328 return 0;
329 }
330}
331
332/**
333 * Return a bitmask of the supported compression types, where 1&lt;&lt;m is
334 * set in the bitmask if and only if compression with method <b>m</b> is
335 * supported.
336 */
337unsigned
339{
340 static unsigned supported = 0;
341 if (supported == 0) {
343 for (m = NO_METHOD; m <= UNKNOWN_METHOD; ++m) {
345 supported |= (1u << m);
346 }
347 }
348 }
349 return supported;
350}
351
352/** Table of compression method names. These should have an "x-" prefix,
353 * if they are not listed in the IANA content coding registry. */
354static const struct {
355 const char *name;
356 compress_method_t method;
358 { "gzip", GZIP_METHOD },
359 { "deflate", ZLIB_METHOD },
360 // We call this "x-tor-lzma" rather than "x-lzma", because we impose a
361 // lower maximum memory usage on the decoding side.
362 { "x-tor-lzma", LZMA_METHOD },
363 { "x-zstd" , ZSTD_METHOD },
364 { "identity", NO_METHOD },
365
366 /* Later entries in this table are not canonical; these are recognized but
367 * not emitted. */
368 { "x-gzip", GZIP_METHOD },
370
371/** Return the canonical string representation of the compression method
372 * <b>method</b>, or NULL if the method isn't recognized. */
373const char *
375{
376 unsigned i;
377 for (i = 0; i < ARRAY_LENGTH(compression_method_names); ++i) {
378 if (method == compression_method_names[i].method)
379 return compression_method_names[i].name;
380 }
381 return NULL;
382}
383
384/** Table of compression human readable method names. */
385static const struct {
386 compress_method_t method;
387 const char *name;
389 { NO_METHOD, "uncompressed" },
390 { GZIP_METHOD, "gzipped" },
391 { ZLIB_METHOD, "deflated" },
392 { LZMA_METHOD, "LZMA compressed" },
393 { ZSTD_METHOD, "Zstandard compressed" },
394 { UNKNOWN_METHOD, "unknown encoding" },
396
397/** Return a human readable string representation of the compression method
398 * <b>method</b>, or NULL if the method isn't recognized. */
399const char *
401{
402 unsigned i;
403 for (i = 0; i < ARRAY_LENGTH(compression_method_human_names); ++i) {
404 if (method == compression_method_human_names[i].method)
405 return compression_method_human_names[i].name;
406 }
407 return NULL;
408}
409
410/** Return the compression method represented by the string <b>name</b>, or
411 * UNKNOWN_METHOD if the string isn't recognized. */
414{
415 unsigned i;
416 for (i = 0; i < ARRAY_LENGTH(compression_method_names); ++i) {
417 if (!strcmp(compression_method_names[i].name, name))
418 return compression_method_names[i].method;
419 }
420 return UNKNOWN_METHOD;
421}
422
423/** Return a string representation of the version of the library providing the
424 * compression method given in <b>method</b>. Returns NULL if <b>method</b> is
425 * unknown or unsupported. */
426const char *
428{
429 switch (method) {
430 case GZIP_METHOD:
431 case ZLIB_METHOD:
433 case LZMA_METHOD:
435 case ZSTD_METHOD:
437 case NO_METHOD:
438 case UNKNOWN_METHOD:
439 default:
440 return NULL;
441 }
442}
443
444/** Return a string representation of the version of the library, found at
445 * compile time, providing the compression method given in <b>method</b>.
446 * Returns NULL if <b>method</b> is unknown or unsupported. */
447const char *
449{
450 switch (method) {
451 case GZIP_METHOD:
452 case ZLIB_METHOD:
454 case LZMA_METHOD:
456 case ZSTD_METHOD:
458 case NO_METHOD:
459 case UNKNOWN_METHOD:
460 default:
461 return NULL;
462 }
463}
464
465/** Return the approximate number of bytes allocated for all
466 * supported compression schemas. */
467size_t
475
476/** Internal state for an incremental compression/decompression. The body of
477 * this struct is not exposed. */
479 compress_method_t method; /**< The compression method. */
480
481 union {
482 tor_zlib_compress_state_t *zlib_state;
483 tor_lzma_compress_state_t *lzma_state;
484 tor_zstd_compress_state_t *zstd_state;
485 } u; /**< Compression backend state. */
486};
487
488/** Construct and return a tor_compress_state_t object using <b>method</b>. If
489 * <b>compress</b>, it's for compression; otherwise it's for decompression. */
492 compression_level_t compression_level)
493{
495
496 state = tor_malloc_zero(sizeof(tor_compress_state_t));
497 state->method = method;
498
499 switch (method) {
500 case GZIP_METHOD:
501 case ZLIB_METHOD: {
502 tor_zlib_compress_state_t *zlib_state =
503 tor_zlib_compress_new(compress, method, compression_level);
504
505 if (zlib_state == NULL)
506 goto err;
507
508 state->u.zlib_state = zlib_state;
509 break;
510 }
511 case LZMA_METHOD: {
512 tor_lzma_compress_state_t *lzma_state =
513 tor_lzma_compress_new(compress, method, compression_level);
514
515 if (lzma_state == NULL)
516 goto err;
517
518 state->u.lzma_state = lzma_state;
519 break;
520 }
521 case ZSTD_METHOD: {
522 tor_zstd_compress_state_t *zstd_state =
523 tor_zstd_compress_new(compress, method, compression_level);
524
525 if (zstd_state == NULL)
526 goto err;
527
528 state->u.zstd_state = zstd_state;
529 break;
530 }
531 case NO_METHOD: {
532 break;
533 }
534 case UNKNOWN_METHOD:
535 goto err;
536 }
537
539 sizeof(tor_compress_state_t));
540 return state;
541
542 err:
543 tor_free(state);
544 return NULL;
545}
546
547/** Compress/decompress some bytes using <b>state</b>. Read up to
548 * *<b>in_len</b> bytes from *<b>in</b>, and write up to *<b>out_len</b> bytes
549 * to *<b>out</b>, adjusting the values as we go. If <b>finish</b> is true,
550 * we've reached the end of the input.
551 *
552 * Return TOR_COMPRESS_DONE if we've finished the entire
553 * compression/decompression.
554 * Return TOR_COMPRESS_OK if we're processed everything from the input.
555 * Return TOR_COMPRESS_BUFFER_FULL if we're out of space on <b>out</b>.
556 * Return TOR_COMPRESS_ERROR if the stream is corrupt.
557 */
560 char **out, size_t *out_len,
561 const char **in, size_t *in_len,
562 int finish)
563{
564 tor_assert(state != NULL);
565 const size_t in_len_orig = *in_len;
566 const size_t out_len_orig = *out_len;
568
569 if (*out_len == 0 && (*in_len > 0 || finish)) {
570 // If we still have input data, but no space for output data, we might as
571 // well return early and let the caller do the reallocation of the out
572 // variable.
573 return TOR_COMPRESS_BUFFER_FULL;
574 }
575
576 switch (state->method) {
577 case GZIP_METHOD:
578 case ZLIB_METHOD:
579 rv = tor_zlib_compress_process(state->u.zlib_state,
580 out, out_len, in, in_len,
581 finish);
582 break;
583 case LZMA_METHOD:
584 rv = tor_lzma_compress_process(state->u.lzma_state,
585 out, out_len, in, in_len,
586 finish);
587 break;
588 case ZSTD_METHOD:
589 rv = tor_zstd_compress_process(state->u.zstd_state,
590 out, out_len, in, in_len,
591 finish);
592 break;
593 case NO_METHOD:
594 rv = tor_cnone_compress_process(out, out_len, in, in_len,
595 finish);
596 break;
597 default:
598 case UNKNOWN_METHOD:
599 goto err;
600 }
601 if (BUG((rv == TOR_COMPRESS_OK) &&
602 *in_len == in_len_orig &&
603 *out_len == out_len_orig)) {
604 log_warn(LD_GENERAL,
605 "More info on the bug: method == %s, finish == %d, "
606 " *in_len == in_len_orig == %lu, "
607 "*out_len == out_len_orig == %lu",
609 (unsigned long)in_len_orig, (unsigned long)out_len_orig);
610 return TOR_COMPRESS_ERROR;
611 }
612
613 return rv;
614 err:
615 return TOR_COMPRESS_ERROR;
616}
617
618/** Deallocate <b>state</b>. */
619void
621{
622 if (state == NULL)
623 return;
624
625 switch (state->method) {
626 case GZIP_METHOD:
627 case ZLIB_METHOD:
628 tor_zlib_compress_free(state->u.zlib_state);
629 break;
630 case LZMA_METHOD:
631 tor_lzma_compress_free(state->u.lzma_state);
632 break;
633 case ZSTD_METHOD:
634 tor_zstd_compress_free(state->u.zstd_state);
635 break;
636 case NO_METHOD:
637 break;
638 case UNKNOWN_METHOD:
639 break;
640 }
641
643 sizeof(tor_compress_state_t));
644 tor_free(state);
645}
646
647/** Return the approximate number of bytes allocated for <b>state</b>. */
648size_t
650{
651 tor_assert(state != NULL);
652
653 size_t size = sizeof(tor_compress_state_t);
654
655 switch (state->method) {
656 case GZIP_METHOD:
657 case ZLIB_METHOD:
658 size += tor_zlib_compress_state_size(state->u.zlib_state);
659 break;
660 case LZMA_METHOD:
661 size += tor_lzma_compress_state_size(state->u.lzma_state);
662 break;
663 case ZSTD_METHOD:
664 size += tor_zstd_compress_state_size(state->u.zstd_state);
665 break;
666 case NO_METHOD:
667 case UNKNOWN_METHOD:
668 break;
669 }
670
671 return size;
672}
673
674/** Initialize all compression modules. */
675int
677{
679
683
684 return 0;
685}
686
687/** Warn if we had any problems while setting up our compression libraries.
688 *
689 * (This isn't part of tor_compress_init, since the logs aren't set up yet.)
690 */
691void
693{
694 // XXXX can we move this into tor_compress_init() after all? log.c queues
695 // XXXX log messages at startup.
697}
698
699static int
700subsys_compress_initialize(void)
701{
702 return tor_compress_init();
703}
704
705const subsys_fns_t sys_compress = {
706 .name = "compress",
708 .supported = true,
709 .level = -55,
710 .initialize = subsys_compress_initialize,
711};
Inline functions for reading and writing multibyte values from the middle of strings,...
static uint16_t get_uint16(const void *cp)
Definition bytes.h:42
static uint16_t tor_ntohs(uint16_t a)
Definition bytes.h:154
Macro definitions for MIN, MAX, and CLAMP.
#define ARRAY_LENGTH(x)
void atomic_counter_init(atomic_counter_t *counter)
void atomic_counter_sub(atomic_counter_t *counter, size_t sub)
void atomic_counter_add(atomic_counter_t *counter, size_t add)
size_t atomic_counter_get(atomic_counter_t *counter)
const char * tor_compress_version_str(compress_method_t method)
Definition compress.c:427
int tor_compress_init(void)
Definition compress.c:676
static const struct @29 compression_method_human_names[]
tor_compress_output_t tor_compress_process(tor_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
Definition compress.c:559
int tor_compress_supports_method(compress_method_t method)
Definition compress.c:314
static size_t guess_compress_size(int compress, compress_method_t method, compression_level_t compression_level, size_t in_len)
Definition compress.c:85
compress_method_t compression_method_get_by_name(const char *name)
Definition compress.c:413
int tor_compress_is_compression_bomb(size_t size_in, size_t size_out)
Definition compress.c:64
const char * tor_compress_header_version_str(compress_method_t method)
Definition compress.c:448
static atomic_counter_t total_compress_allocation
Definition compress.c:41
void tor_compress_free_(tor_compress_state_t *state)
Definition compress.c:620
unsigned tor_compress_get_supported_method_bitmask(void)
Definition compress.c:338
size_t tor_compress_state_size(const tor_compress_state_t *state)
Definition compress.c:649
static int tor_compress_impl(int compress, char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method, compression_level_t compression_level, int complete_only, int protocol_warn_level)
Definition compress.c:111
void tor_compress_log_init_warnings(void)
Definition compress.c:692
int tor_compress(char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method)
Definition compress.c:252
compress_method_t detect_compression_method(const char *in, size_t in_len)
Definition compress.c:294
tor_compress_state_t * tor_compress_new(int compress, compress_method_t method, compression_level_t compression_level)
Definition compress.c:491
int tor_uncompress(char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method, int complete_only, int protocol_warn_level)
Definition compress.c:278
const char * compression_method_get_name(compress_method_t method)
Definition compress.c:374
size_t tor_compress_get_total_allocation(void)
Definition compress.c:468
static const struct @28 compression_method_names[]
const char * compression_method_get_human_name(compress_method_t method)
Definition compress.c:400
Headers for compress.c.
tor_compress_output_t
Definition compress.h:68
compress_method_t
Definition compress.h:21
compression_level_t
Definition compress.h:35
tor_lzma_compress_state_t * tor_lzma_compress_new(int compress, compress_method_t method, compression_level_t level)
const char * tor_lzma_get_version_str(void)
int tor_lzma_method_supported(void)
const char * tor_lzma_get_header_version_str(void)
tor_compress_output_t tor_lzma_compress_process(tor_lzma_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
void tor_lzma_init(void)
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state)
size_t tor_lzma_get_total_allocation(void)
Header for compress_lzma.c.
tor_compress_output_t tor_cnone_compress_process(char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
Header for compress_none.c.
Declare subsystem object for the compress module.
const char * tor_zlib_get_header_version_str(void)
void tor_zlib_init(void)
const char * tor_zlib_get_version_str(void)
int tor_zlib_method_supported(void)
tor_zlib_compress_state_t * tor_zlib_compress_new(int compress_, compress_method_t method, compression_level_t compression_level)
size_t tor_zlib_get_total_allocation(void)
size_t tor_zlib_compress_state_size(const tor_zlib_compress_state_t *state)
tor_compress_output_t tor_zlib_compress_process(tor_zlib_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
Header for compress_zlib.c.
const char * tor_zstd_get_header_version_str(void)
int tor_zstd_method_supported(void)
const char * tor_zstd_get_version_str(void)
tor_zstd_compress_state_t * tor_zstd_compress_new(int compress, compress_method_t method, compression_level_t level)
void tor_zstd_init(void)
tor_compress_output_t tor_zstd_compress_process(tor_zstd_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
size_t tor_zstd_get_total_allocation(void)
size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state)
void tor_zstd_warn_if_version_mismatched(void)
Header for compress_zstd.c.
const char * name
Definition config.c:2472
Headers for di_ops.c.
#define fast_memeq(a, b, c)
Definition di_ops.h:35
Headers for log.c.
#define log_fn(severity, domain, args,...)
Definition log.h:283
#define LD_PROTOCOL
Definition log.h:72
#define LD_BUG
Definition log.h:86
#define LD_GENERAL
Definition log.h:62
#define LOG_WARN
Definition log.h:53
Headers for util_malloc.c.
#define tor_free(p)
Definition malloc.h:56
const char * name
Definition subsys.h:43
compress_method_t method
Definition compress.c:479
union tor_compress_state_t::@30 u
Types used to declare a subsystem.
#define SUBSYS_DECLARE_LOCATION()
Definition subsys.h:211
#define MOCK_IMPL(rv, funcname, arglist)
Header for threads.c.
Integer definitions used throughout Tor.
#define SIZE_T_CEILING
Definition torint.h:126
Macros to manage assertions, fatal and non-fatal.
#define tor_assert_nonfatal_unreached()
Definition util_bug.h:177
#define tor_assert(expr)
Definition util_bug.h:103