mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 06:48:05 +01:00
Merge remote-tracking branch 'asn/bug12202'
This commit is contained in:
commit
368ff2291b
3 changed files with 112 additions and 10 deletions
|
@ -190,12 +190,16 @@ entry_is_time_to_retry(const entry_guard_t *e, time_t now)
|
||||||
* If need_descriptor is true, only return the node if we currently have
|
* If need_descriptor is true, only return the node if we currently have
|
||||||
* a descriptor (routerinfo or microdesc) for it.
|
* a descriptor (routerinfo or microdesc) for it.
|
||||||
*/
|
*/
|
||||||
static INLINE const node_t *
|
STATIC INLINE const node_t *
|
||||||
entry_is_live(const entry_guard_t *e, int need_uptime, int need_capacity,
|
entry_is_live(const entry_guard_t *e, entry_is_live_flags_t flags, const char **msg)
|
||||||
int assume_reachable, int need_descriptor, const char **msg)
|
|
||||||
{
|
{
|
||||||
const node_t *node;
|
const node_t *node;
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
|
int need_uptime = (flags & ENTRY_NEED_UPTIME) != 0;
|
||||||
|
int need_capacity = (flags & ENTRY_NEED_CAPACITY) != 0;
|
||||||
|
const int assume_reachable = (flags & ENTRY_ASSUME_REACHABLE) != 0;
|
||||||
|
const int need_descriptor = (flags & ENTRY_NEED_DESCRIPTOR) != 0;
|
||||||
|
|
||||||
tor_assert(msg);
|
tor_assert(msg);
|
||||||
|
|
||||||
if (e->path_bias_disabled) {
|
if (e->path_bias_disabled) {
|
||||||
|
@ -257,12 +261,18 @@ num_live_entry_guards(int for_directory)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
/* Set the entry node attributes we are interested in. */
|
||||||
|
entry_is_live_flags_t entry_flags = ENTRY_NEED_CAPACITY;
|
||||||
|
if (!for_directory) {
|
||||||
|
entry_flags |= ENTRY_NEED_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
if (! entry_guards)
|
if (! entry_guards)
|
||||||
return 0;
|
return 0;
|
||||||
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
|
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
|
||||||
if (for_directory && !entry->is_dir_cache)
|
if (for_directory && !entry->is_dir_cache)
|
||||||
continue;
|
continue;
|
||||||
if (entry_is_live(entry, 0, 1, 0, !for_directory, &msg))
|
if (entry_is_live(entry, entry_flags, &msg))
|
||||||
++n;
|
++n;
|
||||||
} SMARTLIST_FOREACH_END(entry);
|
} SMARTLIST_FOREACH_END(entry);
|
||||||
return n;
|
return n;
|
||||||
|
@ -291,7 +301,7 @@ log_entry_guards(int severity)
|
||||||
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e)
|
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e)
|
||||||
{
|
{
|
||||||
const char *msg = NULL;
|
const char *msg = NULL;
|
||||||
if (entry_is_live(e, 0, 1, 0, 0, &msg))
|
if (entry_is_live(e, ENTRY_NEED_CAPACITY, &msg))
|
||||||
smartlist_add_asprintf(elements, "%s [%s] (up %s)",
|
smartlist_add_asprintf(elements, "%s [%s] (up %s)",
|
||||||
e->nickname,
|
e->nickname,
|
||||||
hex_str(e->identity, DIGEST_LEN),
|
hex_str(e->identity, DIGEST_LEN),
|
||||||
|
@ -667,7 +677,7 @@ entry_guards_compute_status(const or_options_t *options, time_t now)
|
||||||
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
|
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
|
||||||
const char *reason = digestmap_get(reasons, entry->identity);
|
const char *reason = digestmap_get(reasons, entry->identity);
|
||||||
const char *live_msg = "";
|
const char *live_msg = "";
|
||||||
const node_t *r = entry_is_live(entry, 0, 1, 0, 0, &live_msg);
|
const node_t *r = entry_is_live(entry, ENTRY_NEED_CAPACITY, &live_msg);
|
||||||
log_info(LD_CIRC, "Summary: Entry %s [%s] is %s, %s%s%s, and %s%s.",
|
log_info(LD_CIRC, "Summary: Entry %s [%s] is %s, %s%s%s, and %s%s.",
|
||||||
entry->nickname,
|
entry->nickname,
|
||||||
hex_str(entry->identity, DIGEST_LEN),
|
hex_str(entry->identity, DIGEST_LEN),
|
||||||
|
@ -785,7 +795,9 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
|
||||||
break;
|
break;
|
||||||
if (e->made_contact) {
|
if (e->made_contact) {
|
||||||
const char *msg;
|
const char *msg;
|
||||||
const node_t *r = entry_is_live(e, 0, 1, 1, 0, &msg);
|
const node_t *r = entry_is_live(e,
|
||||||
|
ENTRY_NEED_CAPACITY | ENTRY_ASSUME_REACHABLE,
|
||||||
|
&msg);
|
||||||
if (r && e->unreachable_since) {
|
if (r && e->unreachable_since) {
|
||||||
refuse_conn = 1;
|
refuse_conn = 1;
|
||||||
e->can_retry = 1;
|
e->can_retry = 1;
|
||||||
|
@ -1029,7 +1041,19 @@ populate_live_entry_guards(smartlist_t *live_entry_guards,
|
||||||
const int num_needed = decide_num_guards(options, for_directory);
|
const int num_needed = decide_num_guards(options, for_directory);
|
||||||
smartlist_t *exit_family = smartlist_new();
|
smartlist_t *exit_family = smartlist_new();
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int need_descriptor = !for_directory;
|
entry_is_live_flags_t entry_flags = 0;
|
||||||
|
|
||||||
|
{ /* Set the flags we want our entry node to have */
|
||||||
|
if (need_uptime) {
|
||||||
|
entry_flags |= ENTRY_NEED_UPTIME;
|
||||||
|
}
|
||||||
|
if (need_capacity) {
|
||||||
|
entry_flags |= ENTRY_NEED_CAPACITY;
|
||||||
|
}
|
||||||
|
if (!for_directory) {
|
||||||
|
entry_flags |= ENTRY_NEED_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tor_assert(all_entry_guards);
|
tor_assert(all_entry_guards);
|
||||||
|
|
||||||
|
@ -1039,8 +1063,7 @@ populate_live_entry_guards(smartlist_t *live_entry_guards,
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry) {
|
SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry) {
|
||||||
const char *msg;
|
const char *msg;
|
||||||
node = entry_is_live(entry, need_uptime, need_capacity, 0,
|
node = entry_is_live(entry, entry_flags, &msg);
|
||||||
need_descriptor, &msg);
|
|
||||||
if (!node)
|
if (!node)
|
||||||
continue; /* down, no point */
|
continue; /* down, no point */
|
||||||
if (for_directory) {
|
if (for_directory) {
|
||||||
|
|
|
@ -91,6 +91,19 @@ STATIC int populate_live_entry_guards(smartlist_t *live_entry_guards,
|
||||||
STATIC int decide_num_guards(const or_options_t *options, int for_directory);
|
STATIC int decide_num_guards(const or_options_t *options, int for_directory);
|
||||||
|
|
||||||
STATIC void entry_guards_set_from_config(const or_options_t *options);
|
STATIC void entry_guards_set_from_config(const or_options_t *options);
|
||||||
|
|
||||||
|
/** Flags to be passed to entry_is_live() to indicate what kind of
|
||||||
|
* entry nodes we are looking for. */
|
||||||
|
typedef enum {
|
||||||
|
ENTRY_NEED_UPTIME = 1<<0,
|
||||||
|
ENTRY_NEED_CAPACITY = 1<<1,
|
||||||
|
ENTRY_ASSUME_REACHABLE = 1<<2,
|
||||||
|
ENTRY_NEED_DESCRIPTOR = 1<<3,
|
||||||
|
} entry_is_live_flags_t;
|
||||||
|
|
||||||
|
STATIC INLINE const node_t *entry_is_live(const entry_guard_t *e,
|
||||||
|
entry_is_live_flags_t flags,
|
||||||
|
const char **msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void remove_all_entry_guards(void);
|
void remove_all_entry_guards(void);
|
||||||
|
|
|
@ -544,6 +544,69 @@ test_entry_guards_set_from_config(void *arg)
|
||||||
routerset_free(options->EntryNodes);
|
routerset_free(options->EntryNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** XXX Do some tests that entry_is_live() */
|
||||||
|
static void
|
||||||
|
test_entry_is_live(void *arg)
|
||||||
|
{
|
||||||
|
smartlist_t *our_nodelist = NULL;
|
||||||
|
const smartlist_t *all_entry_guards = get_entry_guards();
|
||||||
|
const node_t *test_node = NULL;
|
||||||
|
const entry_guard_t *test_entry = NULL;
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
/* The global entry guards smartlist should be empty now. */
|
||||||
|
tt_int_op(smartlist_len(all_entry_guards), ==, 0);
|
||||||
|
|
||||||
|
/* Walk the nodelist and add all nodes as entry guards. */
|
||||||
|
our_nodelist = nodelist_get_list();
|
||||||
|
tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
|
||||||
|
const node_t *node_tmp;
|
||||||
|
node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
|
||||||
|
test_assert(node_tmp);
|
||||||
|
|
||||||
|
tt_int_op(node->is_stable, ==, 0);
|
||||||
|
tt_int_op(node->is_fast, ==, 0);
|
||||||
|
} SMARTLIST_FOREACH_END(node);
|
||||||
|
|
||||||
|
/* Make sure the nodes were added as entry guards. */
|
||||||
|
tt_int_op(smartlist_len(all_entry_guards), ==, NUMBER_OF_DESCRIPTORS);
|
||||||
|
|
||||||
|
/* Now get a random test entry that we will use for this unit test. */
|
||||||
|
test_entry = smartlist_get(all_entry_guards, 3); /* chosen by fair dice roll */
|
||||||
|
|
||||||
|
/* Let's do some entry_is_live() tests! */
|
||||||
|
|
||||||
|
/* Require the node to be stable, but it's not. Should fail.
|
||||||
|
Also enable 'assume_reachable' because why not. */
|
||||||
|
test_node = entry_is_live(test_entry,
|
||||||
|
ENTRY_NEED_UPTIME | ENTRY_ASSUME_REACHABLE,
|
||||||
|
&msg);
|
||||||
|
test_assert(!test_node);
|
||||||
|
|
||||||
|
/* Require the node to be fast, but it's not. Should fail. */
|
||||||
|
test_node = entry_is_live(test_entry,
|
||||||
|
ENTRY_NEED_CAPACITY | ENTRY_ASSUME_REACHABLE,
|
||||||
|
&msg);
|
||||||
|
test_assert(!test_node);
|
||||||
|
|
||||||
|
/* Don't impose any restrictions on the node. Should succeed. */
|
||||||
|
test_node = entry_is_live(test_entry, 0, &msg);
|
||||||
|
test_assert(test_node);
|
||||||
|
tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
|
||||||
|
|
||||||
|
/* Require descriptor for this node. It has one so it should succeed. */
|
||||||
|
test_node = entry_is_live(test_entry, ENTRY_NEED_DESCRIPTOR, &msg);
|
||||||
|
test_assert(test_node);
|
||||||
|
tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
|
||||||
|
|
||||||
|
done:
|
||||||
|
; /* XXX */
|
||||||
|
}
|
||||||
|
|
||||||
static const struct testcase_setup_t fake_network = {
|
static const struct testcase_setup_t fake_network = {
|
||||||
fake_network_setup, fake_network_cleanup
|
fake_network_setup, fake_network_cleanup
|
||||||
};
|
};
|
||||||
|
@ -569,6 +632,9 @@ struct testcase_t entrynodes_tests[] = {
|
||||||
{ "entry_guards_set_from_config",
|
{ "entry_guards_set_from_config",
|
||||||
test_entry_guards_set_from_config,
|
test_entry_guards_set_from_config,
|
||||||
TT_FORK, &fake_network, NULL },
|
TT_FORK, &fake_network, NULL },
|
||||||
|
{ "entry_is_live",
|
||||||
|
test_entry_is_live,
|
||||||
|
TT_FORK, &fake_network, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue