Commit 6009c891 authored by George Kadianakis's avatar George Kadianakis
Browse files

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).
parent e102ad60
Loading
Loading
Loading
Loading

changes/bug21969

0 → 100644
+3 −0
Original line number Diff line number Diff line
  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.
+5 −1
Original line number Diff line number Diff line
@@ -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,
@@ -570,12 +571,15 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
    return;
  }

  guard_state = get_guard_state_for_bridge_desc_fetch(bridge->identity);

  directory_initiate_command(&bridge->addr, bridge->port,
                             NULL, 0, /*no dirport*/
                             bridge->identity,
                             DIR_PURPOSE_FETCH_SERVERDESC,
                             ROUTER_PURPOSE_BRIDGE,
                             DIRIND_ONEHOP, "authority.z", NULL, 0, 0, NULL);
                             DIRIND_ONEHOP, "authority.z", NULL, 0, 0,
                             guard_state);
}

/** Fetching the bridge descriptor from the bridge authority returned a
+28 −0
Original line number Diff line number Diff line
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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);