[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master] instrument entry_is_live to tell why our guard isn't live



Author: Roger Dingledine <arma@xxxxxxxxxxxxxx>
Date: Sat, 19 Sep 2009 22:59:14 -0400
Subject: instrument entry_is_live to tell why our guard isn't live
Commit: 7346804ec65c69fa464d37ccdeeb41736671e00e

---
 src/or/circuitbuild.c |   74 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 5198c13..3ef6e7e 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2106,6 +2106,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
       continue; /* skip routers that are known to be down or bad exits */
     }
     if (router_is_unreliable(router, need_uptime, need_capacity, 0)) {
+      /* XXX022 don't skip if it's in ExitNodes */
       n_supported[i] = -1;
       continue; /* skip routers that are not suitable */
     }
@@ -2840,35 +2841,52 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now)
  * - Listed as either up or never yet contacted;
  * - Present in the routerlist;
  * - Listed as 'stable' or 'fast' by the current dirserver consensus,
- *   if demanded by <b>need_uptime</b> or <b>need_capacity</b>;
- *   (This check is currently redundant with the Guard flag, but in
- *   the future that might change. Best to leave it in for now.)
+ *   if demanded by <b>need_uptime</b> or <b>need_capacity</b>
+ *   (unless it's a configured EntryNode);
  * - Allowed by our current ReachableORAddresses config option; and
- * - Currently thought to be reachable by us (unless assume_reachable
+ * - Currently thought to be reachable by us (unless <b>assume_reachable</b>
  *   is true).
+ *
+ * If the answer is no, set *<b>msg</b> to an explanation of why.
  */
 static INLINE routerinfo_t *
 entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
-              int assume_reachable)
+              int assume_reachable, const char **msg)
 {
   routerinfo_t *r;
-  if (e->bad_since)
+  tor_assert(msg);
+
+  if (e->bad_since) {
+    *msg = "bad";
     return NULL;
+  }
   /* no good if it's unreachable, unless assume_unreachable or can_retry. */
   if (!assume_reachable && !e->can_retry &&
-      e->unreachable_since && !entry_is_time_to_retry(e, time(NULL)))
+      e->unreachable_since && !entry_is_time_to_retry(e, time(NULL))) {
+    *msg = "unreachable";
     return NULL;
+  }
   r = router_get_by_digest(e->identity);
-  if (!r)
+  if (!r) {
+    *msg = "no descriptor";
     return NULL;
-  if (get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_BRIDGE)
+  }
+  if (get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_BRIDGE) {
+    *msg = "not a bridge";
     return NULL;
-  if (!get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_GENERAL)
+  }
+  if (!get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_GENERAL) {
+    *msg = "not general-purpose";
     return NULL;
-  if (router_is_unreliable(r, need_uptime, need_capacity, 0))
+  }
+  if (router_is_unreliable(r, need_uptime, need_capacity, 0)) {
+    *msg = "not fast/stable";
     return NULL;
-  if (!fascist_firewall_allows_or(r))
+  }
+  if (!fascist_firewall_allows_or(r)) {
+    *msg = "unreachable by config";
     return NULL;
+  }
   return r;
 }
 
@@ -2877,11 +2895,12 @@ static int
 num_live_entry_guards(void)
 {
   int n = 0;
+  const char *msg;
   if (! entry_guards)
     return 0;
   SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
     {
-      if (entry_is_live(entry, 0, 1, 0))
+      if (entry_is_live(entry, 0, 1, 0, &msg))
         ++n;
     });
   return n;
@@ -2910,10 +2929,15 @@ log_entry_guards(int severity)
 
   SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
     {
-      tor_snprintf(buf, sizeof(buf), "%s (%s%s)",
-                   e->nickname,
-                   entry_is_live(e, 0, 1, 0) ? "up " : "down ",
-                   e->made_contact ? "made-contact" : "never-contacted");
+      const char *msg = NULL;
+      if (entry_is_live(e, 0, 1, 0, &msg))
+        tor_snprintf(buf, sizeof(buf), "%s (up %s)",
+                     e->nickname,
+                     e->made_contact ? "made-contact" : "never-contacted");
+      else
+        tor_snprintf(buf, sizeof(buf), "%s (%s, %s)",
+                     e->nickname, msg,
+                     e->made_contact ? "made-contact" : "never-contacted");
       smartlist_add(elements, tor_strdup(buf));
     });
 
@@ -2938,12 +2962,13 @@ control_event_guard_deferred(void)
    **/
 #if 0
   int n = 0;
+  const char *msg;
   or_options_t *options = get_options();
   if (!entry_guards)
     return;
   SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
     {
-      if (entry_is_live(entry, 0, 1, 0)) {
+      if (entry_is_live(entry, 0, 1, 0, &msg)) {
         if (n++ == options->NumEntryGuards) {
           control_event_guard(entry->nickname, entry->identity, "DEFERRED");
           return;
@@ -3165,13 +3190,16 @@ entry_guards_compute_status(void)
   if (changed) {
     SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
       const char *reason = digestmap_get(reasons, entry->identity);
-      log_info(LD_CIRC, "Summary: Entry '%s' is %s, %s%s%s, and %s.",
+      const char *live_msg;
+      routerinfo_t *r = entry_is_live(entry, 0, 1, 0, &live_msg);
+      log_info(LD_CIRC, "Summary: Entry '%s' is %s, %s%s%s, and %s%s.",
                entry->nickname,
                entry->unreachable_since ? "unreachable" : "reachable",
                entry->bad_since ? "unusable" : "usable",
                reason ? ", ": "",
                reason ? reason : "",
-               entry_is_live(entry, 0, 1, 0) ? "live" : "not live");
+               r ? "live" : "not live / ",
+               r ? "" : live_msg);
     } SMARTLIST_FOREACH_END(entry);
     log_info(LD_CIRC, "    (%d/%d entry guards are usable/new)",
              num_live_entry_guards(), smartlist_len(entry_guards));
@@ -3278,7 +3306,8 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
         if (e == entry)
           break;
         if (e->made_contact) {
-          routerinfo_t *r = entry_is_live(e, 0, 1, 1);
+          const char *msg;
+          routerinfo_t *r = entry_is_live(e, 0, 1, 1, &msg);
           if (r && e->unreachable_since) {
             refuse_conn = 1;
             e->can_retry = 1;
@@ -3457,7 +3486,8 @@ choose_random_entry(cpath_build_state_t *state)
   smartlist_clear(live_entry_guards);
   SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
     {
-      r = entry_is_live(entry, need_uptime, need_capacity, 0);
+      const char *msg;
+      r = entry_is_live(entry, need_uptime, need_capacity, 0, &msg);
       if (!r)
         continue; /* down, no point */
       if (consider_exit_family && smartlist_isin(exit_family, r))
-- 
1.5.6.5