summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-06-27 18:28:34 -0400
committerNick Mathewson <nickm@torproject.org>2017-06-27 18:28:34 -0400
commit2cd49d9ea6f8bad20215ad17d5057a8eea8e39e8 (patch)
tree0ceadb7aece3f75e1f52f367216b0955a5d4f1f0
parent32eba3d6aa7bd39048d32a566d119c013e526759 (diff)
parent09ae4fc583daa8f1a4783a983ae0f5e3d743c2b2 (diff)
downloadtor-2cd49d9ea6f8bad20215ad17d5057a8eea8e39e8.tar.gz
tor-2cd49d9ea6f8bad20215ad17d5057a8eea8e39e8.zip
Merge branch 'ahf_bugs_22702_squashed' into maint-0.3.1
-rw-r--r--changes/bug227025
-rw-r--r--src/or/consdiffmgr.c18
-rw-r--r--src/or/consdiffmgr.h3
-rw-r--r--src/or/directory.c31
-rw-r--r--src/or/dirserv.c6
5 files changed, 63 insertions, 0 deletions
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.
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 <b>ent</b> into
+ * *<b>out</b> 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/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;
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) {