[tor-commits] [tor/master] Fix directory self-testing logic

nickm at torproject.org nickm at torproject.org
Wed Sep 12 20:29:13 UTC 2012


commit 5cbeb6080596c4442a19cffb56c1a68316b3014a
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Sep 12 10:15:58 2012 -0400

    Fix directory self-testing logic
    
    When I removed version_supports_begindir, I accidentally removed the
    mechanism we had been using to make a directory cache self-test its
    directory port.  This caused bug 6815, which caused 6814 (both in
    0.2.4.2-alpha).
    
    To fix this bug, I'm replacing the "anonymized_connection" argument to
    directory_initiate_command_* with an enumeration to say how indirectly
    to connect to a directory server.  (I don't want to reinstate the
    "version_supports_begindir" argument as "begindir_ok" or anything --
    these functions already take too many arguments.)
    
    For safety, I made sure that passing 0 and 1 for 'indirection' gives
    the same result as you would have gotten before -- just in case I
    missed any 0s or 1s.
---
 changes/bug6815        |    6 ++++++
 src/or/circuitbuild.c  |    2 +-
 src/or/directory.c     |   48 ++++++++++++++++++++++++++++++++----------------
 src/or/directory.h     |   20 +++++++++++++++++---
 src/or/networkstatus.c |    2 +-
 src/or/rendclient.c    |    3 ++-
 src/or/rendservice.c   |    3 ++-
 src/or/router.c        |    2 +-
 src/or/routerlist.c    |    2 +-
 9 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/changes/bug6815 b/changes/bug6815
new file mode 100644
index 0000000..d6a1233
--- /dev/null
+++ b/changes/bug6815
@@ -0,0 +1,6 @@
+  o Major bugfixes:
+    - Allow routers to correctly detect their own DirPorts as running.
+      When we removed support for versions_supports_begindir, we also
+      accidentally removed the mechanism we used to self-test our
+      DirPort. Diagnosed with help from kargig. Fixes bugs 6814 and
+      6815; bugfix on 0.2.4.2-alpha.
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index fe327ca..4384e29 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -5479,7 +5479,7 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
                              bridge->identity,
                              DIR_PURPOSE_FETCH_SERVERDESC,
                              ROUTER_PURPOSE_BRIDGE,
-                             0, "authority.z", NULL, 0, 0);
+                             DIRIND_ONEHOP, "authority.z", NULL, 0, 0);
   tor_free(address);
 }
 
diff --git a/src/or/directory.c b/src/or/directory.c
index d22a8b8..effccc5 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -91,7 +91,7 @@ static void directory_initiate_command_rend(const char *address,
                                             const char *digest,
                                             uint8_t dir_purpose,
                                             uint8_t router_purpose,
-                                            int anonymized_connection,
+                                            dir_indirection_t indirection,
                                             const char *resource,
                                             const char *payload,
                                             size_t payload_len,
@@ -432,7 +432,8 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
                                    ri->cache_info.identity_digest,
                                    dir_purpose,
                                    router_purpose,
-                                   0, resource, NULL, 0, if_modified_since);
+                                   DIRIND_ONEHOP,
+                                   resource, NULL, 0, if_modified_since);
       } else
         log_notice(LD_DIR, "Ignoring directory request, since no bridge "
                            "nodes are available yet.");
@@ -493,13 +494,15 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
     }
   }
 
-  if (rs)
+  if (rs) {
+    const dir_indirection_t indirection =
+      get_via_tor ? DIRIND_ANONYMOUS : DIRIND_ONEHOP;
     directory_initiate_command_routerstatus(rs, dir_purpose,
                                             router_purpose,
-                                            get_via_tor,
+                                            indirection,
                                             resource, NULL, 0,
                                             if_modified_since);
-  else {
+  } else {
     log_notice(LD_DIR,
                "While fetching directory info, "
                "no running dirservers known. Will try again later. "
@@ -531,17 +534,25 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
         continue;
       rs = &ds->fake_status;
       directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose,
-                                              0, resource, NULL, 0, 0);
+                                              DIRIND_ONEHOP, resource, NULL,
+                                              0, 0);
   } SMARTLIST_FOREACH_END(ds);
 }
 
+/** Return true iff <b>ind</b> requires a multihop circuit. */
+static int
+dirind_is_anon(dir_indirection_t ind)
+{
+  return ind == DIRIND_ANON_DIRPORT || ind == DIRIND_ANONYMOUS;
+}
+
 /** Same as directory_initiate_command_routerstatus(), but accepts
  * rendezvous data to fetch a hidden service descriptor. */
 void
 directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
                                              uint8_t dir_purpose,
                                              uint8_t router_purpose,
-                                             int anonymized_connection,
+                                             dir_indirection_t indirection,
                                              const char *resource,
                                              const char *payload,
                                              size_t payload_len,
@@ -554,6 +565,7 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
   struct in_addr in;
   const char *address;
   tor_addr_t addr;
+  const int anonymized_connection = dirind_is_anon(indirection);
   node = node_get_by_id(status->identity_digest);
 
   if (!node && anonymized_connection) {
@@ -585,7 +597,7 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
                              status->or_port, status->dir_port,
                              status->identity_digest,
                              dir_purpose, router_purpose,
-                             anonymized_connection, resource,
+                             indirection, resource,
                              payload, payload_len, if_modified_since,
                              rend_query);
 }
@@ -608,7 +620,7 @@ void
 directory_initiate_command_routerstatus(const routerstatus_t *status,
                                         uint8_t dir_purpose,
                                         uint8_t router_purpose,
-                                        int anonymized_connection,
+                                        dir_indirection_t indirection,
                                         const char *resource,
                                         const char *payload,
                                         size_t payload_len,
@@ -616,7 +628,7 @@ directory_initiate_command_routerstatus(const routerstatus_t *status,
 {
   directory_initiate_command_routerstatus_rend(status, dir_purpose,
                                           router_purpose,
-                                          anonymized_connection, resource,
+                                          indirection, resource,
                                           payload, payload_len,
                                           if_modified_since, NULL);
 }
@@ -818,11 +830,13 @@ static int
 directory_command_should_use_begindir(const or_options_t *options,
                                       const tor_addr_t *addr,
                                       int or_port, uint8_t router_purpose,
-                                      int anonymized_connection)
+                                      dir_indirection_t indirection)
 {
   if (!or_port)
     return 0; /* We don't know an ORPort -- no chance. */
-  if (!anonymized_connection)
+  if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT)
+    return 0;
+  if (indirection == DIRIND_ONEHOP)
     if (!fascist_firewall_allows_address_or(addr, or_port) ||
         directory_fetches_from_authorities(options))
       return 0; /* We're firewalled or are acting like a relay -- also no. */
@@ -842,13 +856,13 @@ directory_initiate_command(const char *address, const tor_addr_t *_addr,
                            uint16_t or_port, uint16_t dir_port,
                            const char *digest,
                            uint8_t dir_purpose, uint8_t router_purpose,
-                           int anonymized_connection, const char *resource,
+                           dir_indirection_t indirection, const char *resource,
                            const char *payload, size_t payload_len,
                            time_t if_modified_since)
 {
   directory_initiate_command_rend(address, _addr, or_port, dir_port,
                              digest, dir_purpose,
-                             router_purpose, anonymized_connection,
+                             router_purpose, indirection,
                              resource, payload, payload_len,
                              if_modified_since, NULL);
 }
@@ -874,7 +888,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
                                 uint16_t or_port, uint16_t dir_port,
                                 const char *digest,
                                 uint8_t dir_purpose, uint8_t router_purpose,
-                                int anonymized_connection,
+                                dir_indirection_t indirection,
                                 const char *resource,
                                 const char *payload, size_t payload_len,
                                 time_t if_modified_since,
@@ -884,7 +898,8 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
   const or_options_t *options = get_options();
   int socket_error = 0;
   int use_begindir = directory_command_should_use_begindir(options, _addr,
-                       or_port, router_purpose, anonymized_connection);
+                                     or_port, router_purpose, indirection);
+  const int anonymized_connection = dirind_is_anon(indirection);
   tor_addr_t addr;
 
   tor_assert(address);
@@ -930,6 +945,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
   conn->_base.state = DIR_CONN_STATE_CONNECTING;
 
   /* decide whether we can learn our IP address from this conn */
+  /* XXXX This is a bad name for this field now. */
   conn->dirconn_direct = !anonymized_connection;
 
   /* copy rendezvous data, if any */
diff --git a/src/or/directory.h b/src/or/directory.h
index 14444c0..7029abc 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -22,10 +22,24 @@ void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
 void directory_get_from_all_authorities(uint8_t dir_purpose,
                                         uint8_t router_purpose,
                                         const char *resource);
+
+/** Enumeration of ways to connect to a directory server */
+typedef enum {
+  /** Default: connect over a one-hop Tor circuit but fall back to direct
+   * connection */
+  DIRIND_ONEHOP=0,
+  /** Connect over a multi-hop anonymizing Tor circuit */
+  DIRIND_ANONYMOUS=1,
+  /** Conncet to the DirPort directly */
+  DIRIND_DIRECT_CONN,
+  /** Connect over a multi-hop anonymizing Tor circuit to our dirport */
+  DIRIND_ANON_DIRPORT,
+} dir_indirection_t;
+
 void directory_initiate_command_routerstatus(const routerstatus_t *status,
                                              uint8_t dir_purpose,
                                              uint8_t router_purpose,
-                                             int anonymized_connection,
+                                             dir_indirection_t indirection,
                                              const char *resource,
                                              const char *payload,
                                              size_t payload_len,
@@ -33,7 +47,7 @@ void directory_initiate_command_routerstatus(const routerstatus_t *status,
 void directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
                                                   uint8_t dir_purpose,
                                                   uint8_t router_purpose,
-                                                  int anonymized_connection,
+                                                  dir_indirection_t indirection,
                                                   const char *resource,
                                                   const char *payload,
                                                   size_t payload_len,
@@ -53,7 +67,7 @@ void directory_initiate_command(const char *address, const tor_addr_t *addr,
                                 uint16_t or_port, uint16_t dir_port,
                                 const char *digest,
                                 uint8_t dir_purpose, uint8_t router_purpose,
-                                int anonymized_connection,
+                                dir_indirection_t indirection,
                                 const char *resource,
                                 const char *payload, size_t payload_len,
                                 time_t if_modified_since);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 0df5c4e..ff31f82 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1168,7 +1168,7 @@ update_v2_networkstatus_cache_downloads(time_t now)
          directory_initiate_command_routerstatus(
                &ds->fake_status, DIR_PURPOSE_FETCH_V2_NETWORKSTATUS,
                ROUTER_PURPOSE_GENERAL,
-               0, /* Not private */
+               DIRIND_ONEHOP,
                resource,
                NULL, 0 /* No payload. */,
                0 /* No I-M-S. */);
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 5b3b92e..0b6d82b 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -617,7 +617,8 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
   directory_initiate_command_routerstatus_rend(hs_dir,
                                           DIR_PURPOSE_FETCH_RENDDESC_V2,
                                           ROUTER_PURPOSE_GENERAL,
-                                          !tor2web_mode, desc_id_base32,
+                                   tor2web_mode?DIRIND_ONEHOP:DIRIND_ANONYMOUS,
+                                          desc_id_base32,
                                           NULL, 0, 0,
                                           rend_query);
   log_info(LD_REND, "Sending fetch request for v2 descriptor for "
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index bd8b13a..394831f 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -2782,7 +2782,8 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
       directory_initiate_command_routerstatus(hs_dir,
                                               DIR_PURPOSE_UPLOAD_RENDDESC_V2,
                                               ROUTER_PURPOSE_GENERAL,
-                                              1, NULL, desc->desc_str,
+                                              DIRIND_ANONYMOUS, NULL,
+                                              desc->desc_str,
                                               strlen(desc->desc_str), 0);
       base32_encode(desc_id_base32, sizeof(desc_id_base32),
                     desc->desc_id, DIGEST_LEN);
diff --git a/src/or/router.c b/src/or/router.c
index 4e1eb2d..a26dccc 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -957,7 +957,7 @@ consider_testing_reachability(int test_or, int test_dir)
                                me->cache_info.identity_digest,
                                DIR_PURPOSE_FETCH_SERVERDESC,
                                ROUTER_PURPOSE_GENERAL,
-                               1, "authority.z", NULL, 0, 0);
+                               DIRIND_ANON_DIRPORT, "authority.z", NULL, 0, 0);
   }
 }
 
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 41abc4c..214c086 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -4326,7 +4326,7 @@ initiate_descriptor_downloads(const routerstatus_t *source,
     /* We know which authority we want. */
     directory_initiate_command_routerstatus(source, purpose,
                                             ROUTER_PURPOSE_GENERAL,
-                                            0, /* not private */
+                                            DIRIND_ONEHOP,
                                             resource, NULL, 0, 0);
   } else {
     directory_get_from_dirserver(purpose, ROUTER_PURPOSE_GENERAL, resource,





More information about the tor-commits mailing list