commit 008194035fa8ab3712dead9152622de8509e8cf3 Author: Alexander Færøy ahf@torproject.org Date: Mon May 15 15:13:28 2017 +0200
Handle non-compressed requests gracefully.
This patch makes us use FALLBACK_COMPRESS_METHOD to try to fetch an object from the consensus diff manager in case no mutually supported result was found. This object, if found, is then decompressed using the spooling system to the client.
See: https://bugs.torproject.org/21667 --- src/or/directory.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/src/or/directory.c b/src/or/directory.c index 6504e2e..cf6f0db 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3677,6 +3677,13 @@ parse_or_diff_from_header(smartlist_t **digests_out, const char *headers) return 0; }
+/** Fallback compression method. The fallback compression method is used in + * case a client requests a non-compressed document. We only store compressed + * documents, so we use this compression method to fetch the document and let + * the spooling system do the streaming decompression. + */ +#define FALLBACK_COMPRESS_METHOD ZLIB_METHOD + /** * Try to find the best consensus diff possible in order to serve a client * request for a diff from one of the consensuses in <b>digests</b> to the @@ -3706,6 +3713,16 @@ find_best_diff(const smartlist_t *digests, int flav, } } } SMARTLIST_FOREACH_END(diff_from); + + SMARTLIST_FOREACH_BEGIN(digests, const uint8_t *, diff_from) { + if (consdiffmgr_find_diff_from(&result, flav, DIGEST_SHA3_256, diff_from, + DIGEST256_LEN, FALLBACK_COMPRESS_METHOD) == CONSDIFF_AVAILABLE) { + tor_assert_nonfatal(result); + *compression_used_out = FALLBACK_COMPRESS_METHOD; + return result; + } + } SMARTLIST_FOREACH_END(diff_from); + return NULL; }
@@ -3735,6 +3752,13 @@ find_best_consensus(int flav, } }
+ if (consdiffmgr_find_consensus(&result, flav, + FALLBACK_COMPRESS_METHOD) == CONSDIFF_AVAILABLE) { + tor_assert_nonfatal(result); + *compression_used_out = FALLBACK_COMPRESS_METHOD; + return result; + } + return NULL; }
@@ -3911,12 +3935,15 @@ handle_get_current_consensus(dir_connection_t *conn, }
clear_spool = 0; + + // The compress_method might have been NO_METHOD, but we store the data + // compressed. Decompress them using `compression_used`. See fallback code in + // find_best_consensus() and find_best_diff(). write_http_response_header(conn, -1, - compression_used, + compress_method == NO_METHOD ? + NO_METHOD : compression_used, smartlist_len(conn->spool) == 1 ? lifetime : 0);
- // The compress_method requested was NO_METHOD, but we store the data - // compressed. Decompress them using `compression_used`. if (compress_method == NO_METHOD) conn->compress_state = tor_compress_new(0, compression_used, HIGH_COMPRESSION);