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
;
}
+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 }
DIR(assumed_flags, 0),
DIR(networkstatus_compute_bw_weights_v10, 0),
DIR(platform_str, 0),
+ DIR(networkstatus_consensus_has_ipv6, 0),
END_OF_TESTCASES
};