summaryrefslogtreecommitdiff
path: root/src/or/entrynodes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/entrynodes.c')
-rw-r--r--src/or/entrynodes.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 2cbc8019d4..67b0259243 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -814,7 +814,7 @@ STATIC entry_guard_t *
entry_guard_add_to_sample(guard_selection_t *gs,
const node_t *node)
{
- log_info(LD_GUARD, "Adding %s as to the entry guard sample set.",
+ log_info(LD_GUARD, "Adding %s to the entry guard sample set.",
node_describe(node));
/* make sure that the guard is not already sampled. */
@@ -1841,7 +1841,7 @@ entry_guards_update_primary(guard_selection_t *gs)
bool_eq(guard->is_primary,
smartlist_contains(new_primary_guards, guard)));
});
-#endif
+#endif /* 1 */
int any_change = 0;
if (smartlist_len(gs->primary_entry_guards) !=
@@ -3136,20 +3136,34 @@ entry_list_is_constrained(const or_options_t *options)
}
/** Return the number of bridges that have descriptors that are marked with
- * purpose 'bridge' and are running.
- */
-int
-num_bridges_usable(void)
+ * purpose 'bridge' and are running. If use_maybe_reachable is
+ * true, include bridges that might be reachable in the count.
+ * Otherwise, if it is false, only include bridges that have recently been
+ * found running in the count.
+ *
+ * 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
+ * directory "server/authority" requests finish. */
+MOCK_IMPL(int,
+num_bridges_usable,(int use_maybe_reachable))
{
int n_options = 0;
- tor_assert(get_options()->UseBridges);
+ if (BUG(!get_options()->UseBridges)) {
+ return 0;
+ }
guard_selection_t *gs = get_guard_selection_info();
- tor_assert(gs->type == GS_TYPE_BRIDGE);
+ if (BUG(gs->type != GS_TYPE_BRIDGE)) {
+ return 0;
+ }
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
+ /* Definitely not usable */
if (guard->is_reachable == GUARD_REACHABLE_NO)
continue;
+ /* If we want to be really sure the bridges will work, skip maybes */
+ if (!use_maybe_reachable && guard->is_reachable == GUARD_REACHABLE_MAYBE)
+ continue;
if (tor_digest_is_zero(guard->identity))
continue;
const node_t *node = node_get_by_id(guard->identity);
@@ -3538,15 +3552,20 @@ guards_retry_optimistic(const or_options_t *options)
}
/**
- * Return true iff we know enough directory information to construct
- * circuits through all of the primary guards we'd currently use.
- */
-int
-guard_selection_have_enough_dir_info_to_build_circuits(guard_selection_t *gs)
+ * Check if we are missing any crucial dirinfo for the guard subsystem to
+ * work. Return NULL if everything went well, otherwise return a newly
+ * allocated string with an informative error message. In the latter case, use
+ * the genreal descriptor information <b>using_mds</b>, <b>num_present</b> and
+ * <b>num_usable</b> to improve the error message. */
+char *
+guard_selection_get_err_str_if_dir_info_missing(guard_selection_t *gs,
+ int using_mds,
+ int num_present, int num_usable)
{
if (!gs->primary_guards_up_to_date)
entry_guards_update_primary(gs);
+ char *ret_str = NULL;
int n_missing_descriptors = 0;
int n_considered = 0;
int num_primary_to_check;
@@ -3568,16 +3587,30 @@ guard_selection_have_enough_dir_info_to_build_circuits(guard_selection_t *gs)
break;
} SMARTLIST_FOREACH_END(guard);
- return n_missing_descriptors == 0;
+ /* If we are not missing any descriptors, return NULL. */
+ if (!n_missing_descriptors) {
+ return NULL;
+ }
+
+ /* otherwise return a helpful error string */
+ tor_asprintf(&ret_str, "We're missing descriptors for %d/%d of our "
+ "primary entry guards (total %sdescriptors: %d/%d).",
+ n_missing_descriptors, num_primary_to_check,
+ using_mds?"micro":"", num_present, num_usable);
+
+ return ret_str;
}
/** As guard_selection_have_enough_dir_info_to_build_circuits, but uses
* the default guard selection. */
-int
-entry_guards_have_enough_dir_info_to_build_circuits(void)
-{
- return guard_selection_have_enough_dir_info_to_build_circuits(
- get_guard_selection_info());
+char *
+entry_guards_get_err_str_if_dir_info_missing(int using_mds,
+ int num_present, int num_usable)
+{
+ return guard_selection_get_err_str_if_dir_info_missing(
+ get_guard_selection_info(),
+ using_mds,
+ num_present, num_usable);
}
/** Free one guard selection context */