static void bridge_free(bridge_info_t *bridge);
static const node_t *choose_random_entry_impl(cpath_build_state_t *state,
int for_directory,
- dirinfo_type_t dirtype);
+ dirinfo_type_t dirtype,
+ int *n_options_out);
+static int num_bridges_usable(void);
/** Return the list of entry guards, creating it if necessary. */
const smartlist_t *
const node_t *
choose_random_entry(cpath_build_state_t *state)
{
- return choose_random_entry_impl(state, 0, 0);
+ return choose_random_entry_impl(state, 0, 0, NULL);
}
/** Pick a live (up and listed) directory guard from entry_guards for
const node_t *
choose_random_dirguard(dirinfo_type_t type)
{
- return choose_random_entry_impl(NULL, 1, type);
+ return choose_random_entry_impl(NULL, 1, type, NULL);
}
/** Helper for choose_random{entry,dirguard}. */
static const node_t *
choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
- dirinfo_type_t dirinfo_type)
+ dirinfo_type_t dirinfo_type, int *n_options_out)
{
const or_options_t *options = get_options();
smartlist_t *live_entry_guards = smartlist_new();
int need_descriptor = !for_directory;
const int num_needed = decide_num_guards(options, for_directory);
+ if (n_options_out)
+ n_options_out = 0;
+
if (chosen_exit) {
nodelist_add_node_and_family(exit_family, chosen_exit);
consider_exit_family = 1;
* *double*-weight our guard selection. */
node = smartlist_choose(live_entry_guards);
}
+ if (n_options_out)
+ *n_options_out = smartlist_len(live_entry_guards);
smartlist_free(live_entry_guards);
smartlist_free(exit_family);
return node;
tor_assert(ri);
tor_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
if (get_options()->UseBridges) {
- int first = !any_bridge_descriptors_known();
+ int first = num_bridges_usable() <= 1;
bridge_info_t *bridge = get_configured_bridge_by_routerinfo(ri);
time_t now = time(NULL);
router_set_status(ri->cache_info.identity_digest, 1);
* our entry node list */
entry_guard_register_connect_status(ri->cache_info.identity_digest,
1, 0, now);
- if (first)
+ if (first) {
routerlist_retry_directory_downloads(now);
+ }
}
}
}
-/** Return 1 if any of our entry guards have descriptors that
- * are marked with purpose 'bridge' and are running. Else return 0.
+/** Return the number of bridges that have descriptors that
+ * are marked with purpose 'bridge' and are running.
*
* We use this function to decide if we're ready to start building
* circuits through our bridges, or if we need to wait until the
return choose_random_entry(NULL) != NULL;
}
+/** Return the number of bridges that have descriptors that
+ * are marked with purpose 'bridge' and are running.
+ */
+static int
+num_bridges_usable(void)
+{
+ int n_options = 0;
+ tor_assert(get_options()->UseBridges);
+ (void) choose_random_entry_impl(NULL, 0, 0, &n_options);
+ return n_options == 1;
+}
+
/** Return 1 if there are any directory conns fetching bridge descriptors
* that aren't marked for close. We use this to guess if we should tell
* the controller that we have a problem. */