From 7aa21920481fc4f0bdb159aeedf11582aa95dd01 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 10 Mar 2014 15:11:21 -0400 Subject: Fix our check for the "first" bridge descriptor. This is meant to be a better bug 9229 fix -- or at least, one more in tune with the intent of the original code, which calls router_retry_directory_downloads() only on the first bridge descriptor. --- src/or/entrynodes.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 37d5fb974..a08fda424 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -70,7 +70,9 @@ static int entry_guards_dirty = 0; 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 * @@ -982,7 +984,7 @@ node_can_handle_dirinfo(const node_t *node, dirinfo_type_t dirinfo) 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 @@ -990,13 +992,13 @@ choose_random_entry(cpath_build_state_t *state) 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(); @@ -1010,6 +1012,9 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, 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; @@ -1136,6 +1141,8 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, * *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; @@ -2166,7 +2173,7 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache) 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); @@ -2188,14 +2195,15 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache) * 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 @@ -2207,6 +2215,18 @@ any_bridge_descriptors_known(void) 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. */ -- cgit v1.2.3 From 6ab10a546663b509d189ce16645b11af0e83d41c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 8 Apr 2014 15:49:49 -0400 Subject: Make num_bridges_usable work properly. My first implementation was broken, since it returned "whether there is one bridge" rather than "how many bridges." Also, the implementation for the n_options_out feature in choose_random_entry_impl was completely broken due to a missing *. --- src/or/entrynodes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index a08fda424..da3521ecd 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1013,7 +1013,7 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, const int num_needed = decide_num_guards(options, for_directory); if (n_options_out) - n_options_out = 0; + *n_options_out = 0; if (chosen_exit) { nodelist_add_node_and_family(exit_family, chosen_exit); @@ -2215,8 +2215,8 @@ any_bridge_descriptors_known(void) return choose_random_entry(NULL) != NULL; } -/** Return the number of bridges that have descriptors that - * are marked with purpose 'bridge' and are running. +/** Return the number of bridges that have descriptors that are marked with + * purpose 'bridge' and are running. */ static int num_bridges_usable(void) @@ -2224,7 +2224,7 @@ 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 n_options; } /** Return 1 if there are any directory conns fetching bridge descriptors -- cgit v1.2.3