From d95e7c7d67134b9b964d49cf8c2bdbf805a615d8 Mon Sep 17 00:00:00 2001
From: Roger Dingledine <arma@torproject.org>
Date: Mon, 10 Dec 2007 16:40:14 +0000
Subject: [PATCH] also clear the hsdir status flag in routerinfo_t when the
 relay is no longer listed in the relevant networkstatus document.

svn:r12752
---
 ChangeLog              |  4 +++-
 src/or/config.c        |  2 +-
 src/or/dirserv.c       | 49 +++++++++++++++++++++++++++++-------------
 src/or/networkstatus.c |  8 ++-----
 src/or/or.h            |  1 +
 5 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index edcfb0a40a..963066b32f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -30,7 +30,9 @@ Changes in version 0.2.0.13-alpha - 2007-12-??
   o Minor bugfixes:
     - The fix in 0.2.0.12-alpha cleared the "hsdir" flag in v3 network
       consensus documents when there are too many relays at a single
-      IP address. Now clear it in v2 network status documents too.
+      IP address. Now clear it in v2 network status documents too, and
+      also clear it in routerinfo_t when the relay is no longer listed
+      in the relevant networkstatus document.
     - Don't crash if we get an unexpected value for the
       PublishServerDescriptor config option. Reported by Matt Edman;
       bugfix on 0.2.0.9-alpha.
diff --git a/src/or/config.c b/src/or/config.c
index f6f7b78b6b..9b358fc17e 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -2827,7 +2827,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
   if ((parse_authority_type_from_list(options->PublishServerDescriptor,
                                &options->_PublishServerDescriptor, 1) < 0)) {
     r = tor_snprintf(buf, sizeof(buf),
-        "Unrecognized value for PublishServerDescriptor");
+                     "Unrecognized value in PublishServerDescriptor");
     *msg = tor_strdup(r >= 0 ? buf : "internal error");
     return -1;
   }
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e0d4d05a10..2dc87d11a2 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2041,15 +2041,42 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
   rs->dir_port = ri->dir_port;
 }
 
+/** Routerstatus <b>rs</b> is part of a group of routers that are on
+ * too narrow an IP-space. Clear out its flags: we don't want people
+ * using it.
+ */
+static void
+clear_status_flags_on_sybil(routerstatus_t *rs)
+{
+  rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
+    rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
+    rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit = 0;
+  /* FFFF we might want some mechanism to check later on if we
+   * missed zeroing any flags: it's easy to add a new flag but
+   * forget to add it to this clause. */
+}
+
+/** Clear all the status flags in routerinfo <b>router</b>. We put this
+ * function here because it's eerily similar to
+ * clear_status_flags_on_sybil() above. One day we should merge them. */
+void
+router_clear_status_flags(routerinfo_t *router)
+{
+  router->is_valid = router->is_running = router->is_hs_dir =
+    router->is_fast = router->is_stable =
+    router->is_possible_guard = router->is_exit =
+    router->is_bad_exit = 0;
+}
+
 /** If we've been around for less than this amount of time, our reachability
  * information is not accurate. */
 #define DIRSERV_TIME_TO_GET_REACHABILITY_INFO (30*60)
 
 /** Return a new networkstatus_vote_t* containing our current opinion. (For v3
- * authorities */
+ * authorities) */
 networkstatus_vote_t *
 dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
-                                       authority_cert_t *cert)
+                                        authority_cert_t *cert)
 {
   or_options_t *options = get_options();
   networkstatus_vote_t *v3_out = NULL;
@@ -2132,14 +2159,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
                                        naming, exits_can_be_guards,
                                        listbadexits);
 
-      if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest)) {
-        rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
-          rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
-          rs->is_hs_dir = rs->is_possible_guard = 0;
-        /* FFFF we might want some mechanism to check later on if we
-         * missed zeroing any flags: it's easy to add a new flag but
-         * forget to add it to this clause. */
-      }
+      if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
+        clear_status_flags_on_sybil(rs);
+
       if (!vote_on_reachability)
         rs->is_running = 0;
 
@@ -2351,11 +2373,8 @@ generate_v2_networkstatus_opinion(void)
                                        naming, exits_can_be_guards,
                                        listbadexits);
 
-      if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest)) {
-        rs.is_authority = rs.is_exit = rs.is_stable = rs.is_fast =
-          rs.is_running = rs.is_named = rs.is_valid = rs.is_v2_dir =
-          rs.is_hs_dir = rs.is_possible_guard = 0;
-      }
+      if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
+        clear_status_flags_on_sybil(&rs);
 
       if (routerstatus_format_entry(outp, endp-outp, &rs, version, 0)) {
         log_warn(LD_BUG, "Unable to print router status.");
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 605c8d5f76..3b4f9d31b0 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1590,12 +1590,8 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
       if (!namingdir)
         router->is_named = 0;
       if (!authdir) {
-        if (router->purpose == ROUTER_PURPOSE_GENERAL) {
-          router->is_valid = router->is_running =
-            router->is_fast = router->is_stable =
-            router->is_possible_guard = router->is_exit =
-            router->is_bad_exit = 0;
-        }
+        if (router->purpose == ROUTER_PURPOSE_GENERAL)
+          router_clear_status_flags(router);
       }
       continue;
     }
diff --git a/src/or/or.h b/src/or/or.h
index d8c44e0027..6b29fd714d 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3133,6 +3133,7 @@ const char *dirvote_get_pending_detached_signatures(void);
 #define DGV_INCLUDE_PENDING 2
 #define DGV_INCLUDE_PREVIOUS 4
 const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
+void router_clear_status_flags(routerinfo_t *ri);
 networkstatus_vote_t *
 dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
                                         authority_cert_t *cert);
-- 
GitLab