Add networkstatus_consensus_has_ipv6() and unit tests

networkstatus_consensus_has_ipv6() tells us whether the consensus method of
our current consensus supports IPv6 ORPorts in the consensus.

Part of #23827.
This commit is contained in:
teor 2017-12-02 23:01:07 +11:00
parent 241b676638
commit 28d4355a6e
No known key found for this signature in database
GPG Key ID: 740D9E39025272A2
3 changed files with 123 additions and 0 deletions

View File

@ -1507,6 +1507,32 @@ networkstatus_consensus_is_already_downloading(const char *resource)
return answer;
}
/* Does the current, reasonably live consensus have IPv6 addresses?
* Returns 1 if there is a reasonably live consensus and its consensus method
* includes IPv6 addresses in the consensus.
* Otherwise, if there is no consensus, or the method does not include IPv6
* addresses, returns 0. */
int
networkstatus_consensus_has_ipv6(const or_options_t* options)
{
const networkstatus_t *cons = networkstatus_get_reasonably_live_consensus(
approx_time(),
usable_consensus_flavor());
/* If we have no consensus, we have no IPv6 in it */
if (!cons) {
return 0;
}
/* Different flavours of consensus gained IPv6 at different times */
if (we_use_microdescriptors_for_circuits(options)) {
return
cons->consensus_method >= MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
} else {
return cons->consensus_method >= MIN_METHOD_FOR_A_LINES;
}
}
/** Given two router status entries for the same router identity, return 1 if
* if the contents have changed between them. Otherwise, return 0. */
static int

View File

@ -93,6 +93,7 @@ int networkstatus_consensus_can_use_multiple_directories(
MOCK_DECL(int, networkstatus_consensus_can_use_extra_fallbacks,(
const or_options_t *options));
int networkstatus_consensus_is_already_downloading(const char *resource);
int networkstatus_consensus_has_ipv6(const or_options_t* options);
#define NSSET_FROM_CACHE 1
#define NSSET_WAS_WAITING_FOR_CERTS 2

View File

@ -6174,6 +6174,101 @@ test_dir_platform_str(void *arg)
;
}
static networkstatus_t *mock_networkstatus;
static networkstatus_t *
mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
{
(void)f;
return mock_networkstatus;
}
static void
test_dir_networkstatus_consensus_has_ipv6(void *arg)
{
(void)arg;
int has_ipv6 = 0;
/* Init options and networkstatus */
or_options_t our_options;
mock_options = &our_options;
reset_options(mock_options, &mock_get_options_calls);
MOCK(get_options, mock_get_options);
networkstatus_t our_networkstatus;
mock_networkstatus = &our_networkstatus;
memset(mock_networkstatus, 0, sizeof(*mock_networkstatus));
MOCK(networkstatus_get_latest_consensus_by_flavor,
mock_networkstatus_get_latest_consensus_by_flavor);
/* A live consensus */
mock_networkstatus->valid_after = time(NULL) - 3600;
mock_networkstatus->valid_until = time(NULL) + 3600;
/* Test the bounds for A lines in the NS consensus */
mock_options->UseMicrodescriptors = 0;
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 1;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 20;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES - 1;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(!has_ipv6);
/* Test the bounds for A lines in the microdesc consensus */
mock_options->UseMicrodescriptors = 1;
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 1;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 20;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS - 1;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(!has_ipv6);
/* Test the edge cases */
mock_options->UseMicrodescriptors = 1;
mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
/* Reasonably live */
mock_networkstatus->valid_until = time(NULL) - 60;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
/* Not reasonably live */
mock_networkstatus->valid_after = time(NULL) - 24*60*60 - 3600;
mock_networkstatus->valid_until = time(NULL) - 24*60*60 - 60;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(!has_ipv6);
/* NULL consensus */
mock_networkstatus = NULL;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(!has_ipv6);
done:
UNMOCK(get_options);
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
}
#define DIR_LEGACY(name) \
{ #name, test_dir_ ## name , TT_FORK, NULL, NULL }
@ -6241,6 +6336,7 @@ struct testcase_t dir_tests[] = {
DIR(assumed_flags, 0),
DIR(networkstatus_compute_bw_weights_v10, 0),
DIR(platform_str, 0),
DIR(networkstatus_consensus_has_ipv6, 0),
END_OF_TESTCASES
};