[or-cvs] r9249: checkpoint as we add PreferTunneledDirConns config option (in tor/trunk: doc src/or)

arma at seul.org arma at seul.org
Wed Jan 3 06:33:22 UTC 2007


Author: arma
Date: 2007-01-03 01:33:03 -0500 (Wed, 03 Jan 2007)
New Revision: 9249

Modified:
   tor/trunk/doc/TODO
   tor/trunk/src/or/config.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
Log:
checkpoint as we add PreferTunneledDirConns config option


Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-01-03 05:12:26 UTC (rev 9248)
+++ tor/trunk/doc/TODO	2007-01-03 06:33:03 UTC (rev 9249)
@@ -35,7 +35,6 @@
 N - enumerate events of important things that occur in tor, so vidalia can
     react.
     o Backend implementation
-R   - Clean up the spec a bit.
     - Actually list all the events (notice and warn log messages are a good
       place to look.)  Divide messages into categories, perhaps.
     - Specify general event system
@@ -64,10 +63,14 @@
         o Make an option like __AllDirActionsPrivate that falls back to
           non-Tor DL when not enough info present.  (TunnelDirConns).
         - Set default to 0 before release candidate.
-        - Think harder about whether TunnelDirConns should be on
-          by default.
-        - Handle case where we have no descriptors and so don't know who can
+        o Think harder about whether TunnelDirConns should be on
+          by default. No, they shouldn't, until we have much more of
+          blocking.pdf implemented.
+        o Handle case where we have no descriptors and so don't know who can
           handle BEGIN_DIR.
+        - actually cause the directory.c functions to know about or_port
+          and use it when we're supposed to.
+        - man page items for TunnelDirConns and PreferTunneledDirConns
 
 N - DNS improvements
     . Asynchronous DNS

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-01-03 05:12:26 UTC (rev 9248)
+++ tor/trunk/src/or/config.c	2007-01-03 06:33:03 UTC (rev 9249)
@@ -208,6 +208,7 @@
   VAR("OutboundBindAddress", STRING,   OutboundBindAddress,  NULL),
   VAR("PathlenCoinWeight",   DOUBLE,   PathlenCoinWeight,    "0.3"),
   VAR("PidFile",             STRING,   PidFile,              NULL),
+  VAR("PreferTunneledDirConns", BOOL,  PreferTunneledDirConns, "1"),
   VAR("ProtocolWarnings",    BOOL,     ProtocolWarnings,     "0"),
   VAR("PublishServerDescriptor",BOOL,  PublishServerDescriptor,"1"),
   VAR("PublishHidServDescriptors",BOOL,PublishHidServDescriptors, "1"),
@@ -346,6 +347,7 @@
     "provided IP address (only usefol for multiple network interfaces)." },
   { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
     "remove the file." },
+  /* PreferTunneledDirConns */
   /* ProtocolWarnings */
   /* RephistTrackTime */
   { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
@@ -2707,6 +2709,9 @@
   if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
     return -1;
 
+  if (options->PreferTunneledDirConns && !options->TunnelDirConns)
+    REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
+
   return 0;
 #undef REJECT
 #undef COMPLAIN

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-01-03 05:12:26 UTC (rev 9248)
+++ tor/trunk/src/or/directory.c	2007-01-03 06:33:03 UTC (rev 9249)
@@ -362,6 +362,17 @@
   /* XXXX012 Why did the above get commented out? -NM */
 }
 
+/** Return 1 if platform can handle a BEGIN_DIR cell, and if
+ * we're willing to send one. Else return 0. */
+/* XXX we should refactor directory.c to hand status->or_port around,
+ * so we can check it here rather than platform. */
+static int
+connection_dir_supports_tunnels(or_options_t *options, const char *platform)
+{
+  return options->TunnelDirConns && platform &&
+         tor_version_as_new_as(platform, "0.1.2.2-alpha");
+}
+
 /** Helper for directory_initiate_command_(router|trusted_dir): send the
  * command to a server whose address is <b>address</b>, whose IP is
  * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version is
@@ -376,8 +387,7 @@
 {
   dir_connection_t *conn;
   or_options_t *options = get_options();
-  int want_to_tunnel = options->TunnelDirConns && platform &&
-                       tor_version_as_new_as(platform, "0.1.2.2-alpha");
+  int want_to_tunnel = connection_dir_supports_tunnels(options, platform);
 
   tor_assert(address);
   tor_assert(addr);

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-01-03 05:12:26 UTC (rev 9248)
+++ tor/trunk/src/or/or.h	2007-01-03 06:33:03 UTC (rev 9249)
@@ -1663,6 +1663,8 @@
                                * same network zone in the same circuit. */
   int TunnelDirConns; /**< If true, use BEGIN_DIR rather than BEGIN when
                        * possible. */
+  int PreferTunneledDirConns; /**< If true, avoid dirservers that don't
+                               * support BEGIN_DIR, when possible. */
   int AllowNonRFC953Hostnames; /**< If true, we allow connections to hostnames
                                 * with weird characters. */
 } or_options_t;
@@ -2267,6 +2269,8 @@
 int connection_dir_process_inbuf(dir_connection_t *conn);
 int connection_dir_finished_flushing(dir_connection_t *conn);
 int connection_dir_finished_connecting(dir_connection_t *conn);
+int connection_dir_supports_tunnels(or_options_t *options,
+                                    const char *platform);
 void connection_dir_request_failed(dir_connection_t *conn);
 int dir_split_resource_into_fingerprints(const char *resource,
                                     smartlist_t *fp_out, int *compresseed_out,

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-01-03 05:12:26 UTC (rev 9248)
+++ tor/trunk/src/or/routerlist.c	2007-01-03 06:33:03 UTC (rev 9249)
@@ -20,9 +20,11 @@
 /* static function prototypes */
 static routerstatus_t *router_pick_directory_server_impl(int requireother,
                                                          int fascistfirewall,
+                                                         int prefer_tunnel,
                                                          int for_v2_directory);
 static routerstatus_t *router_pick_trusteddirserver_impl(
-                 authority_type_t type, int requireother, int fascistfirewall);
+                 authority_type_t type, int requireother,
+                 int fascistfirewall, int prefer_tunnel);
 static void mark_all_trusteddirservers_up(void);
 static int router_nickname_matches(routerinfo_t *router, const char *nickname);
 static void routerstatus_list_update_from_networkstatus(time_t now);
@@ -423,12 +425,13 @@
                              int retry_if_no_servers)
 {
   routerstatus_t *choice;
+  int prefer_tunnel = get_options()->PreferTunneledDirConns;
 
   if (!routerlist)
     return NULL;
 
   choice = router_pick_directory_server_impl(requireother, fascistfirewall,
-                                             for_v2_directory);
+                                             prefer_tunnel, for_v2_directory);
   if (choice || !retry_if_no_servers)
     return choice;
 
@@ -439,7 +442,7 @@
   mark_all_trusteddirservers_up();
   /* try again */
   choice = router_pick_directory_server_impl(requireother, fascistfirewall,
-                                             for_v2_directory);
+                                             prefer_tunnel, for_v2_directory);
   if (choice)
     return choice;
 
@@ -450,7 +453,7 @@
   }
   /* give it one last try */
   choice = router_pick_directory_server_impl(requireother, fascistfirewall,
-                                             for_v2_directory);
+                                             prefer_tunnel, for_v2_directory);
   return choice;
 }
 
@@ -486,17 +489,18 @@
                              int retry_if_no_servers)
 {
   routerstatus_t *choice;
+  int prefer_tunnel = get_options()->PreferTunneledDirConns;
 
-  choice = router_pick_trusteddirserver_impl(type,
-                                             requireother, fascistfirewall);
+  choice = router_pick_trusteddirserver_impl(type, requireother,
+                                fascistfirewall, prefer_tunnel);
   if (choice || !retry_if_no_servers)
     return choice;
 
   log_info(LD_DIR,
            "No trusted dirservers are reachable. Trying them all again.");
   mark_all_trusteddirservers_up();
-  return router_pick_trusteddirserver_impl(type,
-                                           requireother, fascistfirewall);
+  return router_pick_trusteddirserver_impl(type, requireother,
+                              fascistfirewall, prefer_tunnel);
 }
 
 /** How long do we avoid using a directory server after it's given us a 503? */
@@ -506,60 +510,81 @@
  * routerlist.  Don't pick an authority if any non-authorities are viable.
  * If <b>fascistfirewall</b>,
  * make sure the router we pick is allowed by our firewall options.
- * If <b>requireother</b>, it cannot be us.  If <b>for_v2_directory</b>,
+ * If <b>requireother</b>, it cannot be us. If <b>for_v2_directory</b>,
  * choose a directory server new enough to support the v2 directory
  * functionality.
+ * If <b>prefer_tunnel</b>, choose a directory server that is reachable
+ * and supports BEGIN_DIR cells, if possible.
+ * Try to avoid using servers that are overloaded (have returned 503
+ * recently).
  */
 static routerstatus_t *
 router_pick_directory_server_impl(int requireother, int fascistfirewall,
-                                  int for_v2_directory)
+                                  int prefer_tunnel, int for_v2_directory)
 {
   routerstatus_t *result;
-  smartlist_t *sl;
-  smartlist_t *overloaded;
-  smartlist_t *trusted;
+  smartlist_t *direct, *tunnel;
+  smartlist_t *trusted_direct, *trusted_tunnel;
+  smartlist_t *overloaded_direct, *overloaded_tunnel;
   time_t now = time(NULL);
 
   if (!routerstatus_list)
     return NULL;
 
+  direct = smartlist_create();
+  tunnel = smartlist_create();
+  trusted_direct = smartlist_create();
+  trusted_tunnel = smartlist_create();
+  overloaded_direct = smartlist_create();
+  overloaded_tunnel = smartlist_create();
+
   /* Find all the running dirservers we know about. */
-  sl = smartlist_create();
-  overloaded = smartlist_create();
-  trusted = smartlist_create();
   SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, _local_status,
   {
     routerstatus_t *status = &(_local_status->status);
     int is_trusted;
+    int is_overloaded = _local_status->last_dir_503_at + DIR_503_TIMEOUT > now;
     if (!status->is_running || !status->dir_port || !status->is_valid)
       continue;
     if (requireother && router_digest_is_me(status->identity_digest))
       continue;
-    if (fascistfirewall) {
-      if (!fascist_firewall_allows_address_dir(status->addr, status->dir_port))
-        continue;
-    }
     is_trusted = router_digest_is_trusted_dir(status->identity_digest);
     if (for_v2_directory && !(status->is_v2_dir || is_trusted))
       continue;
-    if (is_trusted) {
-      smartlist_add(trusted, status);
-    } else if (_local_status->last_dir_503_at + DIR_503_TIMEOUT > now) {
-      smartlist_add(overloaded, status);
-    } else {
-      smartlist_add(sl, status);
-    }
+    if (fascistfirewall &&
+        prefer_tunnel &&
+        status->version_supports_begindir &&
+        fascist_firewall_allows_address_or(status->addr, status->or_port))
+      smartlist_add(is_trusted ? trusted_tunnel :
+                      is_overloaded ? overloaded_tunnel : tunnel, status);
+    else if (!fascistfirewall || (fascistfirewall &&
+             fascist_firewall_allows_address_dir(status->addr,
+                                                 status->dir_port)))
+      smartlist_add(is_trusted ? trusted_direct :
+                      is_overloaded ? overloaded_direct : direct, status);
   });
 
-  if (smartlist_len(sl))
-    result = smartlist_choose(sl);
-  else if (smartlist_len(overloaded))
-    result = smartlist_choose(overloaded);
-  else
-    result = smartlist_choose(trusted);
-  smartlist_free(sl);
-  smartlist_free(overloaded);
-  smartlist_free(trusted);
+  if (smartlist_len(tunnel)) {
+    result = smartlist_choose(tunnel);
+  } else if (smartlist_len(overloaded_tunnel)) {
+    result = smartlist_choose(overloaded_tunnel);
+  } else if (trusted_tunnel) {
+    /* FFFF We don't distinguish between trusteds and overloaded trusteds
+     * yet. Maybe one day we should. */
+    result = smartlist_choose(trusted_tunnel);
+  } else if (smartlist_len(direct)) {
+    result = smartlist_choose(direct);
+  } else if (smartlist_len(overloaded_direct)) {
+    result = smartlist_choose(overloaded_direct);
+  } else {
+    result = smartlist_choose(trusted_direct);
+  }
+  smartlist_free(direct);
+  smartlist_free(tunnel);
+  smartlist_free(trusted_direct);
+  smartlist_free(trusted_tunnel);
+  smartlist_free(overloaded_direct);
+  smartlist_free(overloaded_tunnel);
   return result;
 }
 
@@ -571,22 +596,27 @@
  */
 static routerstatus_t *
 router_pick_trusteddirserver_impl(authority_type_t type,
-                                  int requireother, int fascistfirewall)
+                                  int requireother, int fascistfirewall,
+                                  int prefer_tunnel)
 {
-  smartlist_t *sl;
-  smartlist_t *overloaded;
-  routerinfo_t *me;
-  routerstatus_t *rs;
+  smartlist_t *direct, *tunnel;
+  smartlist_t *overloaded_direct, *overloaded_tunnel;
+  routerinfo_t *me = router_get_my_routerinfo();
+  routerstatus_t *result;
   time_t now = time(NULL);
-  sl = smartlist_create();
-  overloaded = smartlist_create();
-  me = router_get_my_routerinfo();
 
+  direct = smartlist_create();
+  tunnel = smartlist_create();
+  overloaded_direct = smartlist_create();
+  overloaded_tunnel = smartlist_create();
+
   if (!trusted_dir_servers)
     return NULL;
 
   SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
     {
+      int is_overloaded =
+          d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now;
       if (!d->is_running) continue;
       if (type == V1_AUTHORITY && !d->is_v1_authority)
         continue;
@@ -596,23 +626,35 @@
         continue;
       if (requireother && me && router_digest_is_me(d->digest))
           continue;
-      if (fascistfirewall) {
-        if (!fascist_firewall_allows_address_dir(d->addr, d->dir_port))
-          continue;
-      }
-      if (d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now)
-        smartlist_add(overloaded, &d->fake_status.status);
-      else
-        smartlist_add(sl, &d->fake_status.status);
+
+      if (fascistfirewall &&
+          prefer_tunnel &&
+          d->or_port &&
+          fascist_firewall_allows_address_or(d->addr, d->or_port))
+        smartlist_add(is_overloaded ? overloaded_tunnel : tunnel,
+                      &d->fake_status.status);
+      else if (!fascistfirewall || (fascistfirewall &&
+               fascist_firewall_allows_address_dir(d->addr,
+                                                   d->dir_port)))
+        smartlist_add(is_overloaded ? overloaded_direct : direct,
+                      &d->fake_status.status);
     });
 
-  if (smartlist_len(sl))
-    rs = smartlist_choose(sl);
-  else
-    rs = smartlist_choose(overloaded);
-  smartlist_free(sl);
-  smartlist_free(overloaded);
-  return rs;
+  if (smartlist_len(tunnel)) {
+    result = smartlist_choose(tunnel);
+  } else if (smartlist_len(overloaded_tunnel)) {
+    result = smartlist_choose(overloaded_tunnel);
+  } else if (smartlist_len(direct)) {
+    result = smartlist_choose(direct);
+  } else {
+    result = smartlist_choose(overloaded_direct);
+  }
+
+  smartlist_free(direct);
+  smartlist_free(tunnel);
+  smartlist_free(overloaded_direct);
+  smartlist_free(overloaded_tunnel);
+  return result;
 }
 
 /** Go through and mark the authoritative dirservers as up. */



More information about the tor-commits mailing list