[tor-commits] [tor/master] Set guard state on bridge descriptor fetches.

nickm at torproject.org nickm at torproject.org
Mon May 22 13:16:50 UTC 2017


commit 52498b8183a2ab1da525180ee76f704d8257ebc6
Author: George Kadianakis <desnacked at riseup.net>
Date:   Mon May 22 14:10:38 2017 +0300

    Set guard state on bridge descriptor fetches.
    
    We used to not set the guard state in launch_direct_bridge_descriptor_fetch().
    So when a bridge descriptor fetch failed, the guard subsystem would never
    learn about the fail (and hence the guard's reachability state would not
    be updated).
---
 changes/bug21969    |  3 +++
 src/or/bridges.c    |  6 ++++++
 src/or/directory.c  |  4 +---
 src/or/directory.h  |  3 +++
 src/or/entrynodes.c | 28 ++++++++++++++++++++++++++++
 src/or/entrynodes.h |  4 ++++
 6 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/changes/bug21969 b/changes/bug21969
new file mode 100644
index 0000000..9b116fc
--- /dev/null
+++ b/changes/bug21969
@@ -0,0 +1,3 @@
+  o Major bugfixes (entry guards):
+    - Don't block bootstrapping when a primary bridge is offline and we can't
+      get its descriptor. Fixes bug 21969; bugfix on 0.3.0.3-alpha.
diff --git a/src/or/bridges.c b/src/or/bridges.c
index ef0638c..0818fb0 100644
--- a/src/or/bridges.c
+++ b/src/or/bridges.c
@@ -547,6 +547,7 @@ static void
 launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
 {
   const or_options_t *options = get_options();
+  circuit_guard_state_t *guard_state = NULL;
 
   if (connection_get_by_type_addr_port_purpose(
       CONN_TYPE_DIR, &bridge->addr, bridge->port,
@@ -574,12 +575,17 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
   memcpy(&bridge_addrport.addr, &bridge->addr, sizeof(tor_addr_t));
   bridge_addrport.port = bridge->port;
 
+  guard_state = get_guard_state_for_bridge_desc_fetch(bridge->identity);
+
   directory_request_t *req =
     directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC);
   directory_request_set_or_addr_port(req, &bridge_addrport);
   directory_request_set_directory_id_digest(req, bridge->identity);
   directory_request_set_router_purpose(req, ROUTER_PURPOSE_BRIDGE);
   directory_request_set_resource(req, "authority.z");
+  if (guard_state) {
+    directory_request_set_guard_state(req, guard_state);
+  }
   directory_initiate_request(req);
   directory_request_free(req);
 }
diff --git a/src/or/directory.c b/src/or/directory.c
index ef74c0f..960d864 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -123,8 +123,6 @@ static int client_likes_consensus(const struct consensus_cache_entry_t *ent,
 
 static void connection_dir_close_consensus_fetches(
                    dir_connection_t *except_this_one, const char *resource);
-static void directory_request_set_guard_state(directory_request_t *req,
-                                       struct circuit_guard_state_t *state);
 
 /********* START VARIABLES **********/
 
@@ -1273,7 +1271,7 @@ directory_request_set_rend_query(directory_request_t *req,
 /** Set a static circuit_guard_state_t object to affliate with the request in
  * <b>req</b>.  This object will receive notification when the attempt to
  * connect to the guard either succeeds or fails. */
-static void
+void
 directory_request_set_guard_state(directory_request_t *req,
                                   circuit_guard_state_t *state)
 {
diff --git a/src/or/directory.h b/src/or/directory.h
index a015c70..9561ad7 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -47,6 +47,7 @@ int directory_must_use_begindir(const or_options_t *options);
  * directory we're going to ask for it, how we're going to contact that
  * directory, and (in some cases) what to do with it when we're done.
  */
+typedef struct circuit_guard_state_t circuit_guard_state_t;
 typedef struct directory_request_t directory_request_t;
 directory_request_t *directory_request_new(uint8_t dir_purpose);
 void directory_request_free(directory_request_t *req);
@@ -56,6 +57,8 @@ void directory_request_set_dir_addr_port(directory_request_t *req,
                                          const tor_addr_port_t *p);
 void directory_request_set_directory_id_digest(directory_request_t *req,
                                                const char *digest);
+void directory_request_set_guard_state(directory_request_t *req,
+                                       circuit_guard_state_t *state);
 void directory_request_set_router_purpose(directory_request_t *req,
                                           uint8_t router_purpose);
 void directory_request_set_indirection(directory_request_t *req,
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 7a27cd0..a0a595b 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -2926,6 +2926,34 @@ entry_guard_get_by_id_digest(const char *digest)
       get_guard_selection_info(), digest);
 }
 
+/** We are about to connect to bridge with identity <b>digest</b> to fetch its
+ *  descriptor. Create a new guard state for this connection and return it. */
+circuit_guard_state_t *
+get_guard_state_for_bridge_desc_fetch(const char *digest)
+{
+  circuit_guard_state_t *guard_state = NULL;
+  entry_guard_t *guard = NULL;
+
+  guard = entry_guard_get_by_id_digest_for_guard_selection(
+                                    get_guard_selection_info(), digest);
+  if (!guard) {
+    return NULL;
+  }
+
+  /* Update the guard last_tried_to_connect time since it's checked by the
+   * guard susbsystem. */
+  guard->last_tried_to_connect = approx_time();
+
+  /* Create the guard state */
+  guard_state = tor_malloc_zero(sizeof(circuit_guard_state_t));
+  guard_state->guard = entry_guard_handle_new(guard);
+  guard_state->state = GUARD_CIRC_STATE_USABLE_ON_COMPLETION;
+  guard_state->state_set_at = approx_time();
+  guard_state->restrictions = NULL;
+
+  return guard_state;
+}
+
 /** Release all storage held by <b>e</b>. */
 STATIC void
 entry_guard_free(entry_guard_t *e)
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 400a842..11b618b 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -323,6 +323,10 @@ const node_t *guards_choose_dirguard(circuit_guard_state_t **guard_state_out);
 entry_guard_t *entry_guard_get_by_id_digest_for_guard_selection(
     guard_selection_t *gs, const char *digest);
 entry_guard_t *entry_guard_get_by_id_digest(const char *digest);
+
+circuit_guard_state_t *
+get_guard_state_for_bridge_desc_fetch(const char *digest);
+
 void entry_guards_changed_for_guard_selection(guard_selection_t *gs);
 void entry_guards_changed(void);
 guard_selection_t * get_guard_selection_info(void);





More information about the tor-commits mailing list