diff options
author | Alexander Færøy <ahf@0x90.dk> | 2017-06-27 17:16:44 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-06-27 18:25:48 -0400 |
commit | 0a4af86335f1f72982bbc7e57578f07630986999 (patch) | |
tree | f627c2f54d67e3022d6d5866aaca71eabe61a9ba /src/or | |
parent | 07f2940b4519d801eb10b9f5e49790aced1f6322 (diff) | |
download | tor-0a4af86335f1f72982bbc7e57578f07630986999.tar.gz tor-0a4af86335f1f72982bbc7e57578f07630986999.zip |
Return "304 not modified" if a client already have the most recent consensus.
This makes our directory code check if a client is trying to fetch a
document that matches a digest from our latest consensus document.
See: https://bugs.torproject.org/22702
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/directory.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index b680b134a4..6ce739b4f6 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3883,6 +3883,30 @@ find_best_compression_method(unsigned compression_methods, int stream) return NO_METHOD; } +/** Check if any of the digests in <b>digests</b> matches the latest consensus + * flavor (given in <b>flavor</b>) that we have available. */ +static int +digest_list_contains_best_consensus(consensus_flavor_t flavor, + const smartlist_t *digests) +{ + const networkstatus_t *ns = NULL; + + if (digests == NULL) + return 0; + + ns = networkstatus_get_latest_consensus_by_flavor(flavor); + + if (ns == NULL) + return 0; + + SMARTLIST_FOREACH_BEGIN(digests, const uint8_t *, digest) { + if (tor_memeq(ns->digest_sha3_as_signed, digest, DIGEST256_LEN)) + return 1; + } SMARTLIST_FOREACH_END(digest); + + return 0; +} + /** Check if the given compression method is allowed for a connection that is * supposed to be anonymous. Returns 1 if the compression method is allowed, * otherwise 0. */ @@ -4052,6 +4076,13 @@ handle_get_current_consensus(dir_connection_t *conn, goto done; } + if (digest_list_contains_best_consensus(req.flav, + req.diff_from_digests)) { + write_http_status_line(conn, 304, "Not modified"); + geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED); + goto done; + } + struct consensus_cache_entry_t *cached_consensus = NULL; compress_method_t compression_used = NO_METHOD; |