diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-11 17:04:21 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-11 17:04:21 -0400 |
commit | 597da4989e6f6a9c1a12ad3197dd6532b1a80035 (patch) | |
tree | b31fd77d6217384300e96f2640cd924420218a40 | |
parent | b55e31aeb453875728295de664383b12e76fefdc (diff) | |
parent | d82384658d77189cbfae9db90e6ec14af6572b5e (diff) | |
download | tor-597da4989e6f6a9c1a12ad3197dd6532b1a80035.tar.gz tor-597da4989e6f6a9c1a12ad3197dd6532b1a80035.zip |
Merge branch 'bug2798'
-rw-r--r-- | changes/bug2798 | 10 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 63 |
2 files changed, 49 insertions, 24 deletions
diff --git a/changes/bug2798 b/changes/bug2798 new file mode 100644 index 0000000000..8fd2243b04 --- /dev/null +++ b/changes/bug2798 @@ -0,0 +1,10 @@ + o Major bugfixes: + - When configuring a large set of nodes in EntryNodes (as with + 'EntryNodes {cc}' or 'EntryNodes 1.1.1.1/16'), choose only a + random subset to be guards, and choose them in random + order. Bugfix on 0.2.3.1-alpha; fixes bug 2798. + + o Minor features: + - When configuring a large set of nodes in EntryNodes, and there are + enough of them listed as Guard so that we don't need to consider + the non-guard entries, prefer the ones listed with the Guard flag. diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index abf6115cde..4397aa5c13 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -3642,7 +3642,7 @@ control_event_guard_deferred(void) * already in our entry_guards list, put it at the *beginning*. * Else, put the one we pick at the end of the list. */ static const node_t * -add_an_entry_guard(const node_t *chosen, int reset_status) +add_an_entry_guard(const node_t *chosen, int reset_status, int prepend) { const node_t *node; entry_guard_t *entry; @@ -3674,9 +3674,9 @@ add_an_entry_guard(const node_t *chosen, int reset_status) * this guard. For details, see the Jan 2010 or-dev thread. */ entry->chosen_on_date = time(NULL) - crypto_rand_int(3600*24*30); entry->chosen_by_version = tor_strdup(VERSION); - if (chosen) /* prepend */ + if (prepend) smartlist_insert(entry_guards, 0, entry); - else /* append */ + else smartlist_add(entry_guards, entry); control_event_guard(entry->nickname, entry->identity, "NEW"); control_event_guard_deferred(); @@ -3694,7 +3694,7 @@ pick_entry_guards(const or_options_t *options) tor_assert(entry_guards); while (num_live_entry_guards() < options->NumEntryGuards) { - if (!add_an_entry_guard(NULL, 0)) + if (!add_an_entry_guard(NULL, 0, 0)) break; changed = 1; } @@ -4007,12 +4007,12 @@ entry_nodes_should_be_added(void) should_add_entry_nodes = 1; } -/** Add all nodes in EntryNodes that aren't currently guard nodes to the list - * of guard nodes, at the front. */ +/** Adjust the entry guards list so that it only contains entries from + * EntryNodes, adding new entries from EntryNodes to the list as needed. */ static void -entry_guards_prepend_from_config(const or_options_t *options) +entry_guards_set_from_config(const or_options_t *options) { - smartlist_t *entry_nodes, *entry_fps; + smartlist_t *entry_nodes, *worse_entry_nodes, *entry_fps; smartlist_t *old_entry_guards_on_list, *old_entry_guards_not_on_list; tor_assert(entry_guards); @@ -4033,18 +4033,13 @@ entry_guards_prepend_from_config(const or_options_t *options) } entry_nodes = smartlist_create(); + worse_entry_nodes = smartlist_create(); entry_fps = smartlist_create(); old_entry_guards_on_list = smartlist_create(); old_entry_guards_not_on_list = smartlist_create(); /* Split entry guards into those on the list and those not. */ - /* XXXX023 Now that we allow countries and IP ranges in EntryNodes, this is - * potentially an enormous list. For now, we disable such values for - * EntryNodes in options_validate(); really, this wants a better solution. - * Perhaps we should do this calculation once whenever the list of routers - * changes or the entrynodes setting changes. - */ routerset_get_all_nodes(entry_nodes, options->EntryNodes, options->ExcludeNodes, 0); SMARTLIST_FOREACH(entry_nodes, const node_t *,node, @@ -4057,27 +4052,47 @@ entry_guards_prepend_from_config(const or_options_t *options) smartlist_add(old_entry_guards_not_on_list, e); }); - /* Remove all currently configured entry guards from entry_routers. */ - SMARTLIST_FOREACH(entry_nodes, const node_t *, node, { + /* Remove all currently configured guard nodes, excluded nodes, unreachable + * nodes, or non-Guard nodes from entry_nodes. */ + SMARTLIST_FOREACH_BEGIN(entry_nodes, const node_t *, node) { if (is_an_entry_guard(node->identity)) { SMARTLIST_DEL_CURRENT(entry_nodes, node); + continue; + } else if (routerset_contains_node(options->ExcludeNodes, node)) { + SMARTLIST_DEL_CURRENT(entry_nodes, node); + continue; + } else if (!fascist_firewall_allows_node(node)) { + SMARTLIST_DEL_CURRENT(entry_nodes, node); + continue; + } else if (! node->is_possible_guard) { + smartlist_add(worse_entry_nodes, (node_t*)node); + SMARTLIST_DEL_CURRENT(entry_nodes, node); } - }); + } SMARTLIST_FOREACH_END(node); /* Now build the new entry_guards list. */ smartlist_clear(entry_guards); /* First, the previously configured guards that are in EntryNodes. */ smartlist_add_all(entry_guards, old_entry_guards_on_list); + /* Next, scramble the rest of EntryNodes, putting the guards first. */ + smartlist_shuffle(entry_nodes); + smartlist_shuffle(worse_entry_nodes); + smartlist_add_all(entry_nodes, worse_entry_nodes); + /* Next, the rest of EntryNodes */ - SMARTLIST_FOREACH(entry_nodes, const node_t *, node, { - add_an_entry_guard(node, 0); - }); + SMARTLIST_FOREACH_BEGIN(entry_nodes, const node_t *, node) { + add_an_entry_guard(node, 0, 0); + if (smartlist_len(entry_guards) > options->NumEntryGuards * 10) + break; + } SMARTLIST_FOREACH_END(node); + log_notice(LD_GENERAL, "%d entries in guards", smartlist_len(entry_guards)); /* Finally, free the remaining previously configured guards that are not in * EntryNodes. */ SMARTLIST_FOREACH(old_entry_guards_not_on_list, entry_guard_t *, e, entry_guard_free(e)); smartlist_free(entry_nodes); + smartlist_free(worse_entry_nodes); smartlist_free(entry_fps); smartlist_free(old_entry_guards_on_list); smartlist_free(old_entry_guards_not_on_list); @@ -4125,7 +4140,7 @@ choose_random_entry(cpath_build_state_t *state) entry_guards = smartlist_create(); if (should_add_entry_nodes) - entry_guards_prepend_from_config(options); + entry_guards_set_from_config(options); if (!entry_list_is_constrained(options) && smartlist_len(entry_guards) < options->NumEntryGuards) @@ -4150,7 +4165,7 @@ choose_random_entry(cpath_build_state_t *state) goto choose_and_finish; /* only choose from the ones we like */ if (options->StrictNodes) { /* in theory this case should never happen, since - * entry_guards_prepend_from_config() drops unwanted relays */ + * entry_guards_set_from_config() drops unwanted relays */ tor_fragile_assert(); } else { log_info(LD_CIRC, @@ -4188,7 +4203,7 @@ choose_random_entry(cpath_build_state_t *state) /* XXX if guard doesn't imply fast and stable, then we need * to tell add_an_entry_guard below what we want, or it might * be a long time til we get it. -RD */ - node = add_an_entry_guard(NULL, 0); + node = add_an_entry_guard(NULL, 0, 0); if (node) { entry_guards_changed(); /* XXX we start over here in case the new node we added shares @@ -5024,7 +5039,7 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache) node = node_get_mutable_by_id(ri->cache_info.identity_digest); tor_assert(node); rewrite_node_address_for_bridge(bridge, node); - add_an_entry_guard(node, 1); + add_an_entry_guard(node, 1, 1); log_notice(LD_DIR, "new bridge descriptor '%s' (%s)", ri->nickname, from_cache ? "cached" : "fresh"); |