From 07f2940b4519d801eb10b9f5e49790aced1f6322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Fri, 23 Jun 2017 23:55:54 +0000 Subject: [PATCH 1/3] Set published_out for consensus cache entries in spooled_resource_estimate_size(). This patch ensures that the published_out output parameter is set to the current consensus cache entry's "valid after" field. See: https://bugs.torproject.org/22702 --- src/or/consdiffmgr.c | 18 ++++++++++++++++++ src/or/consdiffmgr.h | 3 +++ src/or/dirserv.c | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c index 2af104733b..4036f665f9 100644 --- a/src/or/consdiffmgr.c +++ b/src/or/consdiffmgr.c @@ -1840,3 +1840,21 @@ consensus_cache_entry_get_valid_until(const consensus_cache_entry_t *ent, return 0; } +/** Read the valid after timestamp from the cached object ent into + * *out and return 0, or return -1 if no such time was recorded. */ +int +consensus_cache_entry_get_valid_after(const consensus_cache_entry_t *ent, + time_t *out) +{ + tor_assert(ent); + tor_assert(out); + + const char *s; + s = consensus_cache_entry_get_value(ent, LABEL_VALID_AFTER); + + if (s == NULL || parse_iso_time_nospace(s, out) < 0) + return -1; + else + return 0; +} + diff --git a/src/or/consdiffmgr.h b/src/or/consdiffmgr.h index fe4f9ee239..079f9fe2d2 100644 --- a/src/or/consdiffmgr.h +++ b/src/or/consdiffmgr.h @@ -44,6 +44,9 @@ int consensus_cache_entry_get_fresh_until( int consensus_cache_entry_get_valid_until( const struct consensus_cache_entry_t *ent, time_t *out); +int consensus_cache_entry_get_valid_after( + const struct consensus_cache_entry_t *ent, + time_t *out); void consdiffmgr_rescan(void); int consdiffmgr_cleanup(void); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 408f58b22b..4954471c6a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -14,6 +14,7 @@ #include "connection.h" #include "connection_or.h" #include "conscache.h" +#include "consdiffmgr.h" #include "control.h" #include "directory.h" #include "dirserv.h" @@ -3518,6 +3519,11 @@ spooled_resource_estimate_size(const spooled_resource_t *spooled, } else { cached_dir_t *cached; if (spooled->consensus_cache_entry) { + if (published_out) { + consensus_cache_entry_get_valid_after( + spooled->consensus_cache_entry, published_out); + } + return spooled->cce_len; } if (spooled->cached_dir_ref) { From 0a4af86335f1f72982bbc7e57578f07630986999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 27 Jun 2017 17:16:44 +0000 Subject: [PATCH 2/3] 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 --- src/or/directory.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) 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 digests matches the latest consensus + * flavor (given in flavor) 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; From 09ae4fc583daa8f1a4783a983ae0f5e3d743c2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 27 Jun 2017 22:21:43 +0000 Subject: [PATCH 3/3] Add changes file for bug #22702. See: https://bugs.torproject.org/22702 --- changes/bug22702 | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changes/bug22702 diff --git a/changes/bug22702 b/changes/bug22702 new file mode 100644 index 0000000000..a2044c70bf --- /dev/null +++ b/changes/bug22702 @@ -0,0 +1,5 @@ + o Major bugfixes (directory protocol): + - Ensure that we sent "304 Not modified" as HTTP status code when a + client is attempting to fetch a consensus or consensus diff that + matches the latest consensus we have available. Fixes bug 22702; + bugfix on 0.3.1.1-alpha.