[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Implement bridge backends for sampling, filtering guards.
commit 82fa71610de1c7d7faed78490a3cb90ce917a3e2
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Tue Nov 29 10:19:10 2016 -0500
Implement bridge backends for sampling, filtering guards.
Still missing is functionality for picking bridges when we don't
know a descriptor for them yet, and functionality for learning a
bridge ID.
Everything else remains (basically) the same. Neat!
---
src/or/entrynodes.c | 185 +++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 139 insertions(+), 46 deletions(-)
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index dcaab35..6ac3166 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -802,12 +802,10 @@ entry_guard_add_to_sample_impl(guard_selection_t *gs,
* Add an entry guard to the "bridges" guard selection sample, with
* information taken from <b>bridge</b>. Return that entry guard.
*/
-entry_guard_t *
-entry_guard_add_bridge_to_sample(const bridge_info_t *bridge)
+static entry_guard_t *
+entry_guard_add_bridge_to_sample(guard_selection_t *gs,
+ const bridge_info_t *bridge)
{
- guard_selection_t *gs = get_guard_selection_by_name("bridges",
- GS_TYPE_BRIDGE,
- 1);
const uint8_t *id_digest = bridge_get_rsa_id_digest(bridge);
const tor_addr_port_t *addrport = bridge_get_addr_port(bridge);
@@ -896,24 +894,34 @@ num_reachable_filtered_guards(guard_selection_t *gs)
}
/**
- * Add new guards to the sampled guards in <b>gs</b> until there are
- * enough usable filtered guards, but never grow the sample beyond its
- * maximum size. Return the last guard added, or NULL if none were
- * added.
+ * Return a smartlist of the all the guards that are not currently
+ * members of the sample (GUARDS - SAMPLED_GUARDS). The elements of
+ * this list are node_t pointers in the non-bridge case, and
+ * bridge_info_t pointers in the bridge case. Set *<b>n_guards_out/b>
+ * to the number of guards that we found in GUARDS, including those
+ * that were already sampled.
*/
-STATIC entry_guard_t *
-entry_guards_expand_sample(guard_selection_t *gs)
+static smartlist_t *
+get_eligible_guards(guard_selection_t *gs,
+ int *n_guards_out)
{
- tor_assert(gs);
- int n_sampled = smartlist_len(gs->sampled_entry_guards);
- entry_guard_t *added_guard = NULL;
-
- const smartlist_t *nodes = nodelist_get_list();
/* Construct eligible_guards as GUARDS - SAMPLED_GUARDS */
smartlist_t *eligible_guards = smartlist_new();
int n_guards = 0; // total size of "GUARDS"
- int n_usable_filtered_guards = num_reachable_filtered_guards(gs);
- {
+
+ if (gs->type == GS_TYPE_BRIDGE) {
+ const smartlist_t *bridges = bridge_list_get();
+ SMARTLIST_FOREACH_BEGIN(bridges, bridge_info_t *, bridge) {
+ ++n_guards;
+ if (NULL != get_sampled_guard_for_bridge(gs, bridge)) {
+ continue;
+ }
+ smartlist_add(eligible_guards, bridge);
+ } SMARTLIST_FOREACH_END(bridge);
+ } else {
+ const smartlist_t *nodes = nodelist_get_list();
+ const int n_sampled = smartlist_len(gs->sampled_entry_guards);
+
/* Build a bloom filter of our current guards: let's keep this O(N). */
digestset_t *sampled_guard_ids = digestset_new(n_sampled);
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, const entry_guard_t *,
@@ -934,11 +942,58 @@ entry_guards_expand_sample(guard_selection_t *gs)
digestset_free(sampled_guard_ids);
}
- /* Is there at least one guard we haven't sampled? */
- if (! smartlist_len(eligible_guards))
- goto done;
+ *n_guards_out = n_guards;
+ return eligible_guards;
+}
+
+/** Helper: given a smartlist of either bridge_info_t (if gs->type is
+ * GS_TYPE_BRIDGE) or node_t (otherwise), pick one that can be a guard,
+ * add it as a guard, remove it from the list, and return a new
+ * entry_guard_t. Return NULL on failure. */
+static entry_guard_t *
+select_and_add_guard_item_for_sample(guard_selection_t *gs,
+ smartlist_t *eligible_guards)
+{
+ entry_guard_t *added_guard;
+ if (gs->type == GS_TYPE_BRIDGE) {
+ const bridge_info_t *bridge = smartlist_choose(eligible_guards);
+ if (BUG(!bridge))
+ return NULL; // LCOV_EXCL_LINE
+ smartlist_remove(eligible_guards, bridge);
+ added_guard = entry_guard_add_bridge_to_sample(gs, bridge);
+ } else {
+ const node_t *node =
+ node_sl_choose_by_bandwidth(eligible_guards, WEIGHT_FOR_GUARD);
+ if (BUG(!node))
+ return NULL; // LCOV_EXCL_LINE
+ smartlist_remove(eligible_guards, node);
+ added_guard = entry_guard_add_to_sample(gs, node);
+ }
- const int max_sample = (int)(n_guards * get_max_sample_threshold());
+ return added_guard;
+}
+
+/**
+ * Add new guards to the sampled guards in <b>gs</b> until there are
+ * enough usable filtered guards, but never grow the sample beyond its
+ * maximum size. Return the last guard added, or NULL if none were
+ * added.
+ */
+STATIC entry_guard_t *
+entry_guards_expand_sample(guard_selection_t *gs)
+{
+ tor_assert(gs);
+ int n_sampled = smartlist_len(gs->sampled_entry_guards);
+ entry_guard_t *added_guard = NULL;
+ int n_usable_filtered_guards = num_reachable_filtered_guards(gs);
+ int n_guards = 0;
+ smartlist_t *eligible_guards = get_eligible_guards(gs, &n_guards);
+
+ const int using_bridges = (gs->type == GS_TYPE_BRIDGE);
+
+ /* XXXX prop271 spec deviation with bridges, max_sample is "all of them" */
+ const int max_sample = using_bridges ? n_guards :
+ (int)(n_guards * get_max_sample_threshold());
const int min_filtered_sample = get_min_filtered_sample_size();
log_info(LD_GUARD, "Expanding the sample guard set. We have %d guards "
@@ -967,12 +1022,7 @@ entry_guards_expand_sample(guard_selection_t *gs)
}
/* Otherwise we can add at least one new guard. */
- const node_t *node =
- node_sl_choose_by_bandwidth(eligible_guards, WEIGHT_FOR_GUARD);
- if (BUG(! node))
- goto done; // LCOV_EXCL_LINE -- should be impossible.
-
- added_guard = entry_guard_add_to_sample(gs, node);
+ added_guard = select_and_add_guard_item_for_sample(gs, eligible_guards);
if (!added_guard)
goto done; // LCOV_EXCL_LINE -- only fails on BUG.
@@ -980,8 +1030,6 @@ entry_guards_expand_sample(guard_selection_t *gs)
if (added_guard->is_usable_filtered_guard)
++n_usable_filtered_guards;
-
- smartlist_remove(eligible_guards, node);
}
done:
@@ -1029,6 +1077,21 @@ remove_guard_from_confirmed_and_primary_lists(guard_selection_t *gs,
}
}
+/** Return true iff <b>guard</b> is currently "listed" -- that is, it
+ * appears in the consensus, or as a configured bridge (as
+ * appropriate) */
+static int
+entry_guard_is_listed(guard_selection_t *gs, const entry_guard_t *guard)
+{
+ if (gs->type == GS_TYPE_BRIDGE) {
+ return NULL != get_bridge_info_for_guard(guard);
+ } else {
+ const node_t *node = node_get_by_id(guard->identity);
+
+ return node && node_is_possible_guard(gs, node);
+ }
+}
+
/**
* Update the status of all sampled guards based on the arrival of a
* new consensus networkstatus document. This will include marking
@@ -1059,11 +1122,8 @@ sampled_guards_update_from_consensus(guard_selection_t *gs)
/* First: Update listed/unlisted. */
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
- /* XXXX prop271 handle bridges right? */
/* XXXX prop271 check ed ID too */
- const node_t *node = node_get_by_id(guard->identity);
-
- const unsigned is_listed = node && node_is_possible_guard(gs, node);
+ const int is_listed = entry_guard_is_listed(gs, guard);
if (is_listed && ! guard->currently_listed) {
++n_changes;
@@ -1113,8 +1173,6 @@ sampled_guards_update_from_consensus(guard_selection_t *gs)
/* Then: remove the ones that have been junk for too long */
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
- /* XXXX prop271 handle bridges right? */
-
int remove = 0;
if (guard->currently_listed == 0 &&
@@ -1180,20 +1238,48 @@ node_passes_guard_filter(const or_options_t *options, guard_selection_t *gs,
/* NOTE: Make sure that this function stays in sync with
* options_transition_affects_entry_guards */
+ tor_assert(! options->UseBridges);
+
(void)gs;
if (routerset_contains_node(options->ExcludeNodes, node))
return 0;
/* XXXX -- prop271 spec deviation -- add entrynodes to spec. */
if (options->EntryNodes &&
- !options->UseBridges &&
!routerset_contains_node(options->EntryNodes, node))
return 0;
if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, 0))
return 0;
- if (bool_neq(options->UseBridges, node_is_a_configured_bridge(node)))
+ if (node_is_a_configured_bridge(node))
+ return 0;
+
+ return 1;
+}
+
+/** Helper: Return true iff <b>bridge</b> passes our configuration
+ * filter-- if it is a relay that we are configured to be able to
+ * connect to. */
+static int
+bridge_passes_guard_filter(const or_options_t *options,
+ const bridge_info_t *bridge)
+{
+ tor_assert(options->UseBridges);
+ tor_assert(bridge);
+ if (!bridge)
+ return 0;
+
+ if (routerset_contains_bridge(options->ExcludeNodes, bridge))
+ return 0;
+
+ /* Ignore entrynodes */
+ const tor_addr_port_t *addrport = bridge_get_addr_port(bridge);
+
+ if (!fascist_firewall_allows_address_addr(&addrport->addr,
+ addrport->port,
+ FIREWALL_OR_CONNECTION,
+ 0, 0))
return 0;
return 1;
@@ -1212,14 +1298,21 @@ entry_guard_passes_filter(const or_options_t *options, guard_selection_t *gs,
if (guard->pb.path_bias_disabled)
return 0;
- const node_t *node = node_get_by_id(guard->identity);
- if (node == NULL) {
- // This can happen when currently_listed is true, and we're not updating
- // it because we don't have a live consensus.
- return 0;
- }
+ if (gs->type == GS_TYPE_BRIDGE) {
+ const bridge_info_t *bridge = get_bridge_info_for_guard(guard);
+ if (bridge == NULL)
+ return 0;
+ return bridge_passes_guard_filter(options, bridge);
+ } else {
+ const node_t *node = node_get_by_id(guard->identity);
+ if (node == NULL) {
+ // This can happen when currently_listed is true, and we're not updating
+ // it because we don't have a live consensus.
+ return 0;
+ }
- return node_passes_guard_filter(options, gs, node);
+ return node_passes_guard_filter(options, gs, node);
+ }
}
/**
@@ -3126,7 +3219,7 @@ add_an_entry_guard(guard_selection_t *gs,
/** Entry point for bridges.c to add a bridge as guard.
*
- * XXXX prop271 refactor.*/
+ * XXXX prop271 refactor, bridge.*/
void
add_bridge_as_entry_guard(guard_selection_t *gs,
const node_t *chosen)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits