|  | @@ -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;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /** Return 1 if we have at least one descriptor for an entry guard
 | 
	
		
			
				|  |  |   * (bridge or member of EntryNodes) and all descriptors we know are
 | 
	
		
			
				|  |  |   * down. Else return 0. If <b>act</b> is 1, then mark the down guards
 |