summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@0x90.dk>2017-06-27 17:16:44 +0000
committerNick Mathewson <nickm@torproject.org>2017-06-27 18:25:48 -0400
commit0a4af86335f1f72982bbc7e57578f07630986999 (patch)
treef627c2f54d67e3022d6d5866aaca71eabe61a9ba
parent07f2940b4519d801eb10b9f5e49790aced1f6322 (diff)
downloadtor-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
-rw-r--r--src/or/directory.c31
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;