[tor-commits] [tor/master] Rebuild the guard lists as appropriate on torrc change.

nickm at torproject.org nickm at torproject.org
Fri Dec 16 16:26:18 UTC 2016


commit 897626953b15ac216d27b3814804524caa9fdd1c
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Nov 23 09:09:30 2016 -0500

    Rebuild the guard lists as appropriate on torrc change.
    
    (Also, prepare to tie guard changes into the mark-all-old-circuits
    logic.)
---
 src/or/config.c     | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/or/entrynodes.c | 17 ++++++++++++-----
 src/or/entrynodes.h |  4 ++--
 src/or/main.c       |  5 ++++-
 4 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/src/or/config.c b/src/or/config.c
index f77f4d1..b7b5cff 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1561,6 +1561,36 @@ options_transition_requires_fresh_tls_context(const or_options_t *old_options,
   return 0;
 }
 
+/**
+ * Return true if changing the configuration from <b>old</b> to <b>new</b>
+ * affects the guard susbsystem.
+ */
+static int
+options_transition_affects_guards(const or_options_t *old,
+                                  const or_options_t *new)
+{
+  /* NOTE: Make sure this function stays in sync with
+   * entry_guards_set_filtered_flags */
+
+  tor_assert(old);
+  tor_assert(new);
+
+  return
+    (old->UseEntryGuards != new->UseEntryGuards ||
+     old->UseDeprecatedGuardAlgorithm != new->UseDeprecatedGuardAlgorithm ||
+     old->UseBridges != new->UseBridges ||
+     old->UseEntryGuards != new->UseEntryGuards ||
+     old->ClientUseIPv4 != new->ClientUseIPv4 ||
+     old->ClientUseIPv6 != new->ClientUseIPv6 ||
+     old->FascistFirewall != new->FascistFirewall ||
+     !routerset_equal(old->ExcludeNodes, new->ExcludeNodes) ||
+     !routerset_equal(old->EntryNodes, new->EntryNodes) ||
+     !smartlist_strings_eq(old->FirewallPorts, new->FirewallPorts) ||
+     !config_lines_eq(old->Bridges, new->Bridges) ||
+     !config_lines_eq(old->ReachableORAddresses, new->ReachableORAddresses) ||
+     !config_lines_eq(old->ReachableDirAddresses, new->ReachableDirAddresses));
+}
+
 /** Fetch the active option list, and take actions based on it. All of the
  * things we do should survive being done repeatedly.  If present,
  * <b>old_options</b> contains the previous value of the options.
@@ -1580,6 +1610,8 @@ options_act(const or_options_t *old_options)
   const int transition_affects_workers =
     old_options && options_transition_affects_workers(old_options, options);
   int old_ewma_enabled;
+  const int transition_affects_guards =
+    old_options && options_transition_affects_guards(old_options, options);
 
   /* disable ptrace and later, other basic debugging techniques */
   {
@@ -1875,6 +1907,7 @@ options_act(const or_options_t *old_options)
   if (old_options) {
     int revise_trackexithosts = 0;
     int revise_automap_entries = 0;
+    int abandon_circuits = 0;
     if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
         options->UseBridges != old_options->UseBridges ||
         (options->UseBridges &&
@@ -1891,6 +1924,16 @@ options_act(const or_options_t *old_options)
                "Changed to using entry guards or bridges, or changed "
                "preferred or excluded node lists. "
                "Abandoning previous circuits.");
+      abandon_circuits = 1;
+    }
+
+    if (transition_affects_guards) {
+      if (guards_update_all()) {
+        abandon_circuits = 1;
+      }
+    }
+
+    if (abandon_circuits) {
       circuit_mark_all_unused_circs();
       circuit_mark_all_dirty_circs_as_unusable();
       revise_trackexithosts = 1;
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 81751f5..9a753e6 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -91,7 +91,7 @@
  *
  * [x] Whenever we get a new consensus, call update_from_consensus(). (LATER.)
  *
- * [ ] Whenever the configuration changes in a relevant way, update the
+ * [x] Whenever the configuration changes in a relevant way, update the
  * filtered/usable flags. (LATER.)
  *
  * [x] Whenever we add a guard to the sample, make sure its filtered/usable
@@ -696,6 +696,9 @@ static int
 node_passes_guard_filter(const or_options_t *options, guard_selection_t *gs,
                          const node_t *node)
 {
+  /* NOTE: Make sure that this function stays in sync with
+   * options_transition_affects_entry_guards */
+
   (void)gs;
   if (routerset_contains_node(options->ExcludeNodes, node))
     return 0;
@@ -1636,14 +1639,16 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
 
 /**
  * Update all derived pieces of the guard selection state in <b>gs</b>.
+ * Return true iff we should stop using all previously generated circuits.
  */
-void
+int
 entry_guards_update_all(guard_selection_t *gs)
 {
   sampled_guards_update_from_consensus(gs);
   entry_guards_update_filtered_sets(gs);
   entry_guards_update_confirmed(gs);
   entry_guards_update_primary(gs);
+  return 0;
 }
 
 /**
@@ -4020,14 +4025,16 @@ entries_retry_all(const or_options_t *options)
 }
 
 /** Helper: Update the status of all entry guards, in whatever algorithm
-    is used. */
-void
+ * is used. Return true if we should stop using all previously generated
+ * circuits. */
+int
 guards_update_all(void)
 {
   if (get_options()->UseDeprecatedGuardAlgorithm) {
     entry_guards_compute_status(get_options(), approx_time());
+    return 0;
   } else {
-    entry_guards_update_all(get_guard_selection_info());
+    return entry_guards_update_all(get_guard_selection_info());
   }
 }
 
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index d8468eb..4cbfbf5 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -294,7 +294,7 @@ struct circuit_guard_state_t {
 #endif
 
 /* Common entry points for old and new guard code */
-void guards_update_all(void);
+int guards_update_all(void);
 const node_t *guards_choose_guard(cpath_build_state_t *state,
                                   circuit_guard_state_t **guard_state_out);
 const node_t *guards_choose_dirguard(dirinfo_type_t info,
@@ -336,7 +336,7 @@ void entry_guard_cancel(guard_selection_t *gs,
                         circuit_guard_state_t **guard_state_p);
 void entry_guard_chan_failed(guard_selection_t *gs,
                             channel_t *chan);
-void entry_guards_update_all(guard_selection_t *gs);
+int entry_guards_update_all(guard_selection_t *gs);
 int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
                                           const smartlist_t *all_circuits,
                                           smartlist_t *newly_complete_out);
diff --git a/src/or/main.c b/src/or/main.c
index 65d1c1f..1610661 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -979,7 +979,10 @@ directory_info_has_arrived(time_t now, int from_cache, int suppress_logs)
 
     /* if we have enough dir info, then update our guard status with
      * whatever we just learned. */
-    guards_update_all();
+    int invalidate_circs = guards_update_all();
+    // This shouldn't be able to occur at this point.
+    tor_assert_nonfatal(! invalidate_circs);
+
     /* Don't even bother trying to get extrainfo until the rest of our
      * directory info is up-to-date */
     if (options->DownloadExtraInfo)





More information about the tor-commits mailing list