Browse Source

Merge branch 'ahf_bugs_22702_squashed' into maint-0.3.1

Nick Mathewson 6 years ago
parent
commit
2cd49d9ea6
5 changed files with 63 additions and 0 deletions
  1. 5 0
      changes/bug22702
  2. 18 0
      src/or/consdiffmgr.c
  3. 3 0
      src/or/consdiffmgr.h
  4. 31 0
      src/or/directory.c
  5. 6 0
      src/or/dirserv.c

+ 5 - 0
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.

+ 18 - 0
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;
+}
+

+ 3 - 0
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);

+ 31 - 0
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;

+ 6 - 0
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) {