[tor-commits] [tor/master] Add the ability to count circuit timeouts for guards.

nickm at torproject.org nickm at torproject.org
Wed Dec 26 04:34:54 UTC 2012


commit 954f263ed5eb451a0742f8888681e10e64dd193a
Author: Mike Perry <mikeperry-git at fscked.org>
Date:   Wed Oct 24 17:34:18 2012 -0700

    Add the ability to count circuit timeouts for guards.
    
    This is purely for informational reasons for debugging.
---
 src/or/circuitbuild.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/circuituse.c   |    2 +
 src/or/entrynodes.c   |   18 +++++++++----
 src/or/entrynodes.h   |    2 +
 src/or/or.h           |    2 +
 5 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 7301874..c8c8db3 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1057,6 +1057,53 @@ pathbias_state_to_string(path_state_t state)
 }
 
 /**
+ * Decide if the path bias code should count a circuit.
+ *
+ * @returns 1 if we should count it, 0 otherwise.
+ */
+static int
+pathbias_should_count(origin_circuit_t *circ)
+{
+#define PATHBIAS_COUNT_INTERVAL (600)
+  static ratelim_t count_limit =
+    RATELIM_INIT(PATHBIAS_COUNT_INTERVAL);
+  char *rate_msg = NULL;
+
+  /* We can't do path bias accounting without entry guards.
+   * Testing and controller circuits also have no guards. */
+  if (get_options()->UseEntryGuards == 0 ||
+          circ->base_.purpose == CIRCUIT_PURPOSE_TESTING ||
+          circ->base_.purpose == CIRCUIT_PURPOSE_CONTROLLER) {
+    return 0;
+  }
+
+  /* Completely ignore one hop circuits */
+  if (circ->build_state->onehop_tunnel ||
+      circ->build_state->desired_path_len == 1) {
+    /* Check for inconsistency */
+    if (circ->build_state->desired_path_len != 1 ||
+        !circ->build_state->onehop_tunnel) {
+      if ((rate_msg = rate_limit_log(&count_limit, approx_time()))) {
+        log_notice(LD_BUG,
+               "One-hop circuit has length %d. Path state is %s. "
+               "Circuit is a %s currently %s.%s",
+               circ->build_state->desired_path_len,
+               pathbias_state_to_string(circ->path_state),
+               circuit_purpose_to_string(circ->base_.purpose),
+               circuit_state_to_string(circ->base_.state),
+               rate_msg);
+        tor_free(rate_msg);
+      }
+      tor_fragile_assert();
+    }
+    return 0;
+  }
+
+  return 1;
+}
+
+
+/**
  * Check our circuit state to see if this is a successful first hop.
  * If so, record it in the current guard's path bias first_hop count.
  *
@@ -1290,6 +1337,26 @@ pathbias_count_success(origin_circuit_t *circ)
   }
 }
 
+/**
+ * Count timeouts for path bias log messages.
+ *
+ * These counts are purely informational.
+ */
+void
+pathbias_count_timeout(origin_circuit_t *circ)
+{
+  if(!pathbias_should_count(circ)) {
+    return;
+  }
+  entry_guard_t *guard =
+      entry_guard_get_by_id_digest(circ->base_.n_chan->identity_digest);
+
+  if (guard) {
+    guard->timeouts++;
+    entry_guards_changed();
+  }
+}
+
 /** Increment the number of times we successfully extended a circuit to
  * 'guard', first checking if the failure rate is high enough that we should
  * eliminate the guard.  Return -1 if the guard looks no good; return 0 if the
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index e14f9d0..77822a3 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -663,6 +663,8 @@ circuit_expire_building(void)
       circuit_mark_for_close(victim, END_CIRC_REASON_MEASUREMENT_EXPIRED);
     else
       circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
+
+    pathbias_count_timeout(TO_ORIGIN_CIRCUIT(victim));
   }
 }
 
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 8712241..d9a06a6 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1021,7 +1021,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
       digestmap_set(added_by, d, tor_strdup(line->value+HEX_DIGEST_LEN+1));
     } else if (!strcasecmp(line->key, "EntryGuardPathBias")) {
       const or_options_t *options = get_options();
-      unsigned hop_cnt, success_cnt;
+      unsigned hop_cnt, success_cnt, timeouts;
 
       if (!node) {
         *msg = tor_strdup("Unable to parse entry nodes: "
@@ -1029,14 +1029,20 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
         break;
       }
 
-      if (tor_sscanf(line->value, "%u %u", &success_cnt, &hop_cnt) != 2) {
-        log_warn(LD_GENERAL, "Unable to parse guard path bias info: "
+      /* First try 3 params, then 2. */
+      if (tor_sscanf(line->value, "%u %u %u", &success_cnt, &hop_cnt,
+                     &timeouts) != 3) {
+        timeouts = 0;
+        if (tor_sscanf(line->value, "%u %u", &success_cnt, &hop_cnt) != 2) {
+          log_warn(LD_GENERAL, "Unable to parse guard path bias info: "
                  "Misformated EntryGuardPathBias %s", escaped(line->value));
-        continue;
+          continue;
+        }
       }
 
       node->first_hops = hop_cnt;
       node->circuit_successes = success_cnt;
+      node->timeouts = timeouts;
       log_info(LD_GENERAL, "Read %u/%u path bias for node %s",
                node->circuit_successes, node->first_hops, node->nickname);
       /* Note: We rely on the < comparison here to allow us to set a 0
@@ -1173,8 +1179,8 @@ entry_guards_update_state(or_state_t *state)
       if (e->first_hops) {
         *next = line = tor_malloc_zero(sizeof(config_line_t));
         line->key = tor_strdup("EntryGuardPathBias");
-        tor_asprintf(&line->value, "%u %u",
-                     e->circuit_successes, e->first_hops);
+        tor_asprintf(&line->value, "%u %u %u",
+                     e->circuit_successes, e->first_hops, e->timeouts);
         next = &(line->next);
       }
 
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 4d031c3..b347441 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -47,6 +47,8 @@ typedef struct entry_guard_t {
   unsigned first_hops; /**< Number of first hops this guard has completed */
   unsigned circuit_successes; /**< Number of successfully built circuits using
                                * this guard as first hop. */
+  unsigned timeouts; /**< Number of 'right-censored' timeouts 
+                                   for this guard. */
 } entry_guard_t;
 
 entry_guard_t *entry_guard_get_by_id_digest(const char *digest);
diff --git a/src/or/or.h b/src/or/or.h
index 195cb2b..5920210 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -4067,6 +4067,8 @@ typedef struct {
   double close_ms;
 } circuit_build_times_t;
 
+void pathbias_count_timeout(origin_circuit_t *circ);
+
 /********************************* config.c ***************************/
 
 /** An error from options_trial_assign() or options_init_from_string(). */





More information about the tor-commits mailing list