mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Implement support for per-circuit guard restrictions.
This is an important thing I hadn't considered when writing prop271: sometimes you have to restrict what guard you use for a particular circuit. Most frequently, that would be because you plan to use a certain node as your exit, and so you can't choose that for your guard. This change means that the upgrade-waiting-circuits algorithm needs a slight tweak too: circuit A cannot block circuit B from upgrading if circuit B needs to follow a restriction that circuit A does not follow.
This commit is contained in:
+13
-2
@@ -2515,8 +2515,8 @@ extend_info_dup(extend_info_t *info)
|
||||
return newinfo;
|
||||
}
|
||||
|
||||
/** Return the routerinfo_t for the chosen exit router in <b>state</b>.
|
||||
* If there is no chosen exit, or if we don't know the routerinfo_t for
|
||||
/** Return the node_t for the chosen exit router in <b>state</b>.
|
||||
* If there is no chosen exit, or if we don't know the node_t for
|
||||
* the chosen exit, return NULL.
|
||||
*/
|
||||
const node_t *
|
||||
@@ -2527,6 +2527,17 @@ build_state_get_exit_node(cpath_build_state_t *state)
|
||||
return node_get_by_id(state->chosen_exit->identity_digest);
|
||||
}
|
||||
|
||||
/** Return the RSA ID digest for the chosen exit router in <b>state</b>.
|
||||
* If there is no chosen exit, return NULL.
|
||||
*/
|
||||
const uint8_t *
|
||||
build_state_get_exit_rsa_id(cpath_build_state_t *state)
|
||||
{
|
||||
if (!state || !state->chosen_exit)
|
||||
return NULL;
|
||||
return (const uint8_t *) state->chosen_exit->identity_digest;
|
||||
}
|
||||
|
||||
/** Return the nickname for the chosen exit router in <b>state</b>. If
|
||||
* there is no chosen exit, or if we don't know the routerinfo_t for the
|
||||
* chosen exit, return NULL.
|
||||
|
||||
@@ -61,6 +61,7 @@ int extend_info_supports_ntor(const extend_info_t* ei);
|
||||
int circuit_can_use_tap(const origin_circuit_t *circ);
|
||||
int circuit_has_usable_onion_key(const origin_circuit_t *circ);
|
||||
int extend_info_has_preferred_onion_key(const extend_info_t* ei);
|
||||
const uint8_t *build_state_get_exit_rsa_id(cpath_build_state_t *state);
|
||||
const node_t *build_state_get_exit_node(cpath_build_state_t *state);
|
||||
const char *build_state_get_exit_nickname(cpath_build_state_t *state);
|
||||
|
||||
|
||||
+104
-18
@@ -168,6 +168,8 @@ static entry_guard_t *entry_guard_add_to_sample_impl(guard_selection_t *gs,
|
||||
const tor_addr_port_t *bridge_addrport);
|
||||
static entry_guard_t *get_sampled_guard_by_bridge_addr(guard_selection_t *gs,
|
||||
const tor_addr_port_t *addrport);
|
||||
static int entry_guard_obeys_restriction(const entry_guard_t *guard,
|
||||
const entry_guard_restriction_t *rst);
|
||||
|
||||
/** Return 0 if we should apply guardfraction information found in the
|
||||
* consensus. A specific consensus can be specified with the
|
||||
@@ -878,13 +880,20 @@ entry_guard_learned_bridge_identity(const tor_addr_port_t *addrport,
|
||||
/**
|
||||
* Return the number of sampled guards in <b>gs</b> that are "filtered"
|
||||
* (that is, we're willing to connect to them) and that are "usable"
|
||||
* (that is, either "reachable" or "maybe reachable"). */
|
||||
* (that is, either "reachable" or "maybe reachable").
|
||||
*
|
||||
* If a restriction is provided in <b>rst</b>, do not count any guards that
|
||||
* violate it.
|
||||
*/
|
||||
STATIC int
|
||||
num_reachable_filtered_guards(guard_selection_t *gs)
|
||||
num_reachable_filtered_guards(guard_selection_t *gs,
|
||||
const entry_guard_restriction_t *rst)
|
||||
{
|
||||
int n_reachable_filtered_guards = 0;
|
||||
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
|
||||
entry_guard_consider_retry(guard);
|
||||
if (! entry_guard_obeys_restriction(guard, rst))
|
||||
continue;
|
||||
if (guard->is_usable_filtered_guard)
|
||||
++n_reachable_filtered_guards;
|
||||
} SMARTLIST_FOREACH_END(guard);
|
||||
@@ -1003,7 +1012,7 @@ 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_usable_filtered_guards = num_reachable_filtered_guards(gs, NULL);
|
||||
int n_guards = 0;
|
||||
smartlist_t *eligible_guards = get_eligible_guards(gs, &n_guards);
|
||||
|
||||
@@ -1323,6 +1332,22 @@ entry_guard_passes_filter(const or_options_t *options, guard_selection_t *gs,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff <b>guard</b> obeys the restrictions defined in <b>rst</b>.
|
||||
* (If <b>rst</b> is NULL, there are no restrictions.)
|
||||
*/
|
||||
static int
|
||||
entry_guard_obeys_restriction(const entry_guard_t *guard,
|
||||
const entry_guard_restriction_t *rst)
|
||||
{
|
||||
tor_assert(guard);
|
||||
if (! rst)
|
||||
return 1; // No restriction? No problem.
|
||||
|
||||
// Only one kind of restriction exists right now
|
||||
return tor_memneq(guard->identity, rst->exclude_id, DIGEST_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the <b>is_filtered_guard</b> and <b>is_usable_filtered_guard</b>
|
||||
* flags on <b>guard</b>. */
|
||||
@@ -1373,9 +1398,13 @@ entry_guards_update_filtered_sets(guard_selection_t *gs)
|
||||
*
|
||||
* Make sure that the sample is big enough, and that all the filter flags
|
||||
* are set correctly, before calling this function.
|
||||
*
|
||||
* If a restriction is provided in <b>rst</b>, do not return any guards that
|
||||
* violate it.
|
||||
**/
|
||||
STATIC entry_guard_t *
|
||||
sample_reachable_filtered_entry_guards(guard_selection_t *gs,
|
||||
const entry_guard_restriction_t *rst,
|
||||
unsigned flags)
|
||||
{
|
||||
tor_assert(gs);
|
||||
@@ -1389,7 +1418,7 @@ sample_reachable_filtered_entry_guards(guard_selection_t *gs,
|
||||
entry_guard_consider_retry(guard);
|
||||
} SMARTLIST_FOREACH_END(guard);
|
||||
|
||||
const int n_reachable_filtered = num_reachable_filtered_guards(gs);
|
||||
const int n_reachable_filtered = num_reachable_filtered_guards(gs, rst);
|
||||
|
||||
log_info(LD_GUARD, "Trying to sample a reachable guard: We know of %d "
|
||||
"in the USABLE_FILTERED set.", n_reachable_filtered);
|
||||
@@ -1407,6 +1436,8 @@ sample_reachable_filtered_entry_guards(guard_selection_t *gs,
|
||||
smartlist_t *reachable_filtered_sample = smartlist_new();
|
||||
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
|
||||
entry_guard_consider_retry(guard);// redundant, but cheap.
|
||||
if (! entry_guard_obeys_restriction(guard, rst))
|
||||
continue;
|
||||
if (! guard->is_usable_filtered_guard)
|
||||
continue;
|
||||
if (exclude_confirmed && guard->confirmed_idx >= 0)
|
||||
@@ -1568,7 +1599,7 @@ entry_guards_update_primary(guard_selection_t *gs)
|
||||
|
||||
/* Finally, fill out the list with sampled guards. */
|
||||
while (smartlist_len(new_primary_guards) < N_PRIMARY_GUARDS) {
|
||||
entry_guard_t *guard = sample_reachable_filtered_entry_guards(gs,
|
||||
entry_guard_t *guard = sample_reachable_filtered_entry_guards(gs, NULL,
|
||||
SAMPLE_EXCLUDE_CONFIRMED|
|
||||
SAMPLE_EXCLUDE_PRIMARY|
|
||||
SAMPLE_NO_UPDATE_PRIMARY);
|
||||
@@ -1708,7 +1739,9 @@ entry_guards_note_internet_connectivity(guard_selection_t *gs)
|
||||
* of the circuit.
|
||||
*/
|
||||
STATIC entry_guard_t *
|
||||
select_entry_guard_for_circuit(guard_selection_t *gs, unsigned *state_out)
|
||||
select_entry_guard_for_circuit(guard_selection_t *gs,
|
||||
const entry_guard_restriction_t *rst,
|
||||
unsigned *state_out)
|
||||
{
|
||||
/*XXXX prop271 consider splitting this function up. */
|
||||
tor_assert(gs);
|
||||
@@ -1721,6 +1754,8 @@ select_entry_guard_for_circuit(guard_selection_t *gs, unsigned *state_out)
|
||||
<maybe> or <yes>, return the first such guard." */
|
||||
SMARTLIST_FOREACH_BEGIN(gs->primary_entry_guards, entry_guard_t *, guard) {
|
||||
entry_guard_consider_retry(guard);
|
||||
if (! entry_guard_obeys_restriction(guard, rst))
|
||||
continue;
|
||||
if (guard->is_reachable != GUARD_REACHABLE_NO) {
|
||||
*state_out = GUARD_CIRC_STATE_USABLE_ON_COMPLETION;
|
||||
guard->last_tried_to_connect = approx_time();
|
||||
@@ -1737,6 +1772,8 @@ select_entry_guard_for_circuit(guard_selection_t *gs, unsigned *state_out)
|
||||
SMARTLIST_FOREACH_BEGIN(gs->confirmed_entry_guards, entry_guard_t *, guard) {
|
||||
if (guard->is_primary)
|
||||
continue; /* we already considered this one. */
|
||||
if (! entry_guard_obeys_restriction(guard, rst))
|
||||
continue;
|
||||
entry_guard_consider_retry(guard);
|
||||
if (guard->is_usable_filtered_guard && ! guard->is_pending) {
|
||||
guard->is_pending = 1;
|
||||
@@ -1755,6 +1792,7 @@ select_entry_guard_for_circuit(guard_selection_t *gs, unsigned *state_out)
|
||||
{
|
||||
entry_guard_t *guard;
|
||||
guard = sample_reachable_filtered_entry_guards(gs,
|
||||
rst,
|
||||
SAMPLE_EXCLUDE_CONFIRMED |
|
||||
SAMPLE_EXCLUDE_PRIMARY |
|
||||
SAMPLE_EXCLUDE_PENDING);
|
||||
@@ -1925,6 +1963,13 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b)
|
||||
}
|
||||
}
|
||||
|
||||
/** Release all storage held in <b>restriction</b> */
|
||||
static void
|
||||
entry_guard_restriction_free(entry_guard_restriction_t *rst)
|
||||
{
|
||||
tor_free(rst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all storage held in <b>state</b>.
|
||||
*/
|
||||
@@ -1933,6 +1978,7 @@ circuit_guard_state_free(circuit_guard_state_t *state)
|
||||
{
|
||||
if (!state)
|
||||
return;
|
||||
entry_guard_restriction_free(state->restrictions);
|
||||
entry_guard_handle_free(state->guard);
|
||||
tor_free(state);
|
||||
}
|
||||
@@ -1942,9 +1988,14 @@ circuit_guard_state_free(circuit_guard_state_t *state)
|
||||
* in *<b>chosen_node_out</b>. Set *<b>guard_state_out</b> to an opaque
|
||||
* state object that will record whether the circuit is ready to be used
|
||||
* or not. Return 0 on success; on failure, return -1.
|
||||
*
|
||||
* If a restriction is provided in <b>rst</b>, do not return any guards that
|
||||
* violate it, and remember that restriction in <b>guard_state_out</b> for
|
||||
* later use. (Takes ownership of the <b>rst</b> object.)
|
||||
*/
|
||||
int
|
||||
entry_guard_pick_for_circuit(guard_selection_t *gs,
|
||||
entry_guard_restriction_t *rst,
|
||||
const node_t **chosen_node_out,
|
||||
circuit_guard_state_t **guard_state_out)
|
||||
{
|
||||
@@ -1955,23 +2006,27 @@ entry_guard_pick_for_circuit(guard_selection_t *gs,
|
||||
*guard_state_out = NULL;
|
||||
|
||||
unsigned state = 0;
|
||||
entry_guard_t *guard = select_entry_guard_for_circuit(gs, &state);
|
||||
entry_guard_t *guard = select_entry_guard_for_circuit(gs, rst, &state);
|
||||
if (! guard)
|
||||
return -1;
|
||||
goto fail;
|
||||
if (BUG(state == 0))
|
||||
return -1;
|
||||
goto fail;
|
||||
const node_t *node = node_get_by_id(guard->identity);
|
||||
// XXXX prop271 check Ed ID.
|
||||
if (! node)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
*chosen_node_out = node;
|
||||
*guard_state_out = tor_malloc_zero(sizeof(circuit_guard_state_t));
|
||||
(*guard_state_out)->guard = entry_guard_handle_new(guard);
|
||||
(*guard_state_out)->state = state;
|
||||
(*guard_state_out)->state_set_at = approx_time();
|
||||
(*guard_state_out)->restrictions = rst;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
entry_guard_restriction_free(rst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2098,9 +2153,14 @@ entry_guards_all_primary_guards_are_down(guard_selection_t *gs)
|
||||
}
|
||||
|
||||
/** Wrapper for entry_guard_has_higher_priority that compares the
|
||||
* guard-priorities of a pair of circuits. */
|
||||
* guard-priorities of a pair of circuits.
|
||||
*
|
||||
* If a restriction is provided in <b>rst</b>, then do not consider
|
||||
* <b>a</b> to have higher priority if it violates the restriction.
|
||||
*/
|
||||
static int
|
||||
circ_state_has_higher_priority(origin_circuit_t *a,
|
||||
const entry_guard_restriction_t *rst,
|
||||
origin_circuit_t *b)
|
||||
{
|
||||
circuit_guard_state_t *state_a = origin_circuit_get_guard_state(a);
|
||||
@@ -2118,6 +2178,9 @@ circ_state_has_higher_priority(origin_circuit_t *a,
|
||||
} else if (! guard_b) {
|
||||
/* Known guard -- higher priority than any unknown guard. */
|
||||
return 1;
|
||||
} else if (! entry_guard_obeys_restriction(guard_a, rst)) {
|
||||
/* Restriction violated; guard_a cannot have higher priority. */
|
||||
return 0;
|
||||
} else {
|
||||
/* Both known -- compare.*/
|
||||
return entry_guard_has_higher_priority(guard_a, guard_b);
|
||||
@@ -2175,13 +2238,13 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
|
||||
if (state->state == GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD) {
|
||||
++n_waiting;
|
||||
if (! best_waiting_circuit ||
|
||||
circ_state_has_higher_priority(circ, best_waiting_circuit)) {
|
||||
circ_state_has_higher_priority(circ, NULL, best_waiting_circuit)) {
|
||||
best_waiting_circuit = circ;
|
||||
}
|
||||
} else if (state->state == GUARD_CIRC_STATE_COMPLETE) {
|
||||
++n_complete;
|
||||
if (! best_complete_circuit ||
|
||||
circ_state_has_higher_priority(circ, best_complete_circuit)) {
|
||||
circ_state_has_higher_priority(circ, NULL, best_complete_circuit)) {
|
||||
best_complete_circuit = circ;
|
||||
}
|
||||
}
|
||||
@@ -2193,8 +2256,15 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
|
||||
goto no_change;
|
||||
}
|
||||
|
||||
/* We'll need to keep track of what restrictions were used when picking this
|
||||
* circuit, so that we don't allow any circuit without those restrictions to
|
||||
* block it. */
|
||||
const entry_guard_restriction_t *rst_on_best_waiting =
|
||||
origin_circuit_get_guard_state(best_waiting_circuit)->restrictions;
|
||||
|
||||
if (best_complete_circuit) {
|
||||
if (circ_state_has_higher_priority(best_complete_circuit,
|
||||
rst_on_best_waiting,
|
||||
best_waiting_circuit)) {
|
||||
/* "If any circuit is <complete>, then do not use any
|
||||
<waiting_for_better_guard> or <usable_if_no_better_guard> circuits
|
||||
@@ -2225,8 +2295,10 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
|
||||
continue;
|
||||
if (state->state != GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD)
|
||||
continue;
|
||||
if (state->state_set_at > state_set_at_cutoff &&
|
||||
circ_state_has_higher_priority(circ, best_waiting_circuit))
|
||||
if (state->state_set_at <= state_set_at_cutoff)
|
||||
continue;
|
||||
if (circ_state_has_higher_priority(circ, rst_on_best_waiting,
|
||||
best_waiting_circuit))
|
||||
++n_blockers_found;
|
||||
} SMARTLIST_FOREACH_END(circ);
|
||||
|
||||
@@ -2246,9 +2318,14 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
|
||||
circuit_guard_state_t *state = origin_circuit_get_guard_state(circ);
|
||||
if (BUG(state == NULL))
|
||||
continue;
|
||||
if (circ != best_waiting_circuit && rst_on_best_waiting) {
|
||||
/* Can't upgrade other circ with same priority as best; might
|
||||
be blocked. */
|
||||
continue;
|
||||
}
|
||||
if (state->state != GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD)
|
||||
continue;
|
||||
if (circ_state_has_higher_priority(best_waiting_circuit, circ))
|
||||
if (circ_state_has_higher_priority(best_waiting_circuit, NULL, circ))
|
||||
continue;
|
||||
|
||||
state->state = GUARD_CIRC_STATE_COMPLETE;
|
||||
@@ -4759,10 +4836,18 @@ guards_choose_guard(cpath_build_state_t *state,
|
||||
if (get_options()->UseDeprecatedGuardAlgorithm) {
|
||||
return choose_random_entry(state);
|
||||
} else {
|
||||
// XXXX prop271 we need to look at the chosen exit node if any, and
|
||||
// not duplicate it.
|
||||
const node_t *r = NULL;
|
||||
const uint8_t *exit_id = NULL;
|
||||
entry_guard_restriction_t *rst = NULL;
|
||||
// XXXX prop271 spec deviation -- use of restriction here.
|
||||
if (state && (exit_id = build_state_get_exit_rsa_id(state))) {
|
||||
/* We're building to a targeted exit node, so that node can't be
|
||||
* chosen as our guard for this circuit. */
|
||||
rst = tor_malloc_zero(sizeof(entry_guard_restriction_t));
|
||||
memcpy(rst->exclude_id, exit_id, DIGEST_LEN);
|
||||
}
|
||||
if (entry_guard_pick_for_circuit(get_guard_selection_info(),
|
||||
rst,
|
||||
&r,
|
||||
guard_state_out) < 0) {
|
||||
tor_assert(r == NULL);
|
||||
@@ -4788,6 +4873,7 @@ guards_choose_dirguard(dirinfo_type_t info,
|
||||
* microdescriptors. -NM */
|
||||
const node_t *r = NULL;
|
||||
if (entry_guard_pick_for_circuit(get_guard_selection_info(),
|
||||
NULL,
|
||||
&r,
|
||||
guard_state_out) < 0) {
|
||||
tor_assert(r == NULL);
|
||||
|
||||
+36
-2
@@ -24,6 +24,10 @@ typedef struct entry_guard_t entry_guard_t;
|
||||
private. */
|
||||
typedef struct circuit_guard_state_t circuit_guard_state_t;
|
||||
|
||||
/* Forward declaration for entry_guard_restriction_t; the real declaration is
|
||||
private. */
|
||||
typedef struct entry_guard_restriction_t entry_guard_restriction_t;
|
||||
|
||||
/* Information about a guard's pathbias status.
|
||||
* These fields are used in circpathbias.c to try to detect entry
|
||||
* nodes that are failing circuits at a suspicious frequency.
|
||||
@@ -310,6 +314,24 @@ struct guard_selection_s {
|
||||
|
||||
struct entry_guard_handle_t;
|
||||
|
||||
/**
|
||||
* A restriction to remember which entry guards are off-limits for a given
|
||||
* circuit.
|
||||
*
|
||||
* Right now, we only use restrictions to block a single guard from being
|
||||
* selected; this mechanism is designed to be more extensible in the future,
|
||||
* however.
|
||||
*
|
||||
* Note: This mechanism is NOT for recording which guards are never to be
|
||||
* used: only which guards cannot be used on <em>one particular circuit</em>.
|
||||
*/
|
||||
struct entry_guard_restriction_t {
|
||||
/**
|
||||
* The guard's RSA identity digest must not equal this.
|
||||
*/
|
||||
uint8_t exclude_id[DIGEST_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* Per-circuit state to track whether we'll be able to use the circuit.
|
||||
*/
|
||||
@@ -320,6 +342,14 @@ struct circuit_guard_state_t {
|
||||
time_t state_set_at;
|
||||
/** One of GUARD_CIRC_STATE_* */
|
||||
uint8_t state;
|
||||
|
||||
/**
|
||||
* A set of restrictions that were placed on this guard when we selected it
|
||||
* for this particular circuit. We need to remember the restrictions here,
|
||||
* since any guard that breaks these restrictions will not block this
|
||||
* circuit from becoming COMPLETE.
|
||||
*/
|
||||
entry_guard_restriction_t *restrictions;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -356,6 +386,7 @@ guard_pathbias_t *entry_guard_get_pathbias_state(entry_guard_t *guard);
|
||||
|
||||
void circuit_guard_state_free(circuit_guard_state_t *state);
|
||||
int entry_guard_pick_for_circuit(guard_selection_t *gs,
|
||||
entry_guard_restriction_t *rst,
|
||||
const node_t **chosen_node_out,
|
||||
circuit_guard_state_t **guard_state_out);
|
||||
typedef enum {
|
||||
@@ -491,12 +522,14 @@ STATIC int entry_guards_all_primary_guards_are_down(guard_selection_t *gs);
|
||||
/**@}*/
|
||||
STATIC entry_guard_t *sample_reachable_filtered_entry_guards(
|
||||
guard_selection_t *gs,
|
||||
const entry_guard_restriction_t *rst,
|
||||
unsigned flags);
|
||||
STATIC void entry_guard_consider_retry(entry_guard_t *guard);
|
||||
STATIC void make_guard_confirmed(guard_selection_t *gs, entry_guard_t *guard);
|
||||
STATIC void entry_guards_update_confirmed(guard_selection_t *gs);
|
||||
STATIC void entry_guards_update_primary(guard_selection_t *gs);
|
||||
STATIC int num_reachable_filtered_guards(guard_selection_t *gs);
|
||||
STATIC int num_reachable_filtered_guards(guard_selection_t *gs,
|
||||
const entry_guard_restriction_t *rst);
|
||||
STATIC void sampled_guards_update_from_consensus(guard_selection_t *gs);
|
||||
/**
|
||||
* @name Possible guard-states for a circuit.
|
||||
@@ -522,7 +555,8 @@ STATIC void sampled_guards_update_from_consensus(guard_selection_t *gs);
|
||||
STATIC void entry_guards_note_guard_failure(guard_selection_t *gs,
|
||||
entry_guard_t *guard);
|
||||
STATIC entry_guard_t *select_entry_guard_for_circuit(guard_selection_t *gs,
|
||||
unsigned *state_out);
|
||||
const entry_guard_restriction_t *rst,
|
||||
unsigned *state_out);
|
||||
STATIC void mark_primary_guards_maybe_reachable(guard_selection_t *gs);
|
||||
STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs,
|
||||
entry_guard_t *guard,
|
||||
|
||||
+46
-46
@@ -1353,7 +1353,7 @@ test_entry_guard_node_filter(void *arg)
|
||||
tt_assert(g[i]->is_filtered_guard == 1);
|
||||
tt_assert(g[i]->is_usable_filtered_guard == 1);
|
||||
}
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, NUM);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, NUM);
|
||||
|
||||
/* Make sure refiltering doesn't hurt */
|
||||
entry_guards_update_filtered_sets(gs);
|
||||
@@ -1361,7 +1361,7 @@ test_entry_guard_node_filter(void *arg)
|
||||
tt_assert(g[i]->is_filtered_guard == 1);
|
||||
tt_assert(g[i]->is_usable_filtered_guard == 1);
|
||||
}
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, NUM);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, NUM);
|
||||
|
||||
/* Now start doing things to make the guards get filtered out, 1 by 1. */
|
||||
|
||||
@@ -1401,7 +1401,7 @@ test_entry_guard_node_filter(void *arg)
|
||||
tt_assert(g[i]->is_filtered_guard == (i == 5 || i == 6));
|
||||
tt_assert(g[i]->is_usable_filtered_guard == (i == 6));
|
||||
}
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, 1);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, 1);
|
||||
|
||||
/* Now make sure we have no live consensus, and no nodes. Nothing should
|
||||
* pass the filter any more. */
|
||||
@@ -1415,7 +1415,7 @@ test_entry_guard_node_filter(void *arg)
|
||||
tt_assert(g[i]->is_filtered_guard == 0);
|
||||
tt_assert(g[i]->is_usable_filtered_guard == 0);
|
||||
}
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, 0);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
guard_selection_free(gs);
|
||||
@@ -1434,11 +1434,11 @@ test_entry_guard_expand_sample(void *arg)
|
||||
|
||||
// Every sampled guard here should be filtered and reachable for now.
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
|
||||
/* Make sure we got the right number. */
|
||||
tt_int_op(DFLT_MIN_FILTERED_SAMPLE_SIZE, OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
|
||||
// Make sure everything we got was from our fake node list, and everything
|
||||
// was unique.
|
||||
@@ -1457,7 +1457,7 @@ test_entry_guard_expand_sample(void *arg)
|
||||
guard = entry_guards_expand_sample(gs);
|
||||
tt_assert(! guard); // no guard was added.
|
||||
tt_int_op(DFLT_MIN_FILTERED_SAMPLE_SIZE, OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
|
||||
// Make a few guards unreachable.
|
||||
guard = smartlist_get(gs->sampled_entry_guards, 0);
|
||||
@@ -1467,21 +1467,21 @@ test_entry_guard_expand_sample(void *arg)
|
||||
guard = smartlist_get(gs->sampled_entry_guards, 2);
|
||||
guard->is_usable_filtered_guard = 0;
|
||||
tt_int_op(DFLT_MIN_FILTERED_SAMPLE_SIZE - 3, OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
|
||||
// This time, expanding the sample will add some more guards.
|
||||
guard = entry_guards_expand_sample(gs);
|
||||
tt_assert(guard); // no guard was added.
|
||||
tt_int_op(DFLT_MIN_FILTERED_SAMPLE_SIZE, OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_EQ,
|
||||
num_reachable_filtered_guards(gs)+3);
|
||||
num_reachable_filtered_guards(gs, NULL)+3);
|
||||
|
||||
// Still idempotent.
|
||||
guard = entry_guards_expand_sample(gs);
|
||||
tt_assert(! guard); // no guard was added.
|
||||
tt_int_op(DFLT_MIN_FILTERED_SAMPLE_SIZE, OP_EQ,
|
||||
num_reachable_filtered_guards(gs));
|
||||
num_reachable_filtered_guards(gs, NULL));
|
||||
|
||||
// Now, do a nasty trick: tell the filter to exclude 31/32 of the guards.
|
||||
// This will cause the sample size to get reeeeally huge, while the
|
||||
@@ -1497,7 +1497,7 @@ test_entry_guard_expand_sample(void *arg)
|
||||
entry_guards_update_filtered_sets(gs);
|
||||
|
||||
// Surely (p ~ 1-2**-60), one of our guards has been excluded.
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_LT,
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_LT,
|
||||
DFLT_MIN_FILTERED_SAMPLE_SIZE);
|
||||
|
||||
// Try to regenerate the guards.
|
||||
@@ -1505,7 +1505,7 @@ test_entry_guard_expand_sample(void *arg)
|
||||
tt_assert(guard); // no guard was added.
|
||||
|
||||
/* this time, it's possible that we didn't add enough sampled guards. */
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_LE,
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_LE,
|
||||
DFLT_MIN_FILTERED_SAMPLE_SIZE);
|
||||
/* but we definitely didn't exceed the sample maximum. */
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_LE,
|
||||
@@ -1538,7 +1538,7 @@ test_entry_guard_expand_sample_small_net(void *arg)
|
||||
tt_assert(guard); // the last guard returned -- some guard was added.
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_GT, 0);
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_LT, 10);
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, 0);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, 0);
|
||||
done:
|
||||
guard_selection_free(gs);
|
||||
}
|
||||
@@ -1562,7 +1562,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
|
||||
/* First, sample some guards. */
|
||||
entry_guards_expand_sample(gs);
|
||||
int n_sampled_pre = smartlist_len(gs->sampled_entry_guards);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs, NULL);
|
||||
tt_i64_op(n_sampled_pre, OP_EQ, n_filtered_pre);
|
||||
tt_i64_op(n_sampled_pre, OP_GT, 10);
|
||||
|
||||
@@ -1584,7 +1584,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
|
||||
dummy_consensus = NULL;
|
||||
sampled_guards_update_from_consensus(gs);
|
||||
tt_i64_op(smartlist_len(gs->sampled_entry_guards), OP_EQ, n_sampled_pre);
|
||||
tt_i64_op(num_reachable_filtered_guards(gs), OP_EQ, n_filtered_pre);
|
||||
tt_i64_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, n_filtered_pre);
|
||||
/* put the networkstatus back. */
|
||||
dummy_consensus = ns_tmp;
|
||||
ns_tmp = NULL;
|
||||
@@ -1596,7 +1596,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
|
||||
sampled_guards_update_from_consensus(gs);
|
||||
|
||||
tt_i64_op(smartlist_len(gs->sampled_entry_guards), OP_EQ, n_sampled_pre);
|
||||
tt_i64_op(num_reachable_filtered_guards(gs), OP_EQ, n_filtered_pre - 5);
|
||||
tt_i64_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, n_filtered_pre-5);
|
||||
for (i = 0; i < 5; ++i) {
|
||||
entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, i);
|
||||
tt_assert(! g->currently_listed);
|
||||
@@ -1666,7 +1666,7 @@ test_entry_guard_update_from_consensus_repair(void *arg)
|
||||
/* First, sample some guards. */
|
||||
entry_guards_expand_sample(gs);
|
||||
int n_sampled_pre = smartlist_len(gs->sampled_entry_guards);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs, NULL);
|
||||
tt_i64_op(n_sampled_pre, OP_EQ, n_filtered_pre);
|
||||
tt_i64_op(n_sampled_pre, OP_GT, 10);
|
||||
|
||||
@@ -1694,7 +1694,7 @@ test_entry_guard_update_from_consensus_repair(void *arg)
|
||||
teardown_capture_of_logs();
|
||||
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_EQ, n_sampled_pre);
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, n_filtered_pre - 3);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, n_filtered_pre-3);
|
||||
for (i = 3; i < n_sampled_pre; ++i) {
|
||||
/* these will become listed. */
|
||||
entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, i);
|
||||
@@ -1731,7 +1731,7 @@ test_entry_guard_update_from_consensus_remove(void *arg)
|
||||
/* First, sample some guards. */
|
||||
entry_guards_expand_sample(gs);
|
||||
int n_sampled_pre = smartlist_len(gs->sampled_entry_guards);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs);
|
||||
int n_filtered_pre = num_reachable_filtered_guards(gs, NULL);
|
||||
tt_i64_op(n_sampled_pre, OP_EQ, n_filtered_pre);
|
||||
tt_i64_op(n_sampled_pre, OP_GT, 10);
|
||||
|
||||
@@ -1912,7 +1912,7 @@ test_entry_guard_sample_reachable_filtered(void *arg)
|
||||
|
||||
entry_guards_update_filtered_sets(gs);
|
||||
gs->primary_guards_up_to_date = 1;
|
||||
tt_int_op(num_reachable_filtered_guards(gs), OP_EQ, n_guards - 1);
|
||||
tt_int_op(num_reachable_filtered_guards(gs, NULL), OP_EQ, n_guards - 1);
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_EQ, n_guards);
|
||||
|
||||
// +1 since the one we made disabled will make another one get added.
|
||||
@@ -1934,7 +1934,7 @@ test_entry_guard_sample_reachable_filtered(void *arg)
|
||||
const int excluded_flags = tests[j].flag;
|
||||
const int excluded_idx = tests[j].idx;
|
||||
for (i = 0; i < N; ++i) {
|
||||
g = sample_reachable_filtered_entry_guards(gs, excluded_flags);
|
||||
g = sample_reachable_filtered_entry_guards(gs, NULL, excluded_flags);
|
||||
tor_assert(g);
|
||||
int pos = smartlist_pos(gs->sampled_entry_guards, g);
|
||||
tt_int_op(smartlist_len(gs->sampled_entry_guards), OP_EQ, n_guards);
|
||||
@@ -1965,7 +1965,7 @@ test_entry_guard_sample_reachable_filtered_empty(void *arg)
|
||||
SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n,
|
||||
n->is_possible_guard = 0);
|
||||
|
||||
entry_guard_t *g = sample_reachable_filtered_entry_guards(gs, 0);
|
||||
entry_guard_t *g = sample_reachable_filtered_entry_guards(gs, NULL, 0);
|
||||
tt_ptr_op(g, OP_EQ, NULL);
|
||||
|
||||
done:
|
||||
@@ -2162,7 +2162,7 @@ test_entry_guard_select_for_circuit_no_confirmed(void *arg)
|
||||
entry_guards_update_primary(gs);
|
||||
unsigned state = 9999;
|
||||
|
||||
entry_guard_t *g = select_entry_guard_for_circuit(gs, &state);
|
||||
entry_guard_t *g = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
|
||||
tt_assert(g);
|
||||
tt_assert(g->is_primary);
|
||||
@@ -2172,7 +2172,7 @@ test_entry_guard_select_for_circuit_no_confirmed(void *arg)
|
||||
tt_i64_op(g->last_tried_to_connect, OP_EQ, approx_time());
|
||||
|
||||
// If we do that again, we should get the same guard.
|
||||
entry_guard_t *g2 = select_entry_guard_for_circuit(gs, &state);
|
||||
entry_guard_t *g2 = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_ptr_op(g2, OP_EQ, g);
|
||||
|
||||
// if we mark that guard down, we should get a different primary guard.
|
||||
@@ -2181,7 +2181,7 @@ test_entry_guard_select_for_circuit_no_confirmed(void *arg)
|
||||
g->unreachable_since = approx_time() - 10;
|
||||
g->last_tried_to_connect = approx_time() - 10;
|
||||
state = 9999;
|
||||
g2 = select_entry_guard_for_circuit(gs, &state);
|
||||
g2 = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_ptr_op(g2, OP_NE, g);
|
||||
tt_assert(g2);
|
||||
tt_assert(g2->is_primary);
|
||||
@@ -2195,7 +2195,7 @@ test_entry_guard_select_for_circuit_no_confirmed(void *arg)
|
||||
g->unreachable_since = approx_time() - 72*60*60;
|
||||
g->last_tried_to_connect = approx_time() - 72*60*60;
|
||||
state = 9999;
|
||||
g2 = select_entry_guard_for_circuit(gs, &state);
|
||||
g2 = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_ptr_op(g2, OP_EQ, g);
|
||||
tt_assert(g2);
|
||||
tt_uint_op(state, OP_EQ, GUARD_CIRC_STATE_USABLE_ON_COMPLETION);
|
||||
@@ -2210,7 +2210,7 @@ test_entry_guard_select_for_circuit_no_confirmed(void *arg)
|
||||
guard->unreachable_since = approx_time() - 30;
|
||||
});
|
||||
state = 9999;
|
||||
g2 = select_entry_guard_for_circuit(gs, &state);
|
||||
g2 = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_assert(g2);
|
||||
tt_assert(!g2->is_primary);
|
||||
tt_int_op(g2->confirmed_idx, OP_EQ, -1);
|
||||
@@ -2254,7 +2254,7 @@ test_entry_guard_select_for_circuit_confirmed(void *arg)
|
||||
unsigned state = 9999;
|
||||
|
||||
// As above, this gives us a primary guard.
|
||||
entry_guard_t *g = select_entry_guard_for_circuit(gs, &state);
|
||||
entry_guard_t *g = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_assert(g);
|
||||
tt_assert(g->is_primary);
|
||||
tt_int_op(g->confirmed_idx, OP_EQ, 0);
|
||||
@@ -2271,7 +2271,7 @@ test_entry_guard_select_for_circuit_confirmed(void *arg)
|
||||
|
||||
// ... we should get a confirmed guard.
|
||||
state = 9999;
|
||||
g = select_entry_guard_for_circuit(gs, &state);
|
||||
g = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_assert(g);
|
||||
tt_assert(! g->is_primary);
|
||||
tt_int_op(g->confirmed_idx, OP_EQ, smartlist_len(gs->primary_entry_guards));
|
||||
@@ -2282,7 +2282,7 @@ test_entry_guard_select_for_circuit_confirmed(void *arg)
|
||||
// And if we try again, we should get a different confirmed guard, since
|
||||
// that one is pending.
|
||||
state = 9999;
|
||||
entry_guard_t *g2 = select_entry_guard_for_circuit(gs, &state);
|
||||
entry_guard_t *g2 = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_assert(g2);
|
||||
tt_assert(! g2->is_primary);
|
||||
tt_ptr_op(g2, OP_NE, g);
|
||||
@@ -2297,12 +2297,12 @@ test_entry_guard_select_for_circuit_confirmed(void *arg)
|
||||
const int n_remaining_confirmed =
|
||||
N_CONFIRMED - 2 - smartlist_len(gs->primary_entry_guards);
|
||||
for (i = 0; i < n_remaining_confirmed; ++i) {
|
||||
g = select_entry_guard_for_circuit(gs, &state);
|
||||
g = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_int_op(g->confirmed_idx, OP_GE, 0);
|
||||
tt_assert(g);
|
||||
}
|
||||
state = 9999;
|
||||
g = select_entry_guard_for_circuit(gs, &state);
|
||||
g = select_entry_guard_for_circuit(gs, NULL, &state);
|
||||
tt_assert(g);
|
||||
tt_assert(g->is_pending);
|
||||
tt_int_op(g->confirmed_idx, OP_EQ, -1);
|
||||
@@ -2329,7 +2329,7 @@ test_entry_guard_select_for_circuit_highlevel_primary(void *arg)
|
||||
* Make sure that the pick-for-circuit API basically works. We'll get
|
||||
* a primary guard, so it'll be usable on completion.
|
||||
*/
|
||||
int r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
int r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
|
||||
tt_assert(r == 0);
|
||||
tt_assert(node);
|
||||
@@ -2361,7 +2361,7 @@ test_entry_guard_select_for_circuit_highlevel_primary(void *arg)
|
||||
/* Try again. We'll also get a primary guard this time. (The same one,
|
||||
in fact.) But this time, we'll say the connection has failed. */
|
||||
update_approx_time(start+35);
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(r == 0);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
@@ -2396,7 +2396,7 @@ test_entry_guard_select_for_circuit_highlevel_primary(void *arg)
|
||||
* (still primary) guard.
|
||||
*/
|
||||
update_approx_time(start+60);
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(r == 0);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
@@ -2448,7 +2448,7 @@ test_entry_guard_select_for_circuit_highlevel_confirm_other(void *arg)
|
||||
|
||||
/* Primary guards are down! */
|
||||
for (i = 0; i < N_PRIMARY; ++i) {
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
tt_assert(r == 0);
|
||||
@@ -2461,7 +2461,7 @@ test_entry_guard_select_for_circuit_highlevel_confirm_other(void *arg)
|
||||
|
||||
/* Next guard should be non-primary. */
|
||||
node = NULL;
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
tt_assert(r == 0);
|
||||
@@ -2513,7 +2513,7 @@ test_entry_guard_select_for_circuit_highlevel_primary_retry(void *arg)
|
||||
/* Make primary guards confirmed (so they won't be superseded by a later
|
||||
* guard), then mark them down. */
|
||||
for (i = 0; i < N_PRIMARY; ++i) {
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
tt_assert(r == 0);
|
||||
@@ -2529,7 +2529,7 @@ test_entry_guard_select_for_circuit_highlevel_primary_retry(void *arg)
|
||||
}
|
||||
|
||||
/* Get another guard that we might try. */
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
tt_assert(r == 0);
|
||||
@@ -2556,7 +2556,7 @@ test_entry_guard_select_for_circuit_highlevel_primary_retry(void *arg)
|
||||
});
|
||||
|
||||
/* Have a circuit to a primary guard succeed. */
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard2);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard2);
|
||||
tt_assert(r == 0);
|
||||
tt_int_op(guard2->state, OP_EQ, GUARD_CIRC_STATE_USABLE_ON_COMPLETION);
|
||||
u = entry_guard_succeeded(&guard2);
|
||||
@@ -2585,7 +2585,7 @@ test_entry_guard_select_and_cancel(void *arg)
|
||||
/* Once more, we mark all the primary guards down. */
|
||||
entry_guards_note_internet_connectivity(gs);
|
||||
for (i = 0; i < N_PRIMARY; ++i) {
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_int_op(guard->state, OP_EQ, GUARD_CIRC_STATE_USABLE_ON_COMPLETION);
|
||||
g = entry_guard_handle_get(guard->guard);
|
||||
tt_int_op(g->is_primary, OP_EQ, 1);
|
||||
@@ -2600,7 +2600,7 @@ test_entry_guard_select_and_cancel(void *arg)
|
||||
tt_assert(entry_guards_all_primary_guards_are_down(gs));
|
||||
|
||||
/* Now get another guard we could try... */
|
||||
r = entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
r = entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
tt_assert(node);
|
||||
tt_assert(guard);
|
||||
tt_assert(r == 0);
|
||||
@@ -2659,7 +2659,7 @@ upgrade_circuits_setup(const struct testcase_t *testcase)
|
||||
data->start = approx_time();
|
||||
entry_guards_note_internet_connectivity(gs);
|
||||
for (i = 0; i < N_PRIMARY; ++i) {
|
||||
entry_guard_pick_for_circuit(gs, &node, &guard);
|
||||
entry_guard_pick_for_circuit(gs, NULL, &node, &guard);
|
||||
g = entry_guard_handle_get(guard->guard);
|
||||
make_guard_confirmed(gs, g);
|
||||
entry_guard_failed(&guard);
|
||||
@@ -2670,7 +2670,7 @@ upgrade_circuits_setup(const struct testcase_t *testcase)
|
||||
data->all_origin_circuits = smartlist_new();
|
||||
|
||||
update_approx_time(data->start + 27);
|
||||
entry_guard_pick_for_circuit(gs, &node, &data->guard1_state);
|
||||
entry_guard_pick_for_circuit(gs, NULL, &node, &data->guard1_state);
|
||||
origin_circuit_t *circ;
|
||||
data->circ1 = circ = origin_circuit_new();
|
||||
circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
|
||||
@@ -2678,7 +2678,7 @@ upgrade_circuits_setup(const struct testcase_t *testcase)
|
||||
smartlist_add(data->all_origin_circuits, circ);
|
||||
|
||||
update_approx_time(data->start + 30);
|
||||
entry_guard_pick_for_circuit(gs, &node, &data->guard2_state);
|
||||
entry_guard_pick_for_circuit(gs, NULL, &node, &data->guard2_state);
|
||||
data->circ2 = circ = origin_circuit_new();
|
||||
circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
|
||||
circ->guard_state = data->guard2_state;
|
||||
|
||||
Reference in New Issue
Block a user