[tor-commits] [tor/master] Implement functions to expose valid/fresh-until and voters

nickm at torproject.org nickm at torproject.org
Mon May 15 21:26:28 UTC 2017


commit dcc533fb133646d81c2fa6632d6fb7f05f99f650
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sun May 14 19:43:41 2017 -0400

    Implement functions to expose valid/fresh-until and voters
    
    These still won't do anything till I get the values to be filled in.
    
    Also, I changed the API a little (with corresponding changes in
    directory.c) to match things that it's easier to store.
---
 src/or/consdiffmgr.c   | 80 +++++++++++++++++++++++++++-----------------------
 src/or/consdiffmgr.h   | 13 ++++----
 src/or/directory.c     | 54 +++++++++++++++-------------------
 src/or/networkstatus.c | 18 ++++++++----
 src/or/networkstatus.h |  4 ++-
 5 files changed, 88 insertions(+), 81 deletions(-)

diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c
index c208865..d117acd 100644
--- a/src/or/consdiffmgr.c
+++ b/src/or/consdiffmgr.c
@@ -32,6 +32,15 @@
 /* The valid-after time for a consensus (or for the target consensus of a
  * diff), encoded as ISO UTC. */
 #define LABEL_VALID_AFTER "consensus-valid-after"
+/* The fresh-until time for a consensus (or for the target consensus of a
+ * diff), encoded as ISO UTC. */
+#define LABEL_FRESH_UNTIL "consensus-fresh-until"
+/* The valid-until time for a consensus (or for the target consensus of a
+ * diff), encoded as ISO UTC. */
+#define LABEL_VALID_UNTIL "consensus-valid-until"
+/* Comma-separated list of hex-encoded identity digests for the voting
+ * authorities. */
+#define LABEL_SIGNATORIES "consensus-signatories"
 /* A hex encoded SHA3 digest of the object, as compressed (if any) */
 #define LABEL_SHA3_DIGEST "sha3-digest"
 /* A hex encoded SHA3 digest of the object before compression. */
@@ -1729,54 +1738,53 @@ consdiffmgr_enable_background_compression(void)
   background_compression = 1;
 }
 
-/** Read the lifetime of cached object <b>ent</b> into <b>lifetime</b>. */
+/** Read the set of voters from the cached object <b>ent</b> into
+ * <b>out</b>, as a list of hex-encoded digests. Return 0 on success,
+ * -1 if no signatories were recorded. */
 int
-consensus_cache_entry_get_lifetime(const consensus_cache_entry_t *ent,
-                                   long *lifetime)
+consensus_cache_entry_get_voter_id_digests(const consensus_cache_entry_t *ent,
+                                           smartlist_t *out)
 {
-  tor_assert(lifetime);
-
-  // FIXME(ahf): Fill out.
-  *lifetime = 0;
-
+  tor_assert(ent);
+  tor_assert(out);
+  const char *s;
+  s = consensus_cache_entry_get_value(ent, LABEL_SIGNATORIES);
+  if (s == NULL)
+    return -1;
+  smartlist_split_string(out, s, ",", SPLIT_SKIP_SPACE|SPLIT_STRIP_SPACE, 0);
   return 0;
 }
 
-/** Return non-zero if the cache object found in <b>ent</b> is
- * reasonably live, otherwise return 0.   Use <b>now</b> to pass the
- * timestamp used for comparison. */
-int
-consensus_cache_entry_is_reasonably_live(const consensus_cache_entry_t *ent,
-                                         time_t now)
-{
-  // FIXME(ahf): Fill out.
-  (void)now;
-
-  return 1;
-}
-
-/** Read the set of voters from the cached object <b>ent</b> into <b>out</b>. */
+/** Read the fresh-until time of 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_voters(const consensus_cache_entry_t *ent,
-                                     smartlist_t *out)
+consensus_cache_entry_get_fresh_until(const consensus_cache_entry_t *ent,
+                                      time_t *out)
 {
-  // FIXME(ahf): Fill out.
-  (void)out;
-
-  return 0;
+  tor_assert(ent);
+  tor_assert(out);
+  const char *s;
+  s = consensus_cache_entry_get_value(ent, LABEL_FRESH_UNTIL);
+  if (s == NULL || parse_iso_time_nospace(s, out) < 0)
+    return -1;
+  else
+    return 0;
 }
 
-/** Read the valid until timestamp from the cached object <b>ent</b>
- * into <b>out</b>. */
+/** Read the valid until 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_valid_until(const consensus_cache_entry_t *ent,
-                                  time_t *out)
+consensus_cache_entry_get_valid_until(const consensus_cache_entry_t *ent,
+                                      time_t *out)
 {
+  tor_assert(ent);
   tor_assert(out);
 
-  // FIXME(ahf): Fill out.
-  *out = time(NULL);
-
-  return 0;
+  const char *s;
+  s = consensus_cache_entry_get_value(ent, LABEL_VALID_UNTIL);
+  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 a8111dd..0325a00 100644
--- a/src/or/consdiffmgr.h
+++ b/src/or/consdiffmgr.h
@@ -36,16 +36,13 @@ consdiff_status_t consdiffmgr_find_diff_from(
                            size_t digestlen,
                            compress_method_t method);
 
-int consensus_cache_entry_get_lifetime(
-                                  const struct consensus_cache_entry_t *ent,
-                                  long *lifetime);
-int consensus_cache_entry_is_reasonably_live(
-                                  const struct consensus_cache_entry_t *ent,
-                                  time_t now);
-int consensus_cache_entry_get_voters(
+int consensus_cache_entry_get_voter_id_digests(
                                   const struct consensus_cache_entry_t *ent,
                                   smartlist_t *out);
-int consensus_cache_entry_valid_until(
+int consensus_cache_entry_get_fresh_until(
+                                  const struct consensus_cache_entry_t *ent,
+                                  time_t *out);
+int consensus_cache_entry_get_valid_until(
                                   const struct consensus_cache_entry_t *ent,
                                   time_t *out);
 
diff --git a/src/or/directory.c b/src/or/directory.c
index 946792b..4fa4b3c 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -3382,47 +3382,35 @@ int
 client_likes_consensus(const struct consensus_cache_entry_t *ent,
                        const char *want_url)
 {
-  smartlist_t *want_authorities = smartlist_new();
   smartlist_t *voters = smartlist_new();
   int need_at_least;
   int have = 0;
 
+  if (consensus_cache_entry_get_voter_id_digests(ent, voters) != 0) {
+    return 1; // We don't know the voters; assume the client won't mind. */
+  }
+
+  smartlist_t *want_authorities = smartlist_new();
   dir_split_resource_into_fingerprints(want_url, want_authorities, NULL, 0);
   need_at_least = smartlist_len(want_authorities)/2+1;
 
-  if (consensus_cache_entry_get_voters(ent, voters) != 0)
-    goto done;
-
-  SMARTLIST_FOREACH_BEGIN(want_authorities, const char *, d) {
-    char want_digest[DIGEST_LEN];
-    size_t want_len = strlen(d)/2;
-    if (want_len > DIGEST_LEN)
-      want_len = DIGEST_LEN;
+  SMARTLIST_FOREACH_BEGIN(want_authorities, const char *, want_digest) {
 
-    if (base16_decode(want_digest, DIGEST_LEN, d, want_len*2)
-                      != (int) want_len) {
-      log_fn(LOG_PROTOCOL_WARN, LD_DIR,
-             "Failed to decode requested authority digest %s.", escaped(d));
-      continue;
-    };
-
-    SMARTLIST_FOREACH_BEGIN(voters, networkstatus_voter_info_t *, vi) {
-      if (smartlist_len(vi->sigs) &&
-          tor_memeq(vi->identity_digest, want_digest, want_len)) {
+    SMARTLIST_FOREACH_BEGIN(voters, const char *, digest) {
+      if (!strcasecmpstart(digest, want_digest)) {
         have++;
         break;
       };
-    } SMARTLIST_FOREACH_END(vi);
+    } SMARTLIST_FOREACH_END(digest);
 
     /* early exit, if we already have enough */
     if (have >= need_at_least)
       break;
-  } SMARTLIST_FOREACH_END(d);
+  } SMARTLIST_FOREACH_END(want_digest);
 
- done:
   SMARTLIST_FOREACH(want_authorities, char *, d, tor_free(d));
   smartlist_free(want_authorities);
-  SMARTLIST_FOREACH(voters, networkstatus_voter_info_t *, v, tor_free(v));
+  SMARTLIST_FOREACH(voters, char *, cp, tor_free(cp));
   smartlist_free(voters);
   return (have >= need_at_least);
 }
@@ -3644,7 +3632,7 @@ warn_consensus_is_too_old(const struct consensus_cache_entry_t *cached_consensus
   time_t valid_until;
   char *dupes;
 
-  if (consensus_cache_entry_valid_until(cached_consensus, &valid_until))
+  if (consensus_cache_entry_get_valid_until(cached_consensus, &valid_until))
     return;
 
   if ((dupes = rate_limit_log(&warned, now))) {
@@ -3832,9 +3820,17 @@ handle_get_current_consensus(dir_connection_t *conn,
                                            args->compression_supported,
                                            &compression_used);
   }
+  time_t fresh_until, valid_until;
+  int have_fresh_until = 0, have_valid_until = 0;
+  if (cached_consensus) {
+    have_fresh_until =
+      !consensus_cache_entry_get_fresh_until(cached_consensus, &fresh_until);
+    have_valid_until =
+      !consensus_cache_entry_get_valid_until(cached_consensus, &valid_until);
+  }
 
-  if (cached_consensus &&
-      !consensus_cache_entry_is_reasonably_live(cached_consensus, now)) {
+  if (cached_consensus && have_valid_until &&
+      !networkstatus_valid_until_is_reasonably_live(valid_until, now)) {
     write_http_status_line(conn, 404, "Consensus is too old");
     warn_consensus_is_too_old(cached_consensus, flavor, now);
     geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
@@ -3870,11 +3866,7 @@ handle_get_current_consensus(dir_connection_t *conn,
     smartlist_add(conn->spool, spooled);
   }
 
-  if (cached_consensus &&
-      consensus_cache_entry_get_lifetime(cached_consensus,
-                                         &lifetime) != 0) {
-    lifetime = 0;
-  }
+  lifetime = (have_fresh_until && fresh_until > now) ? fresh_until - now : 0;
 
   if (!smartlist_len(conn->spool)) { /* we failed to create/cache cp */
     write_http_status_line(conn, 503, "Network status object unavailable");
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index bd106fd..fffd107 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1407,16 +1407,24 @@ networkstatus_get_live_consensus,(time_t now))
  * Return 1 if the consensus is reasonably live, or 0 if it is too old.
  */
 int
-networkstatus_consensus_reasonably_live(networkstatus_t *consensus, time_t now)
+networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
+                                        time_t now)
 {
-#define REASONABLY_LIVE_TIME (24*60*60)
   if (BUG(!consensus))
     return 0;
 
-  if (now <= consensus->valid_until + REASONABLY_LIVE_TIME)
-    return 1;
+  return networkstatus_valid_until_is_reasonably_live(consensus->valid_until,
+                                                      now);
+}
 
-  return 0;
+/** As networkstatus_consensus_reasonably_live, but takes a valid_until
+ * time rather than an entire consensus. */
+int
+networkstatus_valid_until_is_reasonably_live(time_t valid_until,
+                                             time_t now)
+{
+#define REASONABLY_LIVE_TIME (24*60*60)
+  return (now <= valid_until + REASONABLY_LIVE_TIME);
 }
 
 /* XXXX remove this in favor of get_live_consensus. But actually,
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index 37a5a3b..e774c4d 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -81,8 +81,10 @@ MOCK_DECL(networkstatus_t *,networkstatus_get_latest_consensus,(void));
 MOCK_DECL(networkstatus_t *,networkstatus_get_latest_consensus_by_flavor,
           (consensus_flavor_t f));
 MOCK_DECL(networkstatus_t *, networkstatus_get_live_consensus,(time_t now));
-int networkstatus_consensus_reasonably_live(networkstatus_t *consensus,
+int networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
                                             time_t now);
+int networkstatus_valid_until_is_reasonably_live(time_t valid_until,
+                                                 time_t now);
 networkstatus_t *networkstatus_get_reasonably_live_consensus(time_t now,
                                                              int flavor);
 MOCK_DECL(int, networkstatus_consensus_is_bootstrapping,(time_t now));





More information about the tor-commits mailing list