[or-cvs] r13648: start allowing clients to give up on trackhostexits targets (tor/trunk/src/or)

arma at seul.org arma at seul.org
Thu Feb 21 09:00:54 UTC 2008


Author: arma
Date: 2008-02-21 04:00:54 -0500 (Thu, 21 Feb 2008)
New Revision: 13648

Modified:
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/relay.c
Log:
start allowing clients to give up on trackhostexits targets if
five circuit attempts fail for a given stream. part of the fix
for bug 437. still an XXX020rc remaining.


Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2008-02-21 08:08:13 UTC (rev 13647)
+++ tor/trunk/src/or/connection.c	2008-02-21 09:00:54 UTC (rev 13648)
@@ -2876,7 +2876,7 @@
     assert_buf_ok(conn->outbuf);
   }
 
-  if (conn->chosen_exit_optional) {
+  if (conn->chosen_exit_optional || conn->chosen_exit_retries) {
     tor_assert(conn->type == CONN_TYPE_AP);
     tor_assert((TO_EDGE_CONN(conn))->chosen_exit_name);
   }

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2008-02-21 08:08:13 UTC (rev 13647)
+++ tor/trunk/src/or/connection_edge.c	2008-02-21 09:00:54 UTC (rev 13648)
@@ -472,13 +472,16 @@
     if (conn->marked_for_close ||
         conn->type != CONN_TYPE_AP ||
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT ||
-        !conn->chosen_exit_optional)
+        (!conn->chosen_exit_optional &&
+         !conn->chosen_exit_retries))
       continue;
     edge_conn = TO_EDGE_CONN(conn);
     r1 = router_get_by_nickname(edge_conn->chosen_exit_name, 0);
     r2 = router_get_by_nickname(info->nickname, 0);
-    if (r1 && r2 && r1==r2) {
-      tor_assert(edge_conn->socks_request);
+    if (!r1 || !r2 || r1 != r2)
+      continue;
+    tor_assert(edge_conn->socks_request);
+    if (conn->chosen_exit_optional) {
       log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
                safe_str(edge_conn->chosen_exit_name),
                escaped_safe_str(edge_conn->socks_request->address));
@@ -488,6 +491,16 @@
        * think it'll be using an enclave. */
       consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
     }
+    if (conn->chosen_exit_retries) {
+      if (--conn->chosen_exit_retries == 0) { /* give up! */
+        /* XXX020rc unregister maps from foo to
+         * foo.chosen_exit_name.exit \forall foo. -RD */
+        tor_free(edge_conn->chosen_exit_name); /* clears it */
+        /* if this port is dangerous, warn or reject it now that we don't
+         * think it'll be using an enclave. */
+        consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
+      }
+    }
   });
 }
 
@@ -1244,6 +1257,7 @@
   int automap = 0;
   char orig_address[MAX_SOCKS_ADDR_LEN];
   time_t map_expires = TIME_MAX;
+  int remapped_to_exit = 0;
   time_t now = time(NULL);
 
   tor_strlower(socks->address); /* normalize it */
@@ -1299,11 +1313,16 @@
       }
     }
   } else if (!automap) {
+    int started_without_chosen_exit = strcasecmpend(socks->address, ".exit");
     /* For address map controls, remap the address. */
     if (addressmap_rewrite(socks->address, sizeof(socks->address),
                            &map_expires)) {
       control_event_stream_status(conn, STREAM_EVENT_REMAP,
                                   REMAP_STREAM_SOURCE_CACHE);
+      if (started_without_chosen_exit &&
+          !strcasecmpend(socks->address, ".exit") &&
+          map_expires < TIME_MAX)
+        remapped_to_exit = 1;
     }
   }
 
@@ -1340,6 +1359,10 @@
     if (s) {
       if (s[1] != '\0') {
         conn->chosen_exit_name = tor_strdup(s+1);
+/* DOCDOC */
+#define TRACKHOSTEXITS_RETRIES 5
+        if (remapped_to_exit) /* 5 tries before it expires the addressmap */
+          TO_CONN(conn)->chosen_exit_retries = TRACKHOSTEXITS_RETRIES;
         *s = 0;
       } else {
         log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-02-21 08:08:13 UTC (rev 13647)
+++ tor/trunk/src/or/or.h	2008-02-21 09:00:54 UTC (rev 13648)
@@ -811,6 +811,11 @@
   /** For AP connections only. If 1, and we fail to reach the chosen exit,
    * stop requiring it. */
   unsigned int chosen_exit_optional:1;
+  /** For AP connections only. If non-zero, this exit node was picked as
+   * a result of the TrackHostExit, and the value decrements every time
+   * we fail to complete a circuit to our chosen exit -- if it reaches
+   * zero, abandon the associated mapaddress. */
+  unsigned int chosen_exit_retries:3;
   /** Set to 1 when we're inside connection_flushed_some to keep us from
    * calling connection_handle_write() recursively. */
   unsigned int in_flushed_some:1;
@@ -861,7 +866,7 @@
                                       * we marked for close? */
   char *address; /**< FQDN (or IP) of the guy on the other end.
                   * strdup into this, because free_connection frees it. */
-  /** Annother connection that's connected to this one in lieu of a socket. */
+  /** Another connection that's connected to this one in lieu of a socket. */
   struct connection_t *linked_conn;
 
   /* XXXX021 move this into a subtype. */

Modified: tor/trunk/src/or/relay.c
===================================================================
--- tor/trunk/src/or/relay.c	2008-02-21 08:08:13 UTC (rev 13647)
+++ tor/trunk/src/or/relay.c	2008-02-21 09:00:54 UTC (rev 13648)
@@ -771,9 +771,18 @@
                                NULL)) {
           control_event_stream_status(conn, STREAM_EVENT_REMAP, 0);
         }
-        if (conn->_base.chosen_exit_optional) {
+        if (conn->_base.chosen_exit_optional ||
+            conn->_base.chosen_exit_retries) {
           /* stop wanting a specific exit */
           conn->_base.chosen_exit_optional = 0;
+          /* A non-zero chosen_exit_retries can happen if we set a
+           * TrackHostExits for this address under a port that the exit
+           * relay allows, but then try the same address with a different
+           * port that it doesn't allow to exit. We shouldn't unregister
+           * the mapping, since it is probably still wanted on the
+           * original port. But now we give away to the exit relay that
+           * we probably have a TrackHostExits on it. So be it. */
+          conn->_base.chosen_exit_retries = 0;
           tor_free(conn->chosen_exit_name); /* clears it */
         }
         if (connection_ap_detach_retriable(conn, circ, control_reason) >= 0)



More information about the tor-commits mailing list