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

[or-cvs] Implement exit enclaves: if we know an IP address for the d...



Update of /home2/or/cvsroot/tor/src/or
In directory moria:/home/arma/work/onion/cvs/tor/src/or

Modified Files:
	circuitbuild.c circuituse.c connection_edge.c control.c or.h 
	routerlist.c 
Log Message:
Implement exit enclaves: if we know an IP address for the destination,
and there's a running Tor server at that address which allows exit to
the destination, then extend the circuit to that exit first.
Also, if the user asks for a .exit node, cannibalize general circs for it.


Index: circuitbuild.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -d -r1.134 -r1.135
--- circuitbuild.c	12 Aug 2005 17:24:53 -0000	1.134
+++ circuitbuild.c	15 Aug 2005 03:25:39 -0000	1.135
@@ -1168,7 +1168,7 @@
         router = smartlist_get(dir->routers, i);
         if (n_supported[i] != -1 &&
             (try || router_handles_some_port(router, needed_ports))) {
-          log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.", try, router->nickname);
+//          log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.", try, router->nickname);
           smartlist_add(sl, router);
         }
       }

Index: circuituse.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuituse.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- circuituse.c	13 Aug 2005 00:22:06 -0000	1.79
+++ circuituse.c	15 Aug 2005 03:25:39 -0000	1.80
@@ -749,7 +749,7 @@
     return NULL;
   }
 
-  if (purpose != CIRCUIT_PURPOSE_C_GENERAL &&
+  if ((info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
       purpose != CIRCUIT_PURPOSE_TESTING) {
     /* see if there are appropriate circs available to cannibalize. */
     if ((circ = circuit_get_clean_open(CIRCUIT_PURPOSE_C_GENERAL, need_uptime,
@@ -768,6 +768,7 @@
           break;
         case CIRCUIT_PURPOSE_C_INTRODUCING:
         case CIRCUIT_PURPOSE_S_CONNECT_REND:
+        case CIRCUIT_PURPOSE_C_GENERAL:
           /* need to add a new hop */
           tor_assert(info);
           if (circuit_extend_to_new_exit(circ, info) < 0)

Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.339
retrieving revision 1.340
diff -u -d -r1.339 -r1.340
--- connection_edge.c	8 Aug 2005 21:58:48 -0000	1.339
+++ connection_edge.c	15 Aug 2005 03:25:39 -0000	1.340
@@ -1009,7 +1009,7 @@
         return -1;
       }
       if (tor_inet_aton(socks->address, &in)) { /* see if it's an IP already */
-        answer = in.s_addr;
+        answer = in.s_addr; /* leave it in network order */
         connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
                                                (char*)&answer);
         connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
@@ -1023,20 +1023,34 @@
         connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
         return -1;
       }
+
+      if (!conn->chosen_exit_name) {
+        /* see if we can find a suitable enclave exit */
+        routerinfo_t *r =
+          router_find_exact_exit_enclave(socks->address, socks->port);
+        if (r) {
+          log_fn(LOG_INFO,"Redirecting address %s to exit at enclave router %s",
+                 safe_str(socks->address), r->nickname);
+          /* use the hex digest, not nickname, in case there are two
+             routers with this nickname */
+          conn->chosen_exit_name =
+            tor_strdup(hex_str(r->identity_digest, DIGEST_LEN));
+        }
+      }
+
       rep_hist_note_used_port(socks->port, time(NULL)); /* help predict this next time */
       control_event_stream_status(conn, STREAM_EVENT_NEW);
     }
-    if (! get_options()->LeaveStreamsUnattached) {
+    if (get_options()->LeaveStreamsUnattached) {
+      conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+    } else {
       conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
       if (connection_ap_handshake_attach_circuit(conn) < 0) {
         connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
         return -1;
       }
-      return 0;
-    } else {
-      conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
-      return 0;
     }
+    return 0;
   } else {
     /* it's a hidden-service request */
     rend_cache_entry_t *entry;

Index: control.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- control.c	13 Aug 2005 02:20:00 -0000	1.120
+++ control.c	15 Aug 2005 03:25:39 -0000	1.121
@@ -2300,6 +2300,7 @@
                         (unsigned long)conn->global_identifier, status,
                         circ?(unsigned long)circ->global_identifier : 0ul,
                         buf);
+    /* XXX need to specify its intended exit, etc? */
   }
   return 0;
 }

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.643
retrieving revision 1.644
diff -u -d -r1.643 -r1.644
--- or.h	13 Aug 2005 02:20:00 -0000	1.643
+++ or.h	15 Aug 2005 03:25:39 -0000	1.644
@@ -626,7 +626,7 @@
   char identity_digest[DIGEST_LEN]; /**< Hash of identity_pkey */
   char *nickname; /**< Nickname of OR on other side (if any). */
 
-  /** Nickname of planned exit node -- to be used with .exit support. */
+  /** Nickname of planned exit node -- used with .exit support. */
   char *chosen_exit_name;
 
 /* Used only by OR connections: */
@@ -1952,6 +1952,7 @@
 #define ROUTER_REQUIRED_MIN_UPTIME (24*3600) /* a day */
 #define ROUTER_REQUIRED_MIN_BANDWIDTH 10000
 
+routerinfo_t *router_find_exact_exit_enclave(const char *address, uint16_t port);
 int router_is_unreliable(routerinfo_t *router, int need_uptime, int need_capacity);
 routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl);
 routerinfo_t *router_choose_random_node(const char *preferred,

Index: routerlist.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.248
retrieving revision 1.249
diff -u -d -r1.248 -r1.249
--- routerlist.c	12 Aug 2005 00:34:50 -0000	1.248
+++ routerlist.c	15 Aug 2005 03:25:40 -0000	1.249
@@ -433,6 +433,37 @@
   return NULL;
 }
 
+/** Find a router that's up, that has this IP address, and
+ * that allows exit to this address:port, or return NULL if there
+ * isn't a good one.
+ */
+routerinfo_t *
+router_find_exact_exit_enclave(const char *address, uint16_t port) {
+  int i;
+  routerinfo_t *router;
+  uint32_t addr;
+  struct in_addr in;
+
+  if (!tor_inet_aton(address, &in))
+    return NULL; /* it's not an IP already */
+  addr = ntohl(in.s_addr);
+
+  for (i=0;i < smartlist_len(routerlist->routers); i++) {
+    router = smartlist_get(routerlist->routers, i);
+    log_fn(LOG_DEBUG,"Considering %s: %d, %u==%u, %d.",
+           router->nickname,
+           router->is_running,
+           router->addr, addr,
+           router_compare_addr_to_addr_policy(addr, port, router->exit_policy));
+    if (router->is_running &&
+        router->addr == addr &&
+        router_compare_addr_to_addr_policy(addr, port, router->exit_policy) ==
+          ADDR_POLICY_ACCEPTED)
+      return router;
+  }
+  return NULL;
+}
+
 /** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
  * If <b>need_uptime</b> is non-zero, we require a minimum uptime.
  * If <b>need_capacity</b> is non-zero, we require a minimum advertised