diff --git a/src/common/compress.c b/src/common/compress.c index 2e7412fd0d..42a5097a58 100644 --- a/src/common/compress.c +++ b/src/common/compress.c @@ -277,6 +277,26 @@ tor_compress_supports_method(compress_method_t method) } } +/** + * Return a bitmask of the supported compression types, where 1<<m is + * set in the bitmask if and only if compression with method m is + * supported. + */ +unsigned +tor_compress_get_supported_method_bitmask(void) +{ + static unsigned supported = 0; + if (supported == 0) { + compress_method_t m; + for (m = NO_METHOD; m <= UNKNOWN_METHOD; ++m) { + if (tor_compress_supports_method(m)) { + supported |= (1u << m); + } + } + } + return supported; +} + /** Table of compression method names. These should have an "x-" prefix, * if they are not listed in the IANA content coding registry. */ static const struct { diff --git a/src/common/compress.h b/src/common/compress.h index 95b70c02ec..5b47c5d458 100644 --- a/src/common/compress.h +++ b/src/common/compress.h @@ -16,12 +16,12 @@ * functions here. Call tor_compress_supports_method() to check if a given * compression schema is supported by Tor. */ typedef enum { - NO_METHOD=0, + NO_METHOD=0, // This method must be first. GZIP_METHOD=1, ZLIB_METHOD=2, LZMA_METHOD=3, ZSTD_METHOD=4, - UNKNOWN_METHOD=5 + UNKNOWN_METHOD=5, // This method must be last. Add new ones in the middle. } compress_method_t; /** @@ -48,6 +48,7 @@ compress_method_t detect_compression_method(const char *in, size_t in_len); int tor_compress_is_compression_bomb(size_t size_in, size_t size_out); int tor_compress_supports_method(compress_method_t method); +unsigned tor_compress_get_supported_method_bitmask(void); const char * compression_method_get_name(compress_method_t method); compress_method_t compression_method_get_by_name(const char *name); diff --git a/src/or/directory.c b/src/or/directory.c index ea3410d8c6..3b3f7ea3a9 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2814,20 +2814,6 @@ parse_accept_encoding_header(const char *h) return result; } -/** Bitmask of supported compression types, to use in a bitwise "and" - * with the results of parse_accept_encoding_header */ -static const unsigned SUPPORTED_COMPRESSION_MASK = - (1u << NO_METHOD) - | (1u << ZLIB_METHOD) - | (1u << GZIP_METHOD) -#ifdef HAVE_ZSTD - | (1u << ZSTD_METHOD) -#endif -#ifdef HAVE_LZMA - | (1u << LZMA_METHOD) -#endif - ; - /** Decide whether a client would accept the consensus we have. * * Clients can say they only want a consensus if it's signed by more @@ -3028,7 +3014,7 @@ directory_handle_command_get,(dir_connection_t *conn, const char *headers, } /* Remove all methods that we don't both support. */ - compression_methods_supported &= SUPPORTED_COMPRESSION_MASK; + compression_methods_supported &= tor_compress_get_supported_method_bitmask(); get_handler_args_t args; args.url = url;