|
@@ -3209,8 +3209,6 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri,
|
|
|
char buf[HEX_DIGEST_LEN+1];
|
|
|
int changed = 0;
|
|
|
|
|
|
- tor_assert(options);
|
|
|
-
|
|
|
*reason = NULL;
|
|
|
|
|
|
/* Do we want to mark this guard as bad? */
|
|
@@ -3468,9 +3466,8 @@ add_an_entry_guard(routerinfo_t *chosen, int reset_status)
|
|
|
/** If the use of entry guards is configured, choose more entry guards
|
|
|
* until we have enough in the list. */
|
|
|
static void
|
|
|
-pick_entry_guards(void)
|
|
|
+pick_entry_guards(or_options_t *options)
|
|
|
{
|
|
|
- or_options_t *options = get_options();
|
|
|
int changed = 0;
|
|
|
|
|
|
tor_assert(entry_guards);
|
|
@@ -3502,10 +3499,9 @@ entry_guard_free(entry_guard_t *e)
|
|
|
* or which was selected by a version of Tor that's known to select
|
|
|
* entry guards badly. */
|
|
|
static int
|
|
|
-remove_obsolete_entry_guards(void)
|
|
|
+remove_obsolete_entry_guards(time_t now)
|
|
|
{
|
|
|
int changed = 0, i;
|
|
|
- time_t now = time(NULL);
|
|
|
|
|
|
for (i = 0; i < smartlist_len(entry_guards); ++i) {
|
|
|
entry_guard_t *entry = smartlist_get(entry_guards, i);
|
|
@@ -3565,11 +3561,10 @@ remove_obsolete_entry_guards(void)
|
|
|
* long that we don't think they'll come up again. Return 1 if we
|
|
|
* removed any, or 0 if we did nothing. */
|
|
|
static int
|
|
|
-remove_dead_entry_guards(void)
|
|
|
+remove_dead_entry_guards(time_t now)
|
|
|
{
|
|
|
char dbuf[HEX_DIGEST_LEN+1];
|
|
|
char tbuf[ISO_TIME_LEN+1];
|
|
|
- time_t now = time(NULL);
|
|
|
int i;
|
|
|
int changed = 0;
|
|
|
|
|
@@ -3604,23 +3599,18 @@ remove_dead_entry_guards(void)
|
|
|
* think that things are unlisted.
|
|
|
*/
|
|
|
void
|
|
|
-entry_guards_compute_status(void)
|
|
|
+entry_guards_compute_status(or_options_t *options, time_t now)
|
|
|
{
|
|
|
- time_t now;
|
|
|
int changed = 0;
|
|
|
int severity = LOG_DEBUG;
|
|
|
- or_options_t *options;
|
|
|
digestmap_t *reasons;
|
|
|
|
|
|
if (! entry_guards)
|
|
|
return;
|
|
|
|
|
|
- options = get_options();
|
|
|
if (options->EntryNodes) /* reshuffle the entry guard list if needed */
|
|
|
entry_nodes_should_be_added();
|
|
|
|
|
|
- now = time(NULL);
|
|
|
-
|
|
|
reasons = digestmap_new();
|
|
|
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry)
|
|
|
{
|
|
@@ -3636,7 +3626,7 @@ entry_guards_compute_status(void)
|
|
|
}
|
|
|
SMARTLIST_FOREACH_END(entry);
|
|
|
|
|
|
- if (remove_dead_entry_guards())
|
|
|
+ if (remove_dead_entry_guards(now))
|
|
|
changed = 1;
|
|
|
|
|
|
severity = changed ? LOG_DEBUG : LOG_INFO;
|
|
@@ -3801,9 +3791,8 @@ entry_nodes_should_be_added(void)
|
|
|
/** Add all nodes in EntryNodes that aren't currently guard nodes to the list
|
|
|
* of guard nodes, at the front. */
|
|
|
static void
|
|
|
-entry_guards_prepend_from_config(void)
|
|
|
+entry_guards_prepend_from_config(or_options_t *options)
|
|
|
{
|
|
|
- or_options_t *options = get_options();
|
|
|
smartlist_t *entry_routers, *entry_fps;
|
|
|
smartlist_t *old_entry_guards_on_list, *old_entry_guards_not_on_list;
|
|
|
tor_assert(entry_guards);
|
|
@@ -3931,11 +3920,11 @@ choose_random_entry(cpath_build_state_t *state)
|
|
|
entry_guards = smartlist_create();
|
|
|
|
|
|
if (should_add_entry_nodes)
|
|
|
- entry_guards_prepend_from_config();
|
|
|
+ entry_guards_prepend_from_config(options);
|
|
|
|
|
|
if (!entry_list_is_constrained(options) &&
|
|
|
smartlist_len(entry_guards) < options->NumEntryGuards)
|
|
|
- pick_entry_guards();
|
|
|
+ pick_entry_guards(options);
|
|
|
|
|
|
retry:
|
|
|
smartlist_clear(live_entry_guards);
|
|
@@ -4164,7 +4153,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
|
|
|
entry_guards_dirty = 0;
|
|
|
/* XXX022 hand new_entry_guards to this func, and move it up a
|
|
|
* few lines, so we don't have to re-dirty it */
|
|
|
- if (remove_obsolete_entry_guards())
|
|
|
+ if (remove_obsolete_entry_guards(now))
|
|
|
entry_guards_dirty = 1;
|
|
|
}
|
|
|
digestmap_free(added_by, _tor_free);
|
|
@@ -4469,9 +4458,8 @@ retry_bridge_descriptor_fetch_directly(const char *digest)
|
|
|
* descriptor, fetch a new copy of its descriptor -- either directly
|
|
|
* from the bridge or via a bridge authority. */
|
|
|
void
|
|
|
-fetch_bridge_descriptors(time_t now)
|
|
|
+fetch_bridge_descriptors(or_options_t *options, time_t now)
|
|
|
{
|
|
|
- or_options_t *options = get_options();
|
|
|
int num_bridge_auths = get_n_authorities(BRIDGE_AUTHORITY);
|
|
|
int ask_bridge_directly;
|
|
|
int can_use_bridge_authority;
|
|
@@ -4595,26 +4583,38 @@ any_pending_bridge_descriptor_fetches(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/** Return 1 if we have at least one descriptor for a bridge and
|
|
|
- * all descriptors we know are down. Else return 0. If <b>act</b> is
|
|
|
- * 1, then mark the down bridges up; else just observe and report. */
|
|
|
+/** 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
|
|
|
+ * up; else just observe and report. */
|
|
|
static int
|
|
|
-bridges_retry_helper(int act)
|
|
|
+entries_retry_helper(or_options_t *options, int act)
|
|
|
{
|
|
|
routerinfo_t *ri;
|
|
|
int any_known = 0;
|
|
|
int any_running = 0;
|
|
|
+ int purpose = options->UseBridges ?
|
|
|
+ ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
|
|
|
if (!entry_guards)
|
|
|
entry_guards = smartlist_create();
|
|
|
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
|
|
|
{
|
|
|
ri = router_get_by_digest(e->identity);
|
|
|
- if (ri && ri->purpose == ROUTER_PURPOSE_BRIDGE) {
|
|
|
+ if (ri && ri->purpose == purpose) {
|
|
|
any_known = 1;
|
|
|
if (ri->is_running)
|
|
|
- any_running = 1; /* some bridge is both known and running */
|
|
|
- else if (act) { /* mark it for retry */
|
|
|
- ri->is_running = 1;
|
|
|
+ any_running = 1; /* some entry is both known and running */
|
|
|
+ else if (act) {
|
|
|
+ /* Mark all current connections to this OR as unhealthy, since
|
|
|
+ * otherwise there could be one that started 30 seconds
|
|
|
+ * ago, and in 30 seconds it will time out, causing us to mark
|
|
|
+ * the node down and undermine the retry attempt. We mark even
|
|
|
+ * the established conns, since if the network just came back
|
|
|
+ * we'll want to attach circuits to fresh conns. */
|
|
|
+ connection_or_set_bad_connections(ri->cache_info.identity_digest, 1);
|
|
|
+
|
|
|
+ /* mark this entry node for retry */
|
|
|
+ router_set_status(ri->cache_info.identity_digest, 1);
|
|
|
e->can_retry = 1;
|
|
|
e->bad_since = 0;
|
|
|
}
|
|
@@ -4625,19 +4625,21 @@ bridges_retry_helper(int act)
|
|
|
return any_known && !any_running;
|
|
|
}
|
|
|
|
|
|
-/** Do we know any descriptors for our bridges, and are they all
|
|
|
- * down? */
|
|
|
+/** Do we know any descriptors for our bridges / entrynodes, and are
|
|
|
+ * all the ones we have descriptors for down? */
|
|
|
int
|
|
|
-bridges_known_but_down(void)
|
|
|
+entries_known_but_down(or_options_t *options)
|
|
|
{
|
|
|
- return bridges_retry_helper(0);
|
|
|
+ tor_assert(entry_list_is_constrained(options));
|
|
|
+ return entries_retry_helper(options, 0);
|
|
|
}
|
|
|
|
|
|
-/** Mark all down known bridges up. */
|
|
|
+/** Mark all down known bridges / entrynodes up. */
|
|
|
void
|
|
|
-bridges_retry_all(void)
|
|
|
+entries_retry_all(or_options_t *options)
|
|
|
{
|
|
|
- bridges_retry_helper(1);
|
|
|
+ tor_assert(entry_list_is_constrained(options));
|
|
|
+ entries_retry_helper(options, 1);
|
|
|
}
|
|
|
|
|
|
/** Release all storage held by the list of entry guards and related
|