summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/aes.c4
-rw-r--r--src/common/crypto.c16
-rw-r--r--src/common/torint.h2
-rw-r--r--src/common/tortls.c19
-rw-r--r--src/or/circuitbuild.c9
-rw-r--r--src/or/config.c95
-rw-r--r--src/or/confparse.c80
-rw-r--r--src/or/confparse.h6
-rw-r--r--src/or/directory.c66
-rw-r--r--src/or/directory.h4
-rw-r--r--src/or/entrynodes.c16
-rw-r--r--src/or/hs_common.c27
-rw-r--r--src/or/hs_common.h13
-rw-r--r--src/or/hs_control.c3
-rw-r--r--src/or/hs_service.c32
-rw-r--r--src/or/hs_service.h1
-rw-r--r--src/or/main.c59
-rw-r--r--src/or/main.h1
-rw-r--r--src/or/nodelist.c16
-rw-r--r--src/or/or.h47
-rw-r--r--src/or/periodic.h1
-rw-r--r--src/or/policies.c98
-rw-r--r--src/or/policies.h14
-rw-r--r--src/or/rendservice.c11
-rw-r--r--src/or/rephist.c2
-rw-r--r--src/or/statefile.c13
-rw-r--r--src/or/statefile.h1
-rw-r--r--src/test/test_dir.c127
-rw-r--r--src/test/test_entrynodes.c19
-rw-r--r--src/test/test_hs_control.c5
-rw-r--r--src/test/test_options.c12
-rw-r--r--src/test/test_periodic_event.c97
-rw-r--r--src/test/test_policy.c14
-rw-r--r--src/test/test_tortls.c41
34 files changed, 567 insertions, 404 deletions
diff --git a/src/common/aes.c b/src/common/aes.c
index 5d0841dfa3..95737cffcc 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -116,7 +116,11 @@ aes_cipher_free_(aes_cnt_cipher_t *cipher_)
if (!cipher_)
return;
EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ EVP_CIPHER_CTX_reset(cipher);
+#else
EVP_CIPHER_CTX_cleanup(cipher);
+#endif
EVP_CIPHER_CTX_free(cipher);
}
void
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 9fcd17742c..c98a968757 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -43,6 +43,7 @@ DISABLE_GCC_WARNING(redundant-decls)
#include <openssl/dh.h>
#include <openssl/conf.h>
#include <openssl/hmac.h>
+#include <openssl/ssl.h>
ENABLE_GCC_WARNING(redundant-decls)
@@ -204,8 +205,15 @@ crypto_early_init(void)
crypto_early_initialized_ = 1;
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
+ OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
+ OPENSSL_INIT_ADD_ALL_CIPHERS |
+ OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+#else
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
+#endif
setup_openssl_threading();
@@ -1660,11 +1668,15 @@ memwipe(void *mem, uint8_t byte, size_t sz)
int
crypto_global_cleanup(void)
{
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
EVP_cleanup();
+#endif
#ifndef NEW_THREAD_API
ERR_remove_thread_state(NULL);
#endif
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
ERR_free_strings();
+#endif
if (dh_param_p)
BN_clear_free(dh_param_p);
@@ -1676,11 +1688,15 @@ crypto_global_cleanup(void)
dh_param_p = dh_param_p_tls = dh_param_g = NULL;
#ifndef DISABLE_ENGINES
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
ENGINE_cleanup();
#endif
+#endif
CONF_modules_unload(1);
+#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
CRYPTO_cleanup_all_ex_data();
+#endif
crypto_openssl_free_all();
diff --git a/src/common/torint.h b/src/common/torint.h
index 0b8061d24f..fc7818fe2c 100644
--- a/src/common/torint.h
+++ b/src/common/torint.h
@@ -40,6 +40,8 @@
#include <inttypes.h>
#endif
+#include <stdbool.h>
+
#if (SIZEOF_INT8_T != 0)
#define HAVE_INT8_T
#endif
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 05e29e22ff..cd236363f8 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -56,10 +56,25 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "container.h"
#include <string.h>
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+#define X509_get_notBefore_const(cert) \
+ X509_get0_notBefore(cert)
+#define X509_get_notAfter_const(cert) \
+ X509_get0_notAfter(cert)
+#ifndef X509_get_notBefore
+#define X509_get_notBefore(cert) \
+ X509_getm_notBefore(cert)
+#endif
+#ifndef X509_get_notAfter
+#define X509_get_notAfter(cert) \
+ X509_getm_notAfter(cert)
+#endif
+#else /* ! OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */
#define X509_get_notBefore_const(cert) \
((const ASN1_TIME*) X509_get_notBefore((X509 *)cert))
#define X509_get_notAfter_const(cert) \
((const ASN1_TIME*) X509_get_notAfter((X509 *)cert))
+#endif
/* Copied from or.h */
#define LEGAL_NICKNAME_CHARACTERS \
@@ -355,8 +370,12 @@ tor_tls_init(void)
check_no_tls_errors();
if (!tls_library_is_initialized) {
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+#else
SSL_library_init();
SSL_load_error_strings();
+#endif
#if (SIZEOF_VOID_P >= 8 && \
OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,1))
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index c33dbbeb2d..24c32b710c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2802,16 +2802,13 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
return NULL;
}
- /* Choose a preferred address first, but fall back to an allowed address.
- * choose_address returns 1 on success, but get_prim_orport returns 0. */
+ /* Choose a preferred address first, but fall back to an allowed address. */
if (for_direct_connect)
- valid_addr = fascist_firewall_choose_address_node(node,
- FIREWALL_OR_CONNECTION,
- 0, &ap);
+ fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
else {
node_get_prim_orport(node, &ap);
- valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
}
+ valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
if (valid_addr)
log_debug(LD_CIRC, "using %s for %s",
diff --git a/src/or/config.c b/src/or/config.c
index 8f5839e2d5..3719ac8847 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -127,6 +127,11 @@ static const char unix_socket_prefix[] = "unix:";
* configuration. */
static const char unix_q_socket_prefix[] = "unix:\"";
+/** macro to help with the bulk rename of *DownloadSchedule to
+ * *DowloadInitialDelay . */
+#define DOWNLOAD_SCHEDULE(name) \
+ { #name "DownloadSchedule", #name "DownloadInitialDelay", 0, 1 }
+
/** A list of abbreviations and aliases to map command-line options, obsolete
* option names, or alternative option names, to their current values. */
static config_abbrev_t option_abbrevs_[] = {
@@ -176,6 +181,16 @@ static config_abbrev_t option_abbrevs_[] = {
{ "_HSLayer2Nodes", "HSLayer2Nodes", 0, 1 },
{ "_HSLayer3Nodes", "HSLayer3Nodes", 0, 1 },
+ DOWNLOAD_SCHEDULE(ClientBootstrapConsensusAuthority),
+ DOWNLOAD_SCHEDULE(ClientBootstrapConsensusAuthorityOnly),
+ DOWNLOAD_SCHEDULE(ClientBootstrapConsensusFallback),
+ DOWNLOAD_SCHEDULE(TestingBridge),
+ DOWNLOAD_SCHEDULE(TestingBridgeBootstrap),
+ DOWNLOAD_SCHEDULE(TestingClient),
+ DOWNLOAD_SCHEDULE(TestingClientConsensus),
+ DOWNLOAD_SCHEDULE(TestingServer),
+ DOWNLOAD_SCHEDULE(TestingServerConsensus),
+
{ NULL, NULL, 0, 0},
};
@@ -458,6 +473,7 @@ static config_var_t option_vars_[] = {
V(NumCPUs, UINT, "0"),
V(NumDirectoryGuards, UINT, "0"),
V(NumEntryGuards, UINT, "0"),
+ V(NumPrimaryGuards, UINT, "0"),
V(OfflineMasterKey, BOOL, "0"),
OBSOLETE("ORListenAddress"),
VPORT(ORPort),
@@ -600,16 +616,10 @@ static config_var_t option_vars_[] = {
VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL),
VAR("__OwningControllerFD",INT,OwningControllerFD, "-1"),
V(MinUptimeHidServDirectoryV2, INTERVAL, "96 hours"),
- V(TestingServerDownloadSchedule, CSV_INTERVAL, "0, 0, 0, 60, 60, 120, "
- "300, 900, 2147483647"),
- V(TestingClientDownloadSchedule, CSV_INTERVAL, "0, 0, 60, 300, 600, "
- "2147483647"),
- V(TestingServerConsensusDownloadSchedule, CSV_INTERVAL, "0, 0, 60, "
- "300, 600, 1800, 1800, 1800, 1800, "
- "1800, 3600, 7200"),
- V(TestingClientConsensusDownloadSchedule, CSV_INTERVAL, "0, 0, 60, "
- "300, 600, 1800, 3600, 3600, 3600, "
- "10800, 21600, 43200"),
+ V(TestingServerDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingClientDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingServerConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingClientConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
/* With the ClientBootstrapConsensus*Download* below:
* Clients with only authorities will try:
* - at least 3 authorities over 10 seconds, then exponentially backoff,
@@ -625,13 +635,11 @@ static config_var_t option_vars_[] = {
*
* When clients have authorities and fallbacks available, they use these
* schedules: (we stagger the times to avoid thundering herds) */
- V(ClientBootstrapConsensusAuthorityDownloadSchedule, CSV_INTERVAL,
- "6, 11, 3600, 10800, 25200, 54000, 111600, 262800" /* 3 days + 1 hour */),
- V(ClientBootstrapConsensusFallbackDownloadSchedule, CSV_INTERVAL,
- "0, 1, 4, 11, 3600, 10800, 25200, 54000, 111600, 262800"),
+ V(ClientBootstrapConsensusAuthorityDownloadInitialDelay, CSV_INTERVAL, "6"),
+ V(ClientBootstrapConsensusFallbackDownloadInitialDelay, CSV_INTERVAL, "0"),
/* When clients only have authorities available, they use this schedule: */
- V(ClientBootstrapConsensusAuthorityOnlyDownloadSchedule, CSV_INTERVAL,
- "0, 3, 7, 3600, 10800, 25200, 54000, 111600, 262800"),
+ V(ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay, CSV_INTERVAL,
+ "0"),
/* We don't want to overwhelm slow networks (or mirrors whose replies are
* blocked), but we also don't want to fail if only some mirrors are
* blackholed. Clients will try 3 directories simultaneously.
@@ -639,14 +647,12 @@ static config_var_t option_vars_[] = {
V(ClientBootstrapConsensusMaxInProgressTries, UINT, "3"),
/* When a client has any running bridges, check each bridge occasionally,
* whether or not that bridge is actually up. */
- V(TestingBridgeDownloadSchedule, CSV_INTERVAL,
- "10800, 25200, 54000, 111600, 262800"),
+ V(TestingBridgeDownloadInitialDelay, CSV_INTERVAL,"10800"),
/* When a client is just starting, or has no running bridges, check each
* bridge a few times quickly, and then try again later. These schedules
* are much longer than the other schedules, because we try each and every
* configured bridge with this schedule. */
- V(TestingBridgeBootstrapDownloadSchedule, CSV_INTERVAL,
- "0, 30, 90, 600, 3600, 10800, 25200, 54000, 111600, 262800"),
+ V(TestingBridgeBootstrapDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "10 minutes"),
V(TestingDirConnectionMaxStall, INTERVAL, "5 minutes"),
OBSOLETE("TestingConsensusMaxDownloadTries"),
@@ -673,12 +679,10 @@ static const config_var_t testing_tor_network_defaults[] = {
V(EnforceDistinctSubnets, BOOL, "0"),
V(AssumeReachable, BOOL, "1"),
V(AuthDirMaxServersPerAddr, UINT, "0"),
- V(ClientBootstrapConsensusAuthorityDownloadSchedule, CSV_INTERVAL,
- "0, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
- V(ClientBootstrapConsensusFallbackDownloadSchedule, CSV_INTERVAL,
- "0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
- V(ClientBootstrapConsensusAuthorityOnlyDownloadSchedule, CSV_INTERVAL,
- "0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
+ V(ClientBootstrapConsensusAuthorityDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(ClientBootstrapConsensusFallbackDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay, CSV_INTERVAL,
+ "0"),
V(ClientDNSRejectInternalAddresses, BOOL,"0"),
V(ClientRejectInternalAddresses, BOOL, "0"),
V(CountPrivateBandwidth, BOOL, "1"),
@@ -693,17 +697,12 @@ static const config_var_t testing_tor_network_defaults[] = {
V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
- V(TestingServerDownloadSchedule, CSV_INTERVAL, "0, 0, 0, 5, 10, 15, "
- "20, 30, 60"),
- V(TestingClientDownloadSchedule, CSV_INTERVAL, "0, 0, 5, 10, 15, 20, "
- "30, 60"),
- V(TestingServerConsensusDownloadSchedule, CSV_INTERVAL, "0, 0, 5, 10, "
- "15, 20, 30, 60"),
- V(TestingClientConsensusDownloadSchedule, CSV_INTERVAL, "0, 0, 5, 10, "
- "15, 20, 30, 60"),
- V(TestingBridgeDownloadSchedule, CSV_INTERVAL, "10, 30, 60"),
- V(TestingBridgeBootstrapDownloadSchedule, CSV_INTERVAL, "0, 0, 5, 10, "
- "15, 20, 30, 60"),
+ V(TestingServerDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingClientDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingServerConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingClientConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
+ V(TestingBridgeDownloadInitialDelay, CSV_INTERVAL, "10"),
+ V(TestingBridgeBootstrapDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "5 seconds"),
V(TestingDirConnectionMaxStall, INTERVAL, "30 seconds"),
V(TestingEnableConnBwEvent, BOOL, "1"),
@@ -3776,6 +3775,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
"http://freehaven.net/anonbib/#hs-attack06 for details.");
}
+ if (options->NumPrimaryGuards && options->NumEntryGuards &&
+ options->NumEntryGuards > options->NumPrimaryGuards) {
+ REJECT("NumEntryGuards must not be greater than NumPrimaryGuards.");
+ }
+
if (options->EntryNodes &&
routerset_is_list(options->EntryNodes) &&
(routerset_len(options->EntryNodes) == 1) &&
@@ -4374,12 +4378,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
CHECK_DEFAULT(TestingV3AuthVotingStartOffset);
CHECK_DEFAULT(TestingAuthDirTimeToLearnReachability);
CHECK_DEFAULT(TestingEstimatedDescriptorPropagationTime);
- CHECK_DEFAULT(TestingServerDownloadSchedule);
- CHECK_DEFAULT(TestingClientDownloadSchedule);
- CHECK_DEFAULT(TestingServerConsensusDownloadSchedule);
- CHECK_DEFAULT(TestingClientConsensusDownloadSchedule);
- CHECK_DEFAULT(TestingBridgeDownloadSchedule);
- CHECK_DEFAULT(TestingBridgeBootstrapDownloadSchedule);
+ CHECK_DEFAULT(TestingServerDownloadInitialDelay);
+ CHECK_DEFAULT(TestingClientDownloadInitialDelay);
+ CHECK_DEFAULT(TestingServerConsensusDownloadInitialDelay);
+ CHECK_DEFAULT(TestingClientConsensusDownloadInitialDelay);
+ CHECK_DEFAULT(TestingBridgeDownloadInitialDelay);
+ CHECK_DEFAULT(TestingBridgeBootstrapDownloadInitialDelay);
CHECK_DEFAULT(TestingClientMaxIntervalWithoutRequest);
CHECK_DEFAULT(TestingDirConnectionMaxStall);
CHECK_DEFAULT(TestingAuthKeyLifetime);
@@ -8102,7 +8106,10 @@ getinfo_helper_config(control_connection_t *conn,
case CONFIG_TYPE_ISOTIME: type = "Time"; break;
case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
case CONFIG_TYPE_CSV: type = "CommaList"; break;
- case CONFIG_TYPE_CSV_INTERVAL: type = "TimeIntervalCommaList"; break;
+ /* This type accepts more inputs than TimeInterval, but it ignores
+ * everything after the first entry, so we may as well pretend
+ * it's a TimeInterval. */
+ case CONFIG_TYPE_CSV_INTERVAL: type = "TimeInterval"; break;
case CONFIG_TYPE_LINELIST: type = "LineList"; break;
case CONFIG_TYPE_LINELIST_S: type = "Dependent"; break;
case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
diff --git a/src/or/confparse.c b/src/or/confparse.c
index 64ed9ee6bb..6bab790945 100644
--- a/src/or/confparse.c
+++ b/src/or/confparse.c
@@ -162,8 +162,6 @@ config_assign_value(const config_format_t *fmt, void *options,
int i, ok;
const config_var_t *var;
void *lvalue;
- int *csv_int;
- smartlist_t *csv_str;
CONFIG_CHECK(fmt, options);
@@ -195,6 +193,30 @@ config_assign_value(const config_format_t *fmt, void *options,
*(int *)lvalue = i;
break;
+ case CONFIG_TYPE_CSV_INTERVAL: {
+ /* We used to have entire smartlists here. But now that all of our
+ * download schedules use exponential backoff, only the first part
+ * matters. */
+ const char *comma = strchr(c->value, ',');
+ const char *val = c->value;
+ char *tmp = NULL;
+ if (comma) {
+ tmp = tor_strndup(c->value, comma - c->value);
+ val = tmp;
+ }
+
+ i = config_parse_interval(val, &ok);
+ if (!ok) {
+ tor_asprintf(msg,
+ "Interval '%s %s' is malformed or out of bounds.",
+ c->key, c->value);
+ return -1;
+ }
+ *(int *)lvalue = i;
+ tor_free(tmp);
+ break;
+ }
+
case CONFIG_TYPE_INTERVAL: {
i = config_parse_interval(c->value, &ok);
if (!ok) {
@@ -298,36 +320,6 @@ config_assign_value(const config_format_t *fmt, void *options,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
break;
- case CONFIG_TYPE_CSV_INTERVAL:
- if (*(smartlist_t**)lvalue) {
- SMARTLIST_FOREACH(*(smartlist_t**)lvalue, int *, cp, tor_free(cp));
- smartlist_clear(*(smartlist_t**)lvalue);
- } else {
- *(smartlist_t**)lvalue = smartlist_new();
- }
- csv_str = smartlist_new();
- smartlist_split_string(csv_str, c->value, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- SMARTLIST_FOREACH_BEGIN(csv_str, char *, str)
- {
- i = config_parse_interval(str, &ok);
- if (!ok) {
- tor_asprintf(msg,
- "Interval in '%s %s' is malformed or out of bounds.",
- c->key, c->value);
- SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
- smartlist_free(csv_str);
- return -1;
- }
- csv_int = tor_malloc_zero(sizeof(int));
- *csv_int = i;
- smartlist_add(*(smartlist_t**)lvalue, csv_int);
- }
- SMARTLIST_FOREACH_END(str);
- SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
- smartlist_free(csv_str);
- break;
-
case CONFIG_TYPE_LINELIST:
case CONFIG_TYPE_LINELIST_S:
{
@@ -528,7 +520,6 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
const config_var_t *var;
const void *value;
config_line_t *result;
- smartlist_t *csv_str;
tor_assert(options && key);
CONFIG_CHECK(fmt, options);
@@ -571,6 +562,7 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
break;
}
/* fall through */
+ case CONFIG_TYPE_CSV_INTERVAL:
case CONFIG_TYPE_INTERVAL:
case CONFIG_TYPE_MSEC_INTERVAL:
case CONFIG_TYPE_UINT:
@@ -611,20 +603,6 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
else
result->value = tor_strdup("");
break;
- case CONFIG_TYPE_CSV_INTERVAL:
- if (*(smartlist_t**)value) {
- csv_str = smartlist_new();
- SMARTLIST_FOREACH_BEGIN(*(smartlist_t**)value, int *, i)
- {
- smartlist_add_asprintf(csv_str, "%d", *i);
- }
- SMARTLIST_FOREACH_END(i);
- result->value = smartlist_join_strings(csv_str, ",", 0, NULL);
- SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
- smartlist_free(csv_str);
- } else
- result->value = tor_strdup("");
- break;
case CONFIG_TYPE_OBSOLETE:
log_fn(LOG_INFO, LD_CONFIG,
"You asked me for the value of an obsolete config option '%s'.",
@@ -789,6 +767,7 @@ config_clear(const config_format_t *fmt, void *options,
case CONFIG_TYPE_ISOTIME:
*(time_t*)lvalue = 0;
break;
+ case CONFIG_TYPE_CSV_INTERVAL:
case CONFIG_TYPE_INTERVAL:
case CONFIG_TYPE_MSEC_INTERVAL:
case CONFIG_TYPE_UINT:
@@ -816,13 +795,6 @@ config_clear(const config_format_t *fmt, void *options,
*(smartlist_t **)lvalue = NULL;
}
break;
- case CONFIG_TYPE_CSV_INTERVAL:
- if (*(smartlist_t**)lvalue) {
- SMARTLIST_FOREACH(*(smartlist_t **)lvalue, int *, cp, tor_free(cp));
- smartlist_free(*(smartlist_t **)lvalue);
- *(smartlist_t **)lvalue = NULL;
- }
- break;
case CONFIG_TYPE_LINELIST:
case CONFIG_TYPE_LINELIST_S:
config_free_lines(*(config_line_t **)lvalue);
diff --git a/src/or/confparse.h b/src/or/confparse.h
index f1f2030343..4b4bf0adb4 100644
--- a/src/or/confparse.h
+++ b/src/or/confparse.h
@@ -28,7 +28,9 @@ typedef enum config_type_t {
* optional whitespace. */
CONFIG_TYPE_CSV_INTERVAL, /**< A list of strings, separated by commas and
* optional whitespace, representing intervals in
- * seconds, with optional units */
+ * seconds, with optional units. We allow
+ * multiple values here for legacy reasons, but
+ * ignore every value after the first. */
CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
* mixed with other keywords. */
@@ -62,7 +64,7 @@ typedef union {
int *AUTOBOOL;
time_t *ISOTIME;
smartlist_t **CSV;
- smartlist_t **CSV_INTERVAL;
+ int *CSV_INTERVAL;
config_line_t **LINELIST;
config_line_t **LINELIST_S;
config_line_t **LINELIST_V;
diff --git a/src/or/directory.c b/src/or/directory.c
index ea38f005e4..2c5ee23f3a 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -795,9 +795,9 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
* Use the preferred address and port if they are reachable, otherwise,
* use the alternate address and port (if any).
*/
- have_or = fascist_firewall_choose_address_rs(status,
- FIREWALL_OR_CONNECTION, 0,
- use_or_ap);
+ fascist_firewall_choose_address_rs(status, FIREWALL_OR_CONNECTION, 0,
+ use_or_ap);
+ have_or = tor_addr_port_is_valid_ap(use_or_ap, 0);
}
/* DirPort connections
@@ -806,9 +806,9 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
indirection == DIRIND_ANON_DIRPORT ||
(indirection == DIRIND_ONEHOP
&& !directory_must_use_begindir(options))) {
- have_dir = fascist_firewall_choose_address_rs(status,
- FIREWALL_DIR_CONNECTION, 0,
- use_dir_ap);
+ fascist_firewall_choose_address_rs(status, FIREWALL_DIR_CONNECTION, 0,
+ use_dir_ap);
+ have_dir = tor_addr_port_is_valid_ap(use_dir_ap, 0);
}
/* We rejected all addresses in the relay's status. This means we can't
@@ -5257,84 +5257,71 @@ connection_dir_finished_connecting(dir_connection_t *conn)
/** Decide which download schedule we want to use based on descriptor type
* in <b>dls</b> and <b>options</b>.
- * Then return a list of int pointers defining download delays in seconds.
+ *
+ * Then, return the initial delay for that download schedule, in seconds.
+ *
* Helper function for download_status_increment_failure(),
* download_status_reset(), and download_status_increment_attempt(). */
-STATIC const smartlist_t *
-find_dl_schedule(const download_status_t *dls, const or_options_t *options)
+STATIC int
+find_dl_min_delay(const download_status_t *dls, const or_options_t *options)
{
+ tor_assert(dls);
+ tor_assert(options);
+
switch (dls->schedule) {
case DL_SCHED_GENERIC:
/* Any other directory document */
if (dir_server_mode(options)) {
/* A directory authority or directory mirror */
- return options->TestingServerDownloadSchedule;
+ return options->TestingServerDownloadInitialDelay;
} else {
- return options->TestingClientDownloadSchedule;
+ return options->TestingClientDownloadInitialDelay;
}
case DL_SCHED_CONSENSUS:
if (!networkstatus_consensus_can_use_multiple_directories(options)) {
/* A public relay */
- return options->TestingServerConsensusDownloadSchedule;
+ return options->TestingServerConsensusDownloadInitialDelay;
} else {
/* A client or bridge */
if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
/* During bootstrapping */
if (!networkstatus_consensus_can_use_extra_fallbacks(options)) {
/* A bootstrapping client without extra fallback directories */
- return
- options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule;
+ return options->
+ ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay;
} else if (dls->want_authority) {
/* A bootstrapping client with extra fallback directories, but
* connecting to an authority */
return
- options->ClientBootstrapConsensusAuthorityDownloadSchedule;
+ options->ClientBootstrapConsensusAuthorityDownloadInitialDelay;
} else {
/* A bootstrapping client connecting to extra fallback directories
*/
return
- options->ClientBootstrapConsensusFallbackDownloadSchedule;
+ options->ClientBootstrapConsensusFallbackDownloadInitialDelay;
}
} else {
/* A client with a reasonably live consensus, with or without
* certificates */
- return options->TestingClientConsensusDownloadSchedule;
+ return options->TestingClientConsensusDownloadInitialDelay;
}
}
case DL_SCHED_BRIDGE:
if (options->UseBridges && num_bridges_usable(0) > 0) {
/* A bridge client that is sure that one or more of its bridges are
* running can afford to wait longer to update bridge descriptors. */
- return options->TestingBridgeDownloadSchedule;
+ return options->TestingBridgeDownloadInitialDelay;
} else {
/* A bridge client which might have no running bridges, must try to
* get bridge descriptors straight away. */
- return options->TestingBridgeBootstrapDownloadSchedule;
+ return options->TestingBridgeBootstrapDownloadInitialDelay;
}
default:
tor_assert(0);
}
/* Impossible, but gcc will fail with -Werror without a `return`. */
- return NULL;
-}
-
-/** Decide which minimum delay step we want to use based on
- * descriptor type in <b>dls</b> and <b>options</b>.
- * Helper function for download_status_schedule_get_delay(). */
-STATIC int
-find_dl_min_delay(download_status_t *dls, const or_options_t *options)
-{
- tor_assert(dls);
- tor_assert(options);
-
- /*
- * For now, just use the existing schedule config stuff and pick the
- * first/last entries off to get min/max delay for backoff purposes
- */
- const smartlist_t *schedule = find_dl_schedule(dls, options);
- tor_assert(schedule != NULL && smartlist_len(schedule) >= 2);
- return *(int *)(smartlist_get(schedule, 0));
+ return 0;
}
/** As next_random_exponential_delay() below, but does not compute a random
@@ -5591,10 +5578,9 @@ download_status_increment_attempt(download_status_t *dls, const char *item,
static time_t
download_status_get_initial_delay_from_now(const download_status_t *dls)
{
- const smartlist_t *schedule = find_dl_schedule(dls, get_options());
/* We use constant initial delays, even in exponential backoff
* schedules. */
- return time(NULL) + *(int *)smartlist_get(schedule, 0);
+ return time(NULL) + find_dl_min_delay(dls, get_options());
}
/** Reset <b>dls</b> so that it will be considered downloadable
diff --git a/src/or/directory.h b/src/or/directory.h
index aa4d29a5bb..5f5ff7eca6 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -259,9 +259,7 @@ STATIC char* authdir_type_to_string(dirinfo_type_t auth);
STATIC const char * dir_conn_purpose_to_string(int purpose);
STATIC int should_use_directory_guards(const or_options_t *options);
STATIC compression_level_t choose_compression_level(ssize_t n_bytes);
-STATIC const smartlist_t *find_dl_schedule(const download_status_t *dls,
- const or_options_t *options);
-STATIC int find_dl_min_delay(download_status_t *dls,
+STATIC int find_dl_min_delay(const download_status_t *dls,
const or_options_t *options);
STATIC int next_random_exponential_delay(int delay,
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 96e6ccaace..2c2bf99925 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -432,14 +432,15 @@ get_guard_confirmed_min_lifetime(void)
STATIC int
get_n_primary_guards(void)
{
- const int n = get_options()->NumEntryGuards;
- const int n_dir = get_options()->NumDirectoryGuards;
- if (n > 5) {
- return MAX(n_dir, n + n / 2);
- } else if (n >= 1) {
- return MAX(n_dir, n * 2);
+ /* If the user has explicitly configured the number of primary guards, do
+ * what the user wishes to do */
+ const int configured_primaries = get_options()->NumPrimaryGuards;
+ if (configured_primaries) {
+ return configured_primaries;
}
+ /* otherwise check for consensus parameter and if that's not set either, just
+ * use the default value. */
return networkstatus_get_param(NULL,
"guard-n-primary-guards",
DFLT_N_PRIMARY_GUARDS, 1, INT32_MAX);
@@ -454,6 +455,9 @@ get_n_primary_guards_to_use(guard_usage_t usage)
int configured;
const char *param_name;
int param_default;
+
+ /* If the user has explicitly configured the amount of guards, use
+ that. Otherwise, fall back to the default value. */
if (usage == GUARD_USAGE_DIRGUARD) {
configured = get_options()->NumDirectoryGuards;
param_name = "guard-n-primary-dir-guards-to-use";
diff --git a/src/or/hs_common.c b/src/or/hs_common.c
index 8cc7d08911..46903a2960 100644
--- a/src/or/hs_common.c
+++ b/src/or/hs_common.c
@@ -103,7 +103,7 @@ compare_digest_to_fetch_hsdir_index(const void *_key, const void **_member)
{
const char *key = _key;
const node_t *node = *_member;
- return tor_memcmp(key, node->hsdir_index->fetch, DIGEST256_LEN);
+ return tor_memcmp(key, node->hsdir_index.fetch, DIGEST256_LEN);
}
/* Helper function: The key is a digest that we compare to a node_t object
@@ -114,7 +114,7 @@ compare_digest_to_store_first_hsdir_index(const void *_key,
{
const char *key = _key;
const node_t *node = *_member;
- return tor_memcmp(key, node->hsdir_index->store_first, DIGEST256_LEN);
+ return tor_memcmp(key, node->hsdir_index.store_first, DIGEST256_LEN);
}
/* Helper function: The key is a digest that we compare to a node_t object
@@ -125,7 +125,7 @@ compare_digest_to_store_second_hsdir_index(const void *_key,
{
const char *key = _key;
const node_t *node = *_member;
- return tor_memcmp(key, node->hsdir_index->store_second, DIGEST256_LEN);
+ return tor_memcmp(key, node->hsdir_index.store_second, DIGEST256_LEN);
}
/* Helper function: Compare two node_t objects current hsdir_index. */
@@ -134,8 +134,8 @@ compare_node_fetch_hsdir_index(const void **a, const void **b)
{
const node_t *node1= *a;
const node_t *node2 = *b;
- return tor_memcmp(node1->hsdir_index->fetch,
- node2->hsdir_index->fetch,
+ return tor_memcmp(node1->hsdir_index.fetch,
+ node2->hsdir_index.fetch,
DIGEST256_LEN);
}
@@ -145,8 +145,8 @@ compare_node_store_first_hsdir_index(const void **a, const void **b)
{
const node_t *node1= *a;
const node_t *node2 = *b;
- return tor_memcmp(node1->hsdir_index->store_first,
- node2->hsdir_index->store_first,
+ return tor_memcmp(node1->hsdir_index.store_first,
+ node2->hsdir_index.store_first,
DIGEST256_LEN);
}
@@ -156,8 +156,8 @@ compare_node_store_second_hsdir_index(const void **a, const void **b)
{
const node_t *node1= *a;
const node_t *node2 = *b;
- return tor_memcmp(node1->hsdir_index->store_second,
- node2->hsdir_index->store_second,
+ return tor_memcmp(node1->hsdir_index.store_second,
+ node2->hsdir_index.store_second,
DIGEST256_LEN);
}
@@ -1288,18 +1288,15 @@ node_has_hsdir_index(const node_t *node)
/* At this point, since the node has a desc, this node must also have an
* hsdir index. If not, something went wrong, so BUG out. */
- if (BUG(node->hsdir_index == NULL)) {
- return 0;
- }
- if (BUG(tor_mem_is_zero((const char*)node->hsdir_index->fetch,
+ if (BUG(tor_mem_is_zero((const char*)node->hsdir_index.fetch,
DIGEST256_LEN))) {
return 0;
}
- if (BUG(tor_mem_is_zero((const char*)node->hsdir_index->store_first,
+ if (BUG(tor_mem_is_zero((const char*)node->hsdir_index.store_first,
DIGEST256_LEN))) {
return 0;
}
- if (BUG(tor_mem_is_zero((const char*)node->hsdir_index->store_second,
+ if (BUG(tor_mem_is_zero((const char*)node->hsdir_index.store_second,
DIGEST256_LEN))) {
return 0;
}
diff --git a/src/or/hs_common.h b/src/or/hs_common.h
index 83ba1b8599..ef7d5dca2b 100644
--- a/src/or/hs_common.h
+++ b/src/or/hs_common.h
@@ -156,19 +156,6 @@ typedef struct rend_service_port_config_t {
char unix_addr[FLEXIBLE_ARRAY_MEMBER];
} rend_service_port_config_t;
-/* Hidden service directory index used in a node_t which is set once we set
- * the consensus. */
-typedef struct hsdir_index_t {
- /* HSDir index to use when fetching a descriptor. */
- uint8_t fetch[DIGEST256_LEN];
-
- /* HSDir index used by services to store their first and second
- * descriptor. The first descriptor is chronologically older than the second
- * one and uses older TP and SRV values. */
- uint8_t store_first[DIGEST256_LEN];
- uint8_t store_second[DIGEST256_LEN];
-} hsdir_index_t;
-
void hs_init(void);
void hs_free_all(void);
diff --git a/src/or/hs_control.c b/src/or/hs_control.c
index 87b4e3fca8..eca9ed1dd5 100644
--- a/src/or/hs_control.c
+++ b/src/or/hs_control.c
@@ -39,9 +39,8 @@ hs_control_desc_event_requested(const ed25519_public_key_t *onion_pk,
* can't pick a node without an hsdir_index. */
hsdir_node = node_get_by_id(hsdir_rs->identity_digest);
tor_assert(hsdir_node);
- tor_assert(hsdir_node->hsdir_index);
/* This is a fetch event. */
- hsdir_index = hsdir_node->hsdir_index->fetch;
+ hsdir_index = hsdir_node->hsdir_index.fetch;
/* Trigger the event. */
control_event_hs_descriptor_requested(onion_address, REND_NO_AUTH,
diff --git a/src/or/hs_service.c b/src/or/hs_service.c
index 4ac0df2add..c4a473a5f7 100644
--- a/src/or/hs_service.c
+++ b/src/or/hs_service.c
@@ -80,6 +80,7 @@ static smartlist_t *hs_service_staging_list;
* reupload if needed */
static int consider_republishing_hs_descriptors = 0;
+/* Static declaration. */
static void set_descriptor_revision_counter(hs_descriptor_t *hs_desc);
static void move_descriptors(hs_service_t *src, hs_service_t *dst);
@@ -152,6 +153,12 @@ register_service(hs_service_ht *map, hs_service_t *service)
}
/* Taking ownership of the object at this point. */
HT_INSERT(hs_service_ht, map, service);
+
+ /* If we just modified the global map, we notify. */
+ if (map == hs_service_map) {
+ hs_service_map_has_changed();
+ }
+
return 0;
}
@@ -178,6 +185,11 @@ remove_service(hs_service_ht *map, hs_service_t *service)
"while removing service %s",
escaped(service->config.directory_path));
}
+
+ /* If we just modified the global map, we notify. */
+ if (map == hs_service_map) {
+ hs_service_map_has_changed();
+ }
}
/* Set the default values for a service configuration object <b>c</b>. */
@@ -916,6 +928,11 @@ register_all_services(void)
smartlist_clear(hs_service_staging_list);
service_free_all();
hs_service_map = new_service_map;
+ /* We've just register services into the new map and now we've replaced the
+ * global map with it so we have to notify that the change happened. When
+ * registering a service, the notify is only triggered if the destination
+ * map is the global map for which in here it was not. */
+ hs_service_map_has_changed();
}
/* Write the onion address of a given service to the given filename fname_ in
@@ -2287,8 +2304,8 @@ upload_descriptor_to_hsdir(const hs_service_t *service,
/* Logging so we know where it was sent. */
{
int is_next_desc = (service->desc_next == desc);
- const uint8_t *idx = (is_next_desc) ? hsdir->hsdir_index->store_second:
- hsdir->hsdir_index->store_first;
+ const uint8_t *idx = (is_next_desc) ? hsdir->hsdir_index.store_second:
+ hsdir->hsdir_index.store_first;
log_info(LD_REND, "Service %s %s descriptor of revision %" PRIu64
" initiated upload request to %s with index %s",
safe_str_client(service->onion_address),
@@ -2936,6 +2953,17 @@ service_add_fnames_to_list(const hs_service_t *service, smartlist_t *list)
/* Public API */
/* ========== */
+/* This is called everytime the service map (v2 or v3) changes that is if an
+ * element is added or removed. */
+void
+hs_service_map_has_changed(void)
+{
+ /* If we now have services where previously we had not, we need to enable
+ * the HS service main loop event. If we changed to having no services, we
+ * need to disable the event. */
+ rescan_periodic_events(get_options());
+}
+
/* Upload an encoded descriptor in encoded_desc of the given version. This
* descriptor is for the service identity_pk and blinded_pk used to setup the
* directory connection identifier. It is uploaded to the directory hsdir_rs
diff --git a/src/or/hs_service.h b/src/or/hs_service.h
index d163eeef28..2e27d8a899 100644
--- a/src/or/hs_service.h
+++ b/src/or/hs_service.h
@@ -260,6 +260,7 @@ void hs_service_lists_fnames_for_sandbox(smartlist_t *file_list,
int hs_service_set_conn_addr_port(const origin_circuit_t *circ,
edge_connection_t *conn);
+void hs_service_map_has_changed(void);
void hs_service_dir_info_changed(void);
void hs_service_run_scheduled_events(time_t now);
void hs_service_circuit_has_opened(origin_circuit_t *circ);
diff --git a/src/or/main.c b/src/or/main.c
index b7b7b71624..1160f377e4 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1356,6 +1356,7 @@ CALLBACK(retry_listeners);
CALLBACK(rotate_onion_key);
CALLBACK(rotate_x509_certificate);
CALLBACK(save_stability);
+CALLBACK(save_state);
CALLBACK(write_bridge_ns);
CALLBACK(write_stats_file);
@@ -1377,6 +1378,7 @@ STATIC periodic_event_item_t periodic_events[] = {
CALLBACK(reset_padding_counts, PERIODIC_EVENT_ROLE_ALL, 0),
CALLBACK(retry_listeners, PERIODIC_EVENT_ROLE_ALL,
PERIODIC_EVENT_FLAG_NEED_NET),
+ CALLBACK(save_state, PERIODIC_EVENT_ROLE_ALL, 0),
CALLBACK(rotate_x509_certificate, PERIODIC_EVENT_ROLE_ALL, 0),
CALLBACK(write_stats_file, PERIODIC_EVENT_ROLE_ALL, 0),
@@ -1387,7 +1389,6 @@ STATIC periodic_event_item_t periodic_events[] = {
CALLBACK(check_for_reachability_bw, PERIODIC_EVENT_ROLE_ROUTER,
PERIODIC_EVENT_FLAG_NEED_NET),
CALLBACK(check_onion_keys_expiry_time, PERIODIC_EVENT_ROLE_ROUTER, 0),
- CALLBACK(clean_consdiffmgr, PERIODIC_EVENT_ROLE_ROUTER, 0),
CALLBACK(expire_old_ciruits_serverside, PERIODIC_EVENT_ROLE_ROUTER,
PERIODIC_EVENT_FLAG_NEED_NET),
CALLBACK(retry_dns, PERIODIC_EVENT_ROLE_ROUTER, 0),
@@ -1421,6 +1422,9 @@ STATIC periodic_event_item_t periodic_events[] = {
/* Bridge Authority only. */
CALLBACK(write_bridge_ns, PERIODIC_EVENT_ROLE_BRIDGEAUTH, 0),
+ /* Directory server only. */
+ CALLBACK(clean_consdiffmgr, PERIODIC_EVENT_ROLE_DIRSERVER, 0),
+
END_OF_PERIODIC_EVENTS
};
#undef CALLBACK
@@ -1433,6 +1437,7 @@ static periodic_event_item_t *check_descriptor_event=NULL;
static periodic_event_item_t *fetch_networkstatus_event=NULL;
static periodic_event_item_t *launch_descriptor_fetches_event=NULL;
static periodic_event_item_t *check_dns_honesty_event=NULL;
+static periodic_event_item_t *save_state_event=NULL;
/** Reset all the periodic events so we'll do all our actions again as if we
* just started up.
@@ -1477,6 +1482,7 @@ get_my_roles(const or_options_t *options)
int is_bridgeauth = authdir_mode_bridge(options);
int is_hidden_service = !!hs_service_get_num_services() ||
!!rend_num_services();
+ int is_dirserver = dir_server_mode(options);
if (is_bridge) roles |= PERIODIC_EVENT_ROLE_BRIDGE;
if (is_client) roles |= PERIODIC_EVENT_ROLE_CLIENT;
@@ -1484,6 +1490,7 @@ get_my_roles(const or_options_t *options)
if (is_dirauth) roles |= PERIODIC_EVENT_ROLE_DIRAUTH;
if (is_bridgeauth) roles |= PERIODIC_EVENT_ROLE_BRIDGEAUTH;
if (is_hidden_service) roles |= PERIODIC_EVENT_ROLE_HS_SERVICE;
+ if (is_dirserver) roles |= PERIODIC_EVENT_ROLE_DIRSERVER;
return roles;
}
@@ -1529,6 +1536,7 @@ initialize_periodic_events(void)
NAMED_CALLBACK(fetch_networkstatus);
NAMED_CALLBACK(launch_descriptor_fetches);
NAMED_CALLBACK(check_dns_honesty);
+ NAMED_CALLBACK(save_state);
struct timeval one_second = { 1, 0 };
initialize_periodic_events_event = tor_evtimer_new(
@@ -1554,6 +1562,13 @@ rescan_periodic_events(const or_options_t *options)
{
tor_assert(options);
+ /* Avoid scanning the event list if we haven't initialized it yet. This is
+ * particularly useful for unit tests in order to avoid initializing main
+ * loop events everytime. */
+ if (!periodic_events_initialized) {
+ return;
+ }
+
int roles = get_my_roles(options);
for (int i = 0; periodic_events[i].name; ++i) {
@@ -1599,8 +1614,9 @@ periodic_events_on_new_options(const or_options_t *options)
void
reschedule_descriptor_update_check(void)
{
- tor_assert(check_descriptor_event);
- periodic_event_reschedule(check_descriptor_event);
+ if (check_descriptor_event) {
+ periodic_event_reschedule(check_descriptor_event);
+ }
}
/**
@@ -1746,10 +1762,6 @@ run_scheduled_events(time_t now)
run_connection_housekeeping(i, now);
}
- /* 8b. And if anything in our state is ready to get flushed to disk, we
- * flush it. */
- or_state_save(now);
-
/* 11b. check pending unconfigured managed proxies */
if (!net_is_disabled() && pt_proxies_configuration_pending())
pt_configure_remaining_proxies();
@@ -1984,6 +1996,37 @@ check_expired_networkstatus_callback(time_t now, const or_options_t *options)
}
/**
+ * Scheduled callback: Save the state file to disk if appropriate.
+ */
+static int
+save_state_callback(time_t now, const or_options_t *options)
+{
+ (void) options;
+ (void) or_state_save(now); // only saves if appropriate
+ const time_t next_write = get_or_state()->next_write;
+ if (next_write == TIME_MAX) {
+ return 86400;
+ } else if (BUG(next_write <= now)) {
+ /* This can't happen due to clock jumps, since the value of next_write
+ * is based on the same "now" that we passed to or_state_save().
+ */
+ return PERIODIC_EVENT_NO_UPDATE;
+ } else {
+ return (int)(next_write - now);
+ }
+}
+
+/** Reschedule the event for saving the state file.
+ *
+ * Run this when the state becomes dirty. */
+void
+reschedule_or_state_save(void)
+{
+ tor_assert(save_state_event);
+ periodic_event_reschedule(save_state_event);
+}
+
+/**
* Periodic callback: Write statistics to disk if appropriate.
*/
static int
@@ -2335,7 +2378,7 @@ static int
clean_consdiffmgr_callback(time_t now, const or_options_t *options)
{
(void)now;
- if (server_mode(options)) {
+ if (dir_server_mode(options)) {
consdiffmgr_cleanup();
}
return CDM_CLEAN_CALLBACK_INTERVAL;
diff --git a/src/or/main.h b/src/or/main.h
index 2447339fb5..836dbf1cad 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -61,6 +61,7 @@ void dns_servers_relaunch_checks(void);
void reset_all_main_loop_timers(void);
void reschedule_descriptor_update_check(void);
void reschedule_directory_downloads(void);
+void reschedule_or_state_save(void);
void mainloop_schedule_postloop_cleanup(void);
void rescan_periodic_events(const or_options_t *options);
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index e7342f9799..675cbb0056 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -225,7 +225,6 @@ node_get_or_create(const char *identity_digest)
smartlist_add(the_nodelist->nodes, node);
node->nodelist_idx = smartlist_len(the_nodelist->nodes) - 1;
- node->hsdir_index = tor_malloc_zero(sizeof(hsdir_index_t));
node->country = -1;
@@ -350,26 +349,26 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns)
/* Build the fetch index. */
hs_build_hsdir_index(node_identity_pk, fetch_srv, fetch_tp,
- node->hsdir_index->fetch);
+ node->hsdir_index.fetch);
/* If we are in the time segment between SRV#N and TP#N, the fetch index is
the same as the first store index */
if (!hs_in_period_between_tp_and_srv(ns, now)) {
- memcpy(node->hsdir_index->store_first, node->hsdir_index->fetch,
- sizeof(node->hsdir_index->store_first));
+ memcpy(node->hsdir_index.store_first, node->hsdir_index.fetch,
+ sizeof(node->hsdir_index.store_first));
} else {
hs_build_hsdir_index(node_identity_pk, store_first_srv, store_first_tp,
- node->hsdir_index->store_first);
+ node->hsdir_index.store_first);
}
/* If we are in the time segment between TP#N and SRV#N+1, the fetch index is
the same as the second store index */
if (hs_in_period_between_tp_and_srv(ns, now)) {
- memcpy(node->hsdir_index->store_second, node->hsdir_index->fetch,
- sizeof(node->hsdir_index->store_second));
+ memcpy(node->hsdir_index.store_second, node->hsdir_index.fetch,
+ sizeof(node->hsdir_index.store_second));
} else {
hs_build_hsdir_index(node_identity_pk, store_second_srv, store_second_tp,
- node->hsdir_index->store_second);
+ node->hsdir_index.store_second);
}
done:
@@ -720,7 +719,6 @@ node_free_(node_t *node)
if (node->md)
node->md->held_by_nodes--;
tor_assert(node->nodelist_idx == -1);
- tor_free(node->hsdir_index);
tor_free(node);
}
diff --git a/src/or/or.h b/src/or/or.h
index e27f25197b..cd77b21056 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -57,7 +57,6 @@
#ifdef HAVE_TIME_H
#include <time.h>
#endif
-#include <stdbool.h>
#ifdef _WIN32
#include <winsock2.h>
@@ -895,8 +894,19 @@ rend_data_v2_t *TO_REND_DATA_V2(const rend_data_t *d)
struct hs_ident_edge_conn_t;
struct hs_ident_dir_conn_t;
struct hs_ident_circuit_t;
-/* Stub because we can't include hs_common.h. */
-struct hsdir_index_t;
+
+/* Hidden service directory index used in a node_t which is set once we set
+ * the consensus. */
+typedef struct hsdir_index_t {
+ /* HSDir index to use when fetching a descriptor. */
+ uint8_t fetch[DIGEST256_LEN];
+
+ /* HSDir index used by services to store their first and second
+ * descriptor. The first descriptor is chronologically older than the second
+ * one and uses older TP and SRV values. */
+ uint8_t store_first[DIGEST256_LEN];
+ uint8_t store_second[DIGEST256_LEN];
+} hsdir_index_t;
/** Time interval for tracking replays of DH public keys received in
* INTRODUCE2 cells. Used only to avoid launching multiple
@@ -2562,7 +2572,7 @@ typedef struct node_t {
/* Hidden service directory index data. This is used by a service or client
* in order to know what's the hs directory index for this node at the time
* the consensus is set. */
- struct hsdir_index_t *hsdir_index;
+ struct hsdir_index_t hsdir_index;
} node_t;
/** Linked list of microdesc hash lines for a single router in a directory
@@ -4149,6 +4159,8 @@ typedef struct {
int NumDirectoryGuards; /**< How many dir guards do we try to establish?
* If 0, use value from NumEntryGuards. */
+ int NumPrimaryGuards; /**< How many primary guards do we want? */
+
int RephistTrackTime; /**< How many seconds do we keep rephist info? */
/** Should we always fetch our dir info on the mirror schedule (which
* means directly from the authorities) no matter our other config? */
@@ -4317,19 +4329,19 @@ typedef struct {
/** Schedule for when servers should download things in general. Only
* altered on testing networks. */
- smartlist_t *TestingServerDownloadSchedule;
+ int TestingServerDownloadInitialDelay;
/** Schedule for when clients should download things in general. Only
* altered on testing networks. */
- smartlist_t *TestingClientDownloadSchedule;
+ int TestingClientDownloadInitialDelay;
/** Schedule for when servers should download consensuses. Only altered
* on testing networks. */
- smartlist_t *TestingServerConsensusDownloadSchedule;
+ int TestingServerConsensusDownloadInitialDelay;
/** Schedule for when clients should download consensuses. Only altered
* on testing networks. */
- smartlist_t *TestingClientConsensusDownloadSchedule;
+ int TestingClientConsensusDownloadInitialDelay;
/** Schedule for when clients should download consensuses from authorities
* if they are bootstrapping (that is, they don't have a usable, reasonably
@@ -4339,7 +4351,7 @@ typedef struct {
* This schedule is incremented by (potentially concurrent) connection
* attempts, unlike other schedules, which are incremented by connection
* failures. Only altered on testing networks. */
- smartlist_t *ClientBootstrapConsensusAuthorityDownloadSchedule;
+ int ClientBootstrapConsensusAuthorityDownloadInitialDelay;
/** Schedule for when clients should download consensuses from fallback
* directory mirrors if they are bootstrapping (that is, they don't have a
@@ -4349,7 +4361,7 @@ typedef struct {
* This schedule is incremented by (potentially concurrent) connection
* attempts, unlike other schedules, which are incremented by connection
* failures. Only altered on testing networks. */
- smartlist_t *ClientBootstrapConsensusFallbackDownloadSchedule;
+ int ClientBootstrapConsensusFallbackDownloadInitialDelay;
/** Schedule for when clients should download consensuses from authorities
* if they are bootstrapping (that is, they don't have a usable, reasonably
@@ -4359,15 +4371,15 @@ typedef struct {
* This schedule is incremented by (potentially concurrent) connection
* attempts, unlike other schedules, which are incremented by connection
* failures. Only altered on testing networks. */
- smartlist_t *ClientBootstrapConsensusAuthorityOnlyDownloadSchedule;
+ int ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay;
/** Schedule for when clients should download bridge descriptors. Only
* altered on testing networks. */
- smartlist_t *TestingBridgeDownloadSchedule;
+ int TestingBridgeDownloadInitialDelay;
/** Schedule for when clients should download bridge descriptors when they
* have no running bridges. Only altered on testing networks. */
- smartlist_t *TestingBridgeBootstrapDownloadSchedule;
+ int TestingBridgeBootstrapDownloadInitialDelay;
/** When directory clients have only a few descriptors to request, they
* batch them until they have more, or until this amount of time has
@@ -4745,15 +4757,6 @@ typedef struct {
time_t LastRotatedOnionKey;
} or_state_t;
-/** Change the next_write time of <b>state</b> to <b>when</b>, unless the
- * state is already scheduled to be written to disk earlier than <b>when</b>.
- */
-static inline void or_state_mark_dirty(or_state_t *state, time_t when)
-{
- if (state->next_write > when)
- state->next_write = when;
-}
-
#define MAX_SOCKS_REPLY_LEN 1024
#define MAX_SOCKS_ADDR_LEN 256
#define SOCKS_NO_AUTH 0x00
diff --git a/src/or/periodic.h b/src/or/periodic.h
index a044b34fdd..e8208b2475 100644
--- a/src/or/periodic.h
+++ b/src/or/periodic.h
@@ -14,6 +14,7 @@
#define PERIODIC_EVENT_ROLE_DIRAUTH (1U << 3)
#define PERIODIC_EVENT_ROLE_BRIDGEAUTH (1U << 4)
#define PERIODIC_EVENT_ROLE_HS_SERVICE (1U << 5)
+#define PERIODIC_EVENT_ROLE_DIRSERVER (1U << 6)
/* Helper macro to make it a bit less annoying to defined groups of roles that
* are often used. */
diff --git a/src/or/policies.c b/src/or/policies.c
index f718ded326..e0dbb021c6 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -825,9 +825,8 @@ fascist_firewall_choose_address(const tor_addr_port_t *a,
* If pref_only, only choose preferred addresses. In either case, choose
* a preferred address before an address that's not preferred.
* If both addresses could be chosen (they are both preferred or both allowed)
- * choose IPv6 if pref_ipv6 is true, otherwise choose IPv4.
- * If neither address is chosen, return 0, else return 1. */
-static int
+ * choose IPv6 if pref_ipv6 is true, otherwise choose IPv4. */
+static void
fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr,
uint16_t ipv4_orport,
uint16_t ipv4_dirport,
@@ -845,6 +844,9 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr,
tor_assert(ipv6_addr);
tor_assert(ap);
+ tor_addr_make_null(&ap->addr, AF_UNSPEC);
+ ap->port = 0;
+
tor_addr_port_t ipv4_ap;
tor_addr_copy(&ipv4_ap.addr, ipv4_addr);
ipv4_ap.port = (fw_connection == FIREWALL_OR_CONNECTION
@@ -865,17 +867,12 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr,
if (result) {
tor_addr_copy(&ap->addr, &result->addr);
ap->port = result->port;
- return 1;
- } else {
- tor_addr_make_null(&ap->addr, AF_UNSPEC);
- ap->port = 0;
- return 0;
}
}
/** Like fascist_firewall_choose_address_base(), but takes a host-order IPv4
* address as the first parameter. */
-static int
+static void
fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr,
uint16_t ipv4_orport,
uint16_t ipv4_dirport,
@@ -889,11 +886,16 @@ fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr,
{
tor_addr_t ipv4_addr;
tor_addr_from_ipv4h(&ipv4_addr, ipv4h_addr);
- return fascist_firewall_choose_address_base(&ipv4_addr, ipv4_orport,
- ipv4_dirport, ipv6_addr,
- ipv6_orport, ipv6_dirport,
- fw_connection, pref_only,
- pref_ipv6, ap);
+ tor_assert(ap);
+
+ tor_addr_make_null(&ap->addr, AF_UNSPEC);
+ ap->port = 0;
+
+ fascist_firewall_choose_address_base(&ipv4_addr, ipv4_orport,
+ ipv4_dirport, ipv6_addr,
+ ipv6_orport, ipv6_dirport,
+ fw_connection, pref_only,
+ pref_ipv6, ap);
}
/* Some microdescriptor consensus methods have no IPv6 addresses in rs: they
@@ -944,23 +946,25 @@ node_awaiting_ipv6(const or_options_t* options, const node_t *node)
* This should only happen when there's no valid consensus, and rs doesn't
* correspond to a bridge client's bridge.
*/
-int
+void
fascist_firewall_choose_address_rs(const routerstatus_t *rs,
firewall_connection_t fw_connection,
int pref_only, tor_addr_port_t* ap)
{
+ tor_assert(ap);
+
+ tor_addr_make_null(&ap->addr, AF_UNSPEC);
+ ap->port = 0;
+
if (!rs) {
- return 0;
+ return;
}
- tor_assert(ap);
-
const or_options_t *options = get_options();
const node_t *node = node_get_by_id(rs->identity_digest);
if (node && !node_awaiting_ipv6(options, node)) {
- return fascist_firewall_choose_address_node(node, fw_connection, pref_only,
- ap);
+ fascist_firewall_choose_address_node(node, fw_connection, pref_only, ap);
} else {
/* There's no node-specific IPv6 preference, so use the generic IPv6
* preference instead. */
@@ -970,33 +974,31 @@ fascist_firewall_choose_address_rs(const routerstatus_t *rs,
/* Assume IPv4 and IPv6 DirPorts are the same.
* Assume the IPv6 OR and Dir addresses are the same. */
- return fascist_firewall_choose_address_ipv4h(rs->addr,
- rs->or_port,
- rs->dir_port,
- &rs->ipv6_addr,
- rs->ipv6_orport,
- rs->dir_port,
- fw_connection,
- pref_only,
- pref_ipv6,
- ap);
+ fascist_firewall_choose_address_ipv4h(rs->addr, rs->or_port, rs->dir_port,
+ &rs->ipv6_addr, rs->ipv6_orport,
+ rs->dir_port, fw_connection,
+ pref_only, pref_ipv6, ap);
}
}
/** Like fascist_firewall_choose_address_base(), but takes <b>node</b>, and
* looks up the node's IPv6 preference rather than taking an argument
* for pref_ipv6. */
-int
+void
fascist_firewall_choose_address_node(const node_t *node,
firewall_connection_t fw_connection,
int pref_only, tor_addr_port_t *ap)
{
+ tor_assert(ap);
+
+ tor_addr_make_null(&ap->addr, AF_UNSPEC);
+ ap->port = 0;
+
if (!node) {
- return 0;
+ return;
}
node_assert_ok(node);
-
/* Calling fascist_firewall_choose_address_node() when the node is missing
* IPv6 information breaks IPv6-only clients.
* If the node is a hard-coded fallback directory or authority, call
@@ -1006,7 +1008,7 @@ fascist_firewall_choose_address_node(const node_t *node,
* descriptor (routerinfo), or is one of our configured bridges before
* calling this function. */
if (BUG(node_awaiting_ipv6(get_options(), node))) {
- return 0;
+ return;
}
const int pref_ipv6_node = (fw_connection == FIREWALL_OR_CONNECTION
@@ -1024,27 +1026,27 @@ fascist_firewall_choose_address_node(const node_t *node,
node_get_pref_ipv6_dirport(node, &ipv6_dir_ap);
/* Assume the IPv6 OR and Dir addresses are the same. */
- return fascist_firewall_choose_address_base(&ipv4_or_ap.addr,
- ipv4_or_ap.port,
- ipv4_dir_ap.port,
- &ipv6_or_ap.addr,
- ipv6_or_ap.port,
- ipv6_dir_ap.port,
- fw_connection,
- pref_only,
- pref_ipv6_node,
- ap);
+ fascist_firewall_choose_address_base(&ipv4_or_ap.addr, ipv4_or_ap.port,
+ ipv4_dir_ap.port, &ipv6_or_ap.addr,
+ ipv6_or_ap.port, ipv6_dir_ap.port,
+ fw_connection, pref_only,
+ pref_ipv6_node, ap);
}
/** Like fascist_firewall_choose_address_rs(), but takes <b>ds</b>. */
-int
+void
fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
firewall_connection_t fw_connection,
int pref_only,
tor_addr_port_t *ap)
{
+ tor_assert(ap);
+
+ tor_addr_make_null(&ap->addr, AF_UNSPEC);
+ ap->port = 0;
+
if (!ds) {
- return 0;
+ return;
}
/* A dir_server_t always has a fake_status. As long as it has the same
@@ -1052,8 +1054,8 @@ fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
* (See #17867.)
* This function relies on fascist_firewall_choose_address_rs looking up the
* node if it can, because that will get the latest info for the relay. */
- return fascist_firewall_choose_address_rs(&ds->fake_status, fw_connection,
- pref_only, ap);
+ fascist_firewall_choose_address_rs(&ds->fake_status, fw_connection,
+ pref_only, ap);
}
/** Return 1 if <b>addr</b> is permitted to connect to our dir port,
diff --git a/src/or/policies.h b/src/or/policies.h
index 35220a812f..4879acdd8d 100644
--- a/src/or/policies.h
+++ b/src/or/policies.h
@@ -55,13 +55,13 @@ int fascist_firewall_allows_dir_server(const dir_server_t *ds,
firewall_connection_t fw_connection,
int pref_only);
-int fascist_firewall_choose_address_rs(const routerstatus_t *rs,
- firewall_connection_t fw_connection,
- int pref_only, tor_addr_port_t* ap);
-int fascist_firewall_choose_address_node(const node_t *node,
- firewall_connection_t fw_connection,
- int pref_only, tor_addr_port_t* ap);
-int fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
+void fascist_firewall_choose_address_rs(const routerstatus_t *rs,
+ firewall_connection_t fw_connection,
+ int pref_only, tor_addr_port_t* ap);
+void fascist_firewall_choose_address_node(const node_t *node,
+ firewall_connection_t fw_connection,
+ int pref_only, tor_addr_port_t* ap);
+void fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
firewall_connection_t fw_connection,
int pref_only, tor_addr_port_t* ap);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 1a93c36433..afaeabe5dc 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -348,6 +348,13 @@ rend_add_service(smartlist_t *service_list, rend_service_t *service)
/* The service passed all the checks */
tor_assert(s_list);
smartlist_add(s_list, service);
+
+ /* Notify that our global service list has changed only if this new service
+ * went into our global list. If not, when we move service from the staging
+ * list to the new list, a notify is triggered. */
+ if (s_list == rend_service_list) {
+ hs_service_map_has_changed();
+ }
return 0;
}
@@ -609,6 +616,8 @@ rend_service_prune_list_impl_(void)
circuit_mark_for_close(TO_CIRCUIT(ocirc), END_CIRC_REASON_FINISHED);
}
smartlist_free(surviving_services);
+ /* Notify that our global service list has changed. */
+ hs_service_map_has_changed();
}
/* Try to prune our main service list using the temporary one that we just
@@ -958,6 +967,8 @@ rend_service_del_ephemeral(const char *service_id)
}
} SMARTLIST_FOREACH_END(circ);
smartlist_remove(rend_service_list, s);
+ /* Notify that we just removed a service from our global list. */
+ hs_service_map_has_changed();
rend_service_free(s);
log_debug(LD_CONFIG, "Removed ephemeral Onion Service: %s", service_id);
diff --git a/src/or/rephist.c b/src/or/rephist.c
index ac3e9f502e..bac2efb1f4 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -85,8 +85,8 @@
#include "routerlist.h"
#include "ht.h"
#include "channelpadding.h"
-
#include "connection_or.h"
+#include "statefile.h"
static void bw_arrays_init(void);
static void predicted_ports_alloc(void);
diff --git a/src/or/statefile.c b/src/or/statefile.c
index cc114f0a2b..c81ea44e06 100644
--- a/src/or/statefile.c
+++ b/src/or/statefile.c
@@ -37,6 +37,7 @@
#include "control.h"
#include "entrynodes.h"
#include "hibernate.h"
+#include "main.h"
#include "rephist.h"
#include "router.h"
#include "sandbox.h"
@@ -680,6 +681,18 @@ save_transport_to_state(const char *transport,
tor_free(transport_addrport);
}
+/** Change the next_write time of <b>state</b> to <b>when</b>, unless the
+ * state is already scheduled to be written to disk earlier than <b>when</b>.
+ */
+void
+or_state_mark_dirty(or_state_t *state, time_t when)
+{
+ if (state->next_write > when) {
+ state->next_write = when;
+ reschedule_or_state_save();
+ }
+}
+
STATIC void
or_state_free_(or_state_t *state)
{
diff --git a/src/or/statefile.h b/src/or/statefile.h
index b4cc4d1dc6..5aa2ca9320 100644
--- a/src/or/statefile.h
+++ b/src/or/statefile.h
@@ -17,6 +17,7 @@ char *get_stored_bindaddr_for_server_transport(const char *transport);
int or_state_load(void);
int or_state_loaded(void);
void or_state_free_all(void);
+void or_state_mark_dirty(or_state_t *state, time_t when);
#ifdef STATEFILE_PRIVATE
STATIC config_line_t *get_transport_in_state_by_name(const char *transport);
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 74153c671a..84fdb96e45 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -4065,34 +4065,19 @@ test_dir_download_status_increment(void *arg)
DL_WANT_ANY_DIRSERVER,
DL_SCHED_INCREMENT_ATTEMPT,
0, 0 };
- int no_delay = 0;
- int delay0 = -1;
- int delay1 = -1;
- int delay2 = -1;
- smartlist_t *schedule = smartlist_new();
- smartlist_t *schedule_no_initial_delay = smartlist_new();
or_options_t test_options;
time_t current_time = time(NULL);
- /* Provide some values for the schedules */
- delay0 = 10;
- delay1 = 99;
- delay2 = 20;
-
- /* Make the schedules */
- smartlist_add(schedule, (void *)&delay0);
- smartlist_add(schedule, (void *)&delay1);
- smartlist_add(schedule, (void *)&delay2);
-
- smartlist_add(schedule_no_initial_delay, (void *)&no_delay);
- smartlist_add(schedule_no_initial_delay, (void *)&delay1);
- smartlist_add(schedule_no_initial_delay, (void *)&delay2);
+ const int delay0 = 10;
+ const int no_delay = 0;
+ const int schedule = 10;
+ const int schedule_no_initial_delay = 0;
/* Put it in the options */
mock_options = &test_options;
reset_options(mock_options, &mock_get_options_calls);
- mock_options->TestingBridgeBootstrapDownloadSchedule = schedule;
- mock_options->TestingClientDownloadSchedule = schedule;
+ mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
+ mock_options->TestingClientDownloadInitialDelay = schedule;
MOCK(get_options, mock_get_options);
@@ -4100,13 +4085,13 @@ test_dir_download_status_increment(void *arg)
* whether or not it was reset before being used */
/* regression test for 17750: no initial delay */
- mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
+ mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
/* regression test for 17750: exponential, no initial delay */
- mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
+ mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
@@ -4119,7 +4104,7 @@ test_dir_download_status_increment(void *arg)
tt_int_op(mock_get_options_calls, OP_GE, 1);
/* regression test for 17750: exponential, initial delay */
- mock_options->TestingClientDownloadSchedule = schedule;
+ mock_options->TestingClientDownloadInitialDelay = schedule;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
@@ -4132,9 +4117,6 @@ test_dir_download_status_increment(void *arg)
tt_int_op(mock_get_options_calls, OP_GE, 1);
done:
- /* the pointers in schedule are allocated on the stack */
- smartlist_free(schedule);
- smartlist_free(schedule_no_initial_delay);
UNMOCK(get_options);
mock_options = NULL;
mock_get_options_calls = 0;
@@ -5452,7 +5434,7 @@ mock_num_bridges_usable(int use_maybe_reachable)
* fallbacks.
*/
static void
-test_dir_find_dl_schedule(void* data)
+test_dir_find_dl_min_delay(void* data)
{
const char *str = (const char *)data;
@@ -5485,44 +5467,45 @@ test_dir_find_dl_schedule(void* data)
mock_num_bridges_usable);
download_status_t dls;
- smartlist_t server, client, server_cons, client_cons;
- smartlist_t client_boot_auth_only_cons, client_boot_auth_cons;
- smartlist_t client_boot_fallback_cons, bridge, bridge_bootstrap;
+
+ const int server=10, client=20, server_cons=30, client_cons=40;
+ const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
+ const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
mock_options = tor_malloc(sizeof(or_options_t));
reset_options(mock_options, &mock_get_options_calls);
MOCK(get_options, mock_get_options);
- mock_options->TestingServerDownloadSchedule = &server;
- mock_options->TestingClientDownloadSchedule = &client;
- mock_options->TestingServerConsensusDownloadSchedule = &server_cons;
- mock_options->TestingClientConsensusDownloadSchedule = &client_cons;
- mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule =
- &client_boot_auth_only_cons;
- mock_options->ClientBootstrapConsensusAuthorityDownloadSchedule =
- &client_boot_auth_cons;
- mock_options->ClientBootstrapConsensusFallbackDownloadSchedule =
- &client_boot_fallback_cons;
- mock_options->TestingBridgeDownloadSchedule = &bridge;
- mock_options->TestingBridgeBootstrapDownloadSchedule = &bridge_bootstrap;
+ mock_options->TestingServerDownloadInitialDelay = server;
+ mock_options->TestingClientDownloadInitialDelay = client;
+ mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
+ mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
+ mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
+ client_boot_auth_only_cons;
+ mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
+ client_boot_auth_cons;
+ mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
+ client_boot_fallback_cons;
+ mock_options->TestingBridgeDownloadInitialDelay = bridge;
+ mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
dls.schedule = DL_SCHED_GENERIC;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &client);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
mock_options->ClientOnly = 0;
/* dir mode */
mock_options->DirPort_set = 1;
mock_options->DirCache = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
mock_options->DirPort_set = 0;
mock_options->DirCache = 0;
dls.schedule = DL_SCHED_CONSENSUS;
/* public server mode */
mock_options->ORPort_set = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
mock_options->ORPort_set = 0;
/* client and bridge modes */
@@ -5531,30 +5514,30 @@ test_dir_find_dl_schedule(void* data)
dls.want_authority = 1;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
dls.want_authority = 0;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_fallback_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_fallback_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_fallback_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_fallback_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
@@ -5562,30 +5545,30 @@ test_dir_find_dl_schedule(void* data)
/* dls.want_authority is ignored */
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_only_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_only_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_only_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_only_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
}
} else {
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
}
@@ -5595,9 +5578,9 @@ test_dir_find_dl_schedule(void* data)
mock_options->ClientOnly = 1;
mock_options->UseBridges = 1;
if (num_bridges_usable(0) > 0) {
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
} else {
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge_bootstrap);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
}
done:
@@ -5871,14 +5854,14 @@ struct testcase_t dir_tests[] = {
DIR(dump_unparseable_descriptors, 0),
DIR(populate_dump_desc_fifo, 0),
DIR(populate_dump_desc_fifo_2, 0),
- DIR_ARG(find_dl_schedule, TT_FORK, "bfd"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bad"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cfd"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cad"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bfr"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bar"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cfr"),
- DIR_ARG(find_dl_schedule, TT_FORK, "car"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
DIR(assumed_flags, 0),
DIR(networkstatus_compute_bw_weights_v10, 0),
DIR(platform_str, 0),
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 92a860360d..f55e9f0173 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -2679,6 +2679,23 @@ test_enty_guard_should_expire_waiting(void *arg)
tor_free(fake_state);
}
+/** Test that the number of primary guards can be controlled using torrc */
+static void
+test_entry_guard_number_of_primaries(void *arg)
+{
+ (void) arg;
+
+ /* Get default value */
+ tt_int_op(get_n_primary_guards(), OP_EQ, DFLT_N_PRIMARY_GUARDS);
+
+ /* Set number of primaries using torrc */
+ get_options_mutable()->NumPrimaryGuards = 42;
+ tt_int_op(get_n_primary_guards(), OP_EQ, 42);
+
+ done:
+ ;
+}
+
static void
mock_directory_initiate_request(directory_request_t *req)
{
@@ -2826,6 +2843,8 @@ struct testcase_t entrynodes_tests[] = {
test_entry_guard_parse_from_state_broken, TT_FORK, NULL, NULL },
{ "get_guard_selection_by_name",
test_entry_guard_get_guard_selection_by_name, TT_FORK, NULL, NULL },
+ { "number_of_primaries",
+ test_entry_guard_number_of_primaries, TT_FORK, NULL, NULL },
BFN_TEST(choose_selection_initial),
BFN_TEST(add_single_guard),
BFN_TEST(node_filter),
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
index 207a55de6d..308843e9b8 100644
--- a/src/test/test_hs_control.c
+++ b/src/test/test_hs_control.c
@@ -76,9 +76,8 @@ mock_node_get_by_id(const char *digest)
{
static node_t node;
memcpy(node.identity, digest, DIGEST_LEN);
- node.hsdir_index = tor_malloc_zero(sizeof(hsdir_index_t));
- memset(node.hsdir_index->fetch, 'C', DIGEST256_LEN);
- memset(node.hsdir_index->store_first, 'D', DIGEST256_LEN);
+ memset(node.hsdir_index.fetch, 'C', DIGEST256_LEN);
+ memset(node.hsdir_index.store_first, 'D', DIGEST256_LEN);
return &node;
}
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 9974ed2575..65564f324c 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -2067,12 +2067,12 @@ test_options_validate__testing(void *ignored)
ENSURE_DEFAULT(TestingV3AuthVotingStartOffset, 3000);
ENSURE_DEFAULT(TestingAuthDirTimeToLearnReachability, 3000);
ENSURE_DEFAULT(TestingEstimatedDescriptorPropagationTime, 3000);
- ENSURE_DEFAULT(TestingServerDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingClientDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingServerConsensusDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingClientConsensusDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingBridgeDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingBridgeBootstrapDownloadSchedule, 3000);
+ ENSURE_DEFAULT(TestingServerDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingClientDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingServerConsensusDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingClientConsensusDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingBridgeDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingBridgeBootstrapDownloadInitialDelay, 3000);
ENSURE_DEFAULT(TestingClientMaxIntervalWithoutRequest, 3000);
ENSURE_DEFAULT(TestingDirConnectionMaxStall, 3000);
ENSURE_DEFAULT(TestingAuthKeyLifetime, 3000);
diff --git a/src/test/test_periodic_event.c b/src/test/test_periodic_event.c
index bebbb5e584..34689b64f4 100644
--- a/src/test/test_periodic_event.c
+++ b/src/test/test_periodic_event.c
@@ -69,7 +69,7 @@ test_pe_initialize(void *arg)
static void
test_pe_launch(void *arg)
{
- hs_service_t service;
+ hs_service_t service, *to_remove = NULL;
or_options_t *options;
(void) arg;
@@ -118,6 +118,10 @@ test_pe_launch(void *arg)
options->ORPort_set = 1;
periodic_events_on_new_options(options);
+ unsigned roles = get_my_roles(options);
+ tt_uint_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_RELAY|PERIODIC_EVENT_ROLE_DIRSERVER);
+
for (int i = 0; periodic_events[i].name; ++i) {
periodic_event_item_t *item = &periodic_events[i];
/* Only Client role should be disabled. */
@@ -130,8 +134,8 @@ test_pe_launch(void *arg)
tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
tt_u64_op(item->last_action_time, OP_NE, 0);
}
- /* Non Relay role should be disabled! */
- if (!(item->roles & PERIODIC_EVENT_ROLE_RELAY)) {
+ /* Non Relay role should be disabled, except for Dirserver. */
+ if (!(item->roles & roles)) {
tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
}
}
@@ -152,8 +156,11 @@ test_pe_launch(void *arg)
options->V3AuthoritativeDir = 1; options->BridgeAuthoritativeDir = 1;
register_dummy_hidden_service(&service);
periodic_events_on_new_options(options);
- /* Remove it now so the hs_free_all() doesn't try to free stack memory. */
- remove_service(get_hs_service_map(), &service);
+ /* Note down the reference because we need to remove this service from the
+ * global list before the hs_free_all() call so it doesn't try to free
+ * memory on the stack. Furthermore, we can't remove it now else it will
+ * trigger a rescan of the event disabling the HS service event. */
+ to_remove = &service;
for (int i = 0; periodic_events[i].name; ++i) {
periodic_event_item_t *item = &periodic_events[i];
@@ -161,6 +168,9 @@ test_pe_launch(void *arg)
}
done:
+ if (to_remove) {
+ remove_service(get_hs_service_map(), to_remove);
+ }
hs_free_all();
}
@@ -190,19 +200,21 @@ test_pe_get_roles(void *arg)
options->ORPort_set = 1;
roles = get_my_roles(options);
tt_int_op(roles, OP_EQ,
- (PERIODIC_EVENT_ROLE_CLIENT | PERIODIC_EVENT_ROLE_RELAY));
+ (PERIODIC_EVENT_ROLE_CLIENT | PERIODIC_EVENT_ROLE_RELAY |
+ PERIODIC_EVENT_ROLE_DIRSERVER));
/* Now add a Bridge. */
options->BridgeRelay = 1;
roles = get_my_roles(options);
tt_int_op(roles, OP_EQ,
(PERIODIC_EVENT_ROLE_CLIENT | PERIODIC_EVENT_ROLE_RELAY |
- PERIODIC_EVENT_ROLE_BRIDGE));
+ PERIODIC_EVENT_ROLE_BRIDGE | PERIODIC_EVENT_ROLE_DIRSERVER));
tt_assert(roles & PERIODIC_EVENT_ROLE_ROUTER);
/* Unset client so we can solely test Router role. */
options->SocksPort_set = 0;
roles = get_my_roles(options);
- tt_int_op(roles, OP_EQ, PERIODIC_EVENT_ROLE_ROUTER);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_ROUTER | PERIODIC_EVENT_ROLE_DIRSERVER);
/* Reset options so we can test authorities. */
options->SocksPort_set = 0;
@@ -212,24 +224,28 @@ test_pe_get_roles(void *arg)
tt_int_op(roles, OP_EQ, 0);
/* Now upgrade to Dirauth. */
+ options->DirPort_set = 1;
options->AuthoritativeDir = 1;
options->V3AuthoritativeDir = 1;
roles = get_my_roles(options);
- tt_int_op(roles, OP_EQ, PERIODIC_EVENT_ROLE_DIRAUTH);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_DIRAUTH|PERIODIC_EVENT_ROLE_DIRSERVER);
tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
/* Now Bridge Authority. */
options->V3AuthoritativeDir = 0;
options->BridgeAuthoritativeDir = 1;
roles = get_my_roles(options);
- tt_int_op(roles, OP_EQ, PERIODIC_EVENT_ROLE_BRIDGEAUTH);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_BRIDGEAUTH|PERIODIC_EVENT_ROLE_DIRSERVER);
tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
/* Move that bridge auth to become a relay. */
options->ORPort_set = 1;
roles = get_my_roles(options);
tt_int_op(roles, OP_EQ,
- (PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_RELAY));
+ (PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_RELAY
+ | PERIODIC_EVENT_ROLE_DIRSERVER));
tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
/* And now an Hidden service. */
@@ -240,13 +256,69 @@ test_pe_get_roles(void *arg)
remove_service(get_hs_service_map(), &service);
tt_int_op(roles, OP_EQ,
(PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_RELAY |
- PERIODIC_EVENT_ROLE_HS_SERVICE));
+ PERIODIC_EVENT_ROLE_HS_SERVICE | PERIODIC_EVENT_ROLE_DIRSERVER));
tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
done:
hs_free_all();
}
+static void
+test_pe_hs_service(void *arg)
+{
+ hs_service_t service, *to_remove = NULL;
+
+ (void) arg;
+
+ hs_init();
+ /* We need to put tor in hibernation live state so the events requiring
+ * network gets enabled. */
+ consider_hibernation(time(NULL));
+ /* Initialize the events so we can enable them */
+ initialize_periodic_events();
+
+ /* Hack: We'll set a dumb fn() of each events so they don't get called when
+ * dispatching them. We just want to test the state of the callbacks, not
+ * the whole code path. */
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ item->fn = dumb_event_fn;
+ }
+
+ /* This should trigger a rescan of the list and enable the HS service
+ * events. */
+ register_dummy_hidden_service(&service);
+ /* Note down the reference because we need to remove this service from the
+ * global list before the hs_free_all() call so it doesn't try to free
+ * memory on the stack. Furthermore, we can't remove it now else it will
+ * trigger a rescan of the event disabling the HS service event. */
+ to_remove = &service;
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ if (item->roles & PERIODIC_EVENT_ROLE_HS_SERVICE) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
+ }
+ }
+ to_remove = NULL;
+
+ /* Remove the service from the global map, it should trigger a rescan and
+ * disable the HS service events. */
+ remove_service(get_hs_service_map(), &service);
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ if (item->roles & PERIODIC_EVENT_ROLE_HS_SERVICE) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+ }
+
+ done:
+ if (to_remove) {
+ remove_service(get_hs_service_map(), to_remove);
+ }
+ hs_free_all();
+}
+
#define PE_TEST(name) \
{ #name, test_pe_## name , TT_FORK, NULL, NULL }
@@ -254,6 +326,7 @@ struct testcase_t periodic_event_tests[] = {
PE_TEST(initialize),
PE_TEST(launch),
PE_TEST(get_roles),
+ PE_TEST(hs_service),
END_OF_TESTCASES
};
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index f8aa8ac40b..f180585861 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -1923,11 +1923,8 @@ test_policies_fascist_firewall_allows_address(void *arg)
tor_addr_port_t chosen_rs_ap; \
tor_addr_make_null(&chosen_rs_ap.addr, AF_INET); \
chosen_rs_ap.port = 0; \
- tt_int_op(fascist_firewall_choose_address_rs(&(fake_rs), \
- (fw_connection), \
- (pref_only), \
- &chosen_rs_ap), \
- OP_EQ, (expect_rv)); \
+ fascist_firewall_choose_address_rs(&(fake_rs), (fw_connection), \
+ (pref_only), &chosen_rs_ap); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_rs_ap.addr)); \
tt_int_op((expect_ap).port, OP_EQ, chosen_rs_ap.port); \
STMT_END
@@ -1940,11 +1937,8 @@ test_policies_fascist_firewall_allows_address(void *arg)
tor_addr_port_t chosen_node_ap; \
tor_addr_make_null(&chosen_node_ap.addr, AF_INET); \
chosen_node_ap.port = 0; \
- tt_int_op(fascist_firewall_choose_address_node(&(fake_node), \
- (fw_connection), \
- (pref_only), \
- &chosen_node_ap), \
- OP_EQ, (expect_rv)); \
+ fascist_firewall_choose_address_node(&(fake_node),(fw_connection), \
+ (pref_only), &chosen_node_ap); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_node_ap.addr)); \
tt_int_op((expect_ap).port, OP_EQ, chosen_node_ap.port); \
STMT_END
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index 29f7cc9c37..ef1be139a6 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -203,6 +203,17 @@ test_tortls_tor_tls_get_error(void *data)
}
static void
+library_init(void)
+{
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+#else
+ SSL_library_init();
+ SSL_load_error_strings();
+#endif
+}
+
+static void
test_tortls_get_state_description(void *ignored)
{
(void)ignored;
@@ -210,9 +221,7 @@ test_tortls_get_state_description(void *ignored)
char *buf;
SSL_CTX *ctx;
- SSL_library_init();
- SSL_load_error_strings();
-
+ library_init();
ctx = SSL_CTX_new(SSLv23_method());
buf = tor_malloc_zero(1000);
@@ -274,8 +283,7 @@ test_tortls_get_by_ssl(void *ignored)
SSL_CTX *ctx;
SSL *ssl;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
tor_tls_allocate_tor_tls_object_ex_data_index();
ctx = SSL_CTX_new(SSLv23_method());
@@ -322,8 +330,7 @@ test_tortls_log_one_error(void *ignored)
SSL_CTX *ctx;
SSL *ssl = NULL;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
ctx = SSL_CTX_new(SSLv23_method());
tls = tor_malloc_zero(sizeof(tor_tls_t));
@@ -415,8 +422,7 @@ test_tortls_get_error(void *ignored)
int ret;
SSL_CTX *ctx;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
ctx = SSL_CTX_new(SSLv23_method());
setup_capture_of_logs(LOG_INFO);
@@ -792,8 +798,8 @@ test_tortls_classify_client_ciphers(void *ignored)
STACK_OF(SSL_CIPHER) *ciphers;
SSL_CIPHER *tmp_cipher;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
+
tor_tls_allocate_tor_tls_object_ex_data_index();
tls = tor_malloc_zero(sizeof(tor_tls_t));
@@ -897,8 +903,7 @@ test_tortls_client_is_using_v2_ciphers(void *ignored)
SSL_SESSION *sess;
STACK_OF(SSL_CIPHER) *ciphers;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
ctx = SSL_CTX_new(TLSv1_method());
ssl = SSL_new(ctx);
@@ -1541,8 +1546,8 @@ test_tortls_session_secret_cb(void *ignored)
STACK_OF(SSL_CIPHER) *ciphers = NULL;
SSL_CIPHER *one;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
+
tor_tls_allocate_tor_tls_object_ex_data_index();
tls = tor_malloc_zero(sizeof(tor_tls_t));
@@ -1733,8 +1738,7 @@ test_tortls_find_cipher_by_id(void *ignored)
fixed_cipher2 = tor_malloc_zero(sizeof(SSL_CIPHER));
fixed_cipher2->id = 0xC00A;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
ctx = SSL_CTX_new(m);
ssl = SSL_new(ctx);
@@ -1825,8 +1829,7 @@ test_tortls_server_info_callback(void *ignored)
SSL_CTX *ctx;
SSL *ssl;
- SSL_library_init();
- SSL_load_error_strings();
+ library_init();
ctx = SSL_CTX_new(TLSv1_method());
ssl = SSL_new(ctx);