[or-cvs] [tor/master] Be more willing to use an unsuitable circuit for exit.

arma at seul.org arma at seul.org
Mon Dec 21 09:07:17 UTC 2009


Author: Roger Dingledine <arma at torproject.org>
Date: Sat, 19 Sep 2009 21:52:57 -0400
Subject: Be more willing to use an unsuitable circuit for exit.
Commit: ef81649d2fc9246d6fec07402eafae689a39688a

Specifically, there are two cases: a) are we willing to start a new
circuit at a node not in your ExitNodes config option, and b) are we
willing to make use of a circuit that's already established but has an
unsuitable exit.

Now we discard all your circuits when you set ExitNodes, so the only
way you could end up with an exit circuit that ends at an unsuitable
place is if we explicitly ran out of exit nodes, StrictNodes was 0,
and we built this circuit to solve a stream that needs solving.

Fixes bug in dc322931, which would ignore the just-built circuit because
it has an unsuitable exit.
---
 src/or/circuitbuild.c    |    7 ++++---
 src/or/circuituse.c      |    8 ++++----
 src/or/config.c          |   11 ++++++++---
 src/or/connection_edge.c |   21 ++++++++++++++++++++-
 src/or/or.h              |    3 ++-
 5 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 56c49c2..5198c13 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2132,7 +2132,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
     {
       if (!ap_stream_wants_exit_attention(conn))
         continue; /* Skip everything but APs in CIRCUIT_WAIT */
-      if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router)) {
+      if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router, 1)) {
         ++n_supported[i];
 //        log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
 //               router->nickname, i, n_supported[i]);
@@ -2200,8 +2200,9 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
         tor_free(n_supported);
         return choose_good_exit_server_general(dir, 0, 0);
       }
-      log_notice(LD_CIRC, "All routers are down or won't exit -- choosing a "
-                 "doomed exit at random.");
+      log_notice(LD_CIRC, "All routers are down or won't exit%s -- "
+                 "choosing a doomed exit at random.",
+                 options->_ExcludeExitNodesUnion ? " or are Excluded" : "");
     }
     supporting = smartlist_create();
     use = smartlist_create();
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 145aefe..59b6998 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -115,7 +115,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
         return 0;
       }
     }
-    if (exitrouter && !connection_ap_can_use_exit(conn, exitrouter)) {
+    if (exitrouter && !connection_ap_can_use_exit(conn, exitrouter, 0)) {
       /* can't exit from this router */
       return 0;
     }
@@ -424,7 +424,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
       if (exitrouter && (!need_uptime || build_state->need_uptime)) {
         int ok;
         if (conn) {
-          ok = connection_ap_can_use_exit(conn, exitrouter);
+          ok = connection_ap_can_use_exit(conn, exitrouter, 0);
         } else {
           addr_policy_result_t r = compare_addr_to_addr_policy(
               0, port, exitrouter->exit_policy);
@@ -1111,7 +1111,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
       /* XXXX022 Duplicates checks in connection_ap_handshake_attach_circuit */
       routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
       int opt = conn->chosen_exit_optional;
-      if (router && !connection_ap_can_use_exit(conn, router)) {
+      if (router && !connection_ap_can_use_exit(conn, router, 0)) {
         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
                "Requested exit point '%s' would refuse request. %s.",
                conn->chosen_exit_name, opt ? "Trying others" : "Closing");
@@ -1431,7 +1431,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
         }
         return -1;
       }
-      if (router && !connection_ap_can_use_exit(conn, router)) {
+      if (router && !connection_ap_can_use_exit(conn, router, 0)) {
         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
                "Requested exit point '%s' would refuse request. %s.",
                conn->chosen_exit_name, opt ? "Trying others" : "Closing");
diff --git a/src/or/config.c b/src/or/config.c
index b67ed3f..0f6d997 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1424,10 +1424,15 @@ options_act(or_options_t *old_options)
          !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes)) ||
         (options->ExcludeExitNodes &&
          !routerset_equal(old_options->ExcludeExitNodes,
-                          options->ExcludeExitNodes))) {
+                          options->ExcludeExitNodes)) ||
+        (options->EntryNodes &&
+         !routerset_equal(old_options->EntryNodes, options->EntryNodes)) ||
+        (options->ExitNodes &&
+         !routerset_equal(old_options->ExitNodes, options->ExitNodes)) ||
+        options->StrictNodes != old_options->StrictNodes) {
       log_info(LD_CIRC,
-               "Changed to using entry guards, or changed ExcludeNodes, or "
-               "changed ExcludeExitNodes. Abandoning previous circuits.");
+               "Changed to using entry guards, or changed preferred or "
+               "excluded node lists. Abandoning previous circuits.");
       circuit_mark_all_unused_circs();
       circuit_expire_all_dirty_circs();
     }
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index b1e952d..47230da 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2840,9 +2840,13 @@ connection_edge_is_rendezvous_stream(edge_connection_t *conn)
  * to exit from it, or 0 if it probably will not allow it.
  * (We might be uncertain if conn's destination address has not yet been
  * resolved.)
+ *
+ * If <b>excluded_means_no</b> is 1 and Exclude*Nodes is set and excludes
+ * this relay, return 0.
  */
 int
-connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
+connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+                           int excluded_means_no)
 {
   tor_assert(conn);
   tor_assert(conn->_base.type == CONN_TYPE_AP);
@@ -2889,6 +2893,21 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
     if (!conn->chosen_exit_name && policy_is_reject_star(exit->exit_policy))
       return 0;
   }
+  if (options->_ExcludeExitNodesUnion &&
+      (options->StrictNodes || excluded_means_no) &&
+      routerset_contains_router(options->_ExcludeExitNodesUnion, exit)) {
+    /* If we are trying to avoid this node as exit, and we have StrictNodes
+     * set, then this is not a suitable exit. Refuse it.
+     *
+     * If we don't have StrictNodes set, then this function gets called in
+     * two contexts. First, we've got a circuit open and we want to know
+     * whether we can use it. In that case, we somehow built this circuit
+     * despite having the last hop in ExcludeExitNodes, so we should be
+     * willing to use it. Second, we are evaluating whether this is an
+     * acceptable exit for a new circuit. In that case, skip it. */
+    return 0;
+  }
+
   return 1;
 }
 
diff --git a/src/or/or.h b/src/or/or.h
index dabc401..431b62e 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3452,7 +3452,8 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
 int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
 void connection_exit_connect(edge_connection_t *conn);
 int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
-int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit);
+int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+                               int excluded_means_no);
 void connection_ap_expire_beginning(void);
 void connection_ap_attach_pending(void);
 void connection_ap_fail_onehop(const char *failed_digest,
-- 
1.5.6.5




More information about the tor-commits mailing list