tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2019
- 20 participants
- 2923 discussions

[tor/master] config: Move relay config checks into the relay module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit 093a127c82a06546029e42cf0030edf43fb5f87b
Author: teor <teor(a)torproject.org>
Date: Tue Oct 29 16:22:39 2019 +1000
config: Move relay config checks into the relay module
This commit:
* moves relay config checks into relay_config.[ch],
* exposes some code from src/app/config.c
(we'll refactor it later in 29211), and
* adds thin wrappers to make the moved code compile.
No functional changes: the moved code is still enabled,
even if the relay module is disabled. (Some of the checks
are re-ordered, so the order of some warnings may change.)
Part of 32213.
---
src/app/config/config.c | 380 +---------------------------
src/app/config/config.h | 4 -
src/feature/relay/relay_config.c | 533 ++++++++++++++++++++++++++++++++++++++-
src/feature/relay/relay_config.h | 35 +++
src/test/test_config.c | 2 +
src/test/test_options.c | 2 +
6 files changed, 581 insertions(+), 375 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index aa6e4d71d..3d6ba00ef 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -827,9 +827,6 @@ static int options_transition_affects_workers(
const or_options_t *old_options, const or_options_t *new_options);
static int options_transition_affects_descriptor(
const or_options_t *old_options, const or_options_t *new_options);
-static int normalize_nickname_list(config_line_t **normalized_out,
- const config_line_t *lst, const char *name,
- char **msg);
static char *get_bindaddr_from_transport_listen_line(const char *line,
const char *transport);
static int parse_ports(or_options_t *options, int validate_only,
@@ -3112,48 +3109,6 @@ ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
return 0;
}
-/** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
- * and write it to <b>options</b>-\>PublishServerDescriptor_. Treat "1"
- * as "v3" unless BridgeRelay is 1, in which case treat it as "bridge".
- * Treat "0" as "".
- * Return 0 on success or -1 if not a recognized authority type (in which
- * case the value of PublishServerDescriptor_ is undefined). */
-static int
-compute_publishserverdescriptor(or_options_t *options)
-{
- smartlist_t *list = options->PublishServerDescriptor;
- dirinfo_type_t *auth = &options->PublishServerDescriptor_;
- *auth = NO_DIRINFO;
- if (!list) /* empty list, answer is none */
- return 0;
- SMARTLIST_FOREACH_BEGIN(list, const char *, string) {
- if (!strcasecmp(string, "v1"))
- log_warn(LD_CONFIG, "PublishServerDescriptor v1 has no effect, because "
- "there are no v1 directory authorities anymore.");
- else if (!strcmp(string, "1"))
- if (options->BridgeRelay)
- *auth |= BRIDGE_DIRINFO;
- else
- *auth |= V3_DIRINFO;
- else if (!strcasecmp(string, "v2"))
- log_warn(LD_CONFIG, "PublishServerDescriptor v2 has no effect, because "
- "there are no v2 directory authorities anymore.");
- else if (!strcasecmp(string, "v3"))
- *auth |= V3_DIRINFO;
- else if (!strcasecmp(string, "bridge"))
- *auth |= BRIDGE_DIRINFO;
- else if (!strcasecmp(string, "hidserv"))
- log_warn(LD_CONFIG,
- "PublishServerDescriptor hidserv is invalid. See "
- "PublishHidServDescriptors.");
- else if (!strcasecmp(string, "") || !strcmp(string, "0"))
- /* no authority */;
- else
- return -1;
- } SMARTLIST_FOREACH_END(string);
- return 0;
-}
-
/** Lowest allowable value for RendPostPeriod; if this is too low, hidden
* services can overload the directory system. */
#define MIN_REND_POST_PERIOD (10*60)
@@ -3445,7 +3400,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
or_options_t *options = options_;
config_line_t *cl;
- const char *uname = get_uname();
int n_ports=0;
int world_writable_control_socket=0;
@@ -3462,15 +3416,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
* Always use the value of UseEntryGuards, not UseEntryGuards_option. */
options->UseEntryGuards = options->UseEntryGuards_option;
- if (server_mode(options) &&
- (!strcmpstart(uname, "Windows 95") ||
- !strcmpstart(uname, "Windows 98") ||
- !strcmpstart(uname, "Windows Me"))) {
- log_warn(LD_CONFIG, "Tor is running as a server, but you are "
- "running %s; this probably won't work. See "
- "https://www.torproject.org/docs/faq.html#BestOSForRelay "
- "for details.", uname);
- }
+ if (options_validate_relay_os(old_options, options, msg) < 0)
+ return -1;
if (parse_outbound_addresses(options, 1, msg) < 0)
return -1;
@@ -3486,27 +3433,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
"with relative paths.");
}
- if (options->Nickname == NULL) {
- if (server_mode(options)) {
- options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
- }
- } else {
- if (!is_legal_nickname(options->Nickname)) {
- tor_asprintf(msg,
- "Nickname '%s', nicknames must be between 1 and 19 characters "
- "inclusive, and must contain only the characters [a-zA-Z0-9].",
- options->Nickname);
- return -1;
- }
- }
-
- if (server_mode(options) && !options->ContactInfo)
- log_notice(LD_CONFIG, "Your ContactInfo config option is not set. "
- "Please consider setting it, so we can contact you if your server is "
- "misconfigured or something else goes wrong.");
- const char *ContactInfo = options->ContactInfo;
- if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
- REJECT("ContactInfo config option must be UTF-8.");
+ if (options_validate_relay_info(old_options, options, msg) < 0)
+ return -1;
check_network_configuration(server_mode(options));
@@ -3746,51 +3674,11 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
return -1;
}
- if (compute_publishserverdescriptor(options) < 0) {
- tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
+ if (options_validate_publish_server(old_options, options, msg) < 0)
return -1;
- }
-
- if ((options->BridgeRelay
- || options->PublishServerDescriptor_ & BRIDGE_DIRINFO)
- && (options->PublishServerDescriptor_ & V3_DIRINFO)) {
- REJECT("Bridges are not supposed to publish router descriptors to the "
- "directory authorities. Please correct your "
- "PublishServerDescriptor line.");
- }
-
- if (options->BridgeRelay && options->DirPort_set) {
- log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
- "DirPort");
- config_free_lines(options->DirPort_lines);
- options->DirPort_lines = NULL;
- options->DirPort_set = 0;
- }
-
- if (server_mode(options) && options->ConnectionPadding != -1) {
- REJECT("Relays must use 'auto' for the ConnectionPadding setting.");
- }
-
- if (server_mode(options) && options->ReducedConnectionPadding != 0) {
- REJECT("Relays cannot set ReducedConnectionPadding. ");
- }
-
- if (server_mode(options) && options->CircuitPadding == 0) {
- REJECT("Relays cannot set CircuitPadding to 0. ");
- }
- if (server_mode(options) && options->ReducedCircuitPadding == 1) {
- REJECT("Relays cannot set ReducedCircuitPadding. ");
- }
-
- if (options->BridgeDistribution) {
- if (!options->BridgeRelay) {
- REJECT("You set BridgeDistribution, but you didn't set BridgeRelay!");
- }
- if (check_bridge_distribution_setting(options->BridgeDistribution) < 0) {
- REJECT("Invalid BridgeDistribution value.");
- }
- }
+ if (options_validate_relay_padding(old_options, options, msg) < 0)
+ return -1;
if (options->MinUptimeHidServDirectoryV2 < 0) {
log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
@@ -4003,38 +3891,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
options->RelayBandwidthRate = options->RelayBandwidthBurst;
- if (server_mode(options)) {
- const unsigned required_min_bw =
- public_server_mode(options) ?
- RELAY_REQUIRED_MIN_BANDWIDTH : BRIDGE_REQUIRED_MIN_BANDWIDTH;
- const char * const optbridge =
- public_server_mode(options) ? "" : "bridge ";
- if (options->BandwidthRate < required_min_bw) {
- tor_asprintf(msg,
- "BandwidthRate is set to %d bytes/second. "
- "For %sservers, it must be at least %u.",
- (int)options->BandwidthRate, optbridge,
- required_min_bw);
- return -1;
- } else if (options->MaxAdvertisedBandwidth <
- required_min_bw/2) {
- tor_asprintf(msg,
- "MaxAdvertisedBandwidth is set to %d bytes/second. "
- "For %sservers, it must be at least %u.",
- (int)options->MaxAdvertisedBandwidth, optbridge,
- required_min_bw/2);
- return -1;
- }
- if (options->RelayBandwidthRate &&
- options->RelayBandwidthRate < required_min_bw) {
- tor_asprintf(msg,
- "RelayBandwidthRate is set to %d bytes/second. "
- "For %sservers, it must be at least %u.",
- (int)options->RelayBandwidthRate, optbridge,
- required_min_bw);
- return -1;
- }
- }
+ if (options_validate_relay_bandwidth(old_options, options, msg) < 0)
+ return -1;
if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
REJECT("RelayBandwidthBurst must be at least equal "
@@ -4081,23 +3939,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
}
- if (options->DirPort_set && !options->DirCache) {
- REJECT("DirPort configured but DirCache disabled. DirPort requires "
- "DirCache.");
- }
-
- if (options->BridgeRelay && !options->DirCache) {
- REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires "
- "DirCache.");
- }
-
- if (server_mode(options)) {
- char *dircache_msg = NULL;
- if (have_enough_mem_for_dircache(options, 0, &dircache_msg)) {
- log_warn(LD_CONFIG, "%s", dircache_msg);
- tor_free(dircache_msg);
- }
- }
+ if (options_validate_relay_mode(old_options, options, msg) < 0)
+ return -1;
if (options->HTTPProxy) { /* parse it now */
if (tor_addr_port_lookup(options->HTTPProxy,
@@ -4227,19 +4070,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
"have it group-readable.");
}
- if (options->MyFamily_lines && options->BridgeRelay) {
- log_warn(LD_CONFIG, "Listing a family for a bridge relay is not "
- "supported: it can reveal bridge fingerprints to censors. "
- "You should also make sure you aren't listing this bridge's "
- "fingerprint in any other MyFamily.");
- }
- if (options->MyFamily_lines && !options->ContactInfo) {
- log_warn(LD_CONFIG, "MyFamily is set but ContactInfo is not configured. "
- "ContactInfo should always be set when MyFamily option is too.");
- }
- if (normalize_nickname_list(&options->MyFamily,
- options->MyFamily_lines, "MyFamily", msg))
- return -1;
for (cl = options->NodeFamilies; cl; cl = cl->next) {
routerset_t *rs = routerset_new();
if (routerset_parse(rs, cl->value, cl->key)) {
@@ -4471,22 +4301,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options->AccelDir && !options->AccelName)
REJECT("Can't use hardware crypto accelerator dir without engine name.");
- if (options->PublishServerDescriptor)
- SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
- if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
- if (smartlist_len(options->PublishServerDescriptor) > 1) {
- COMPLAIN("You have passed a list of multiple arguments to the "
- "PublishServerDescriptor option that includes 0 or 1. "
- "0 or 1 should only be used as the sole argument. "
- "This configuration will be rejected in a future release.");
- break;
- }
- });
-
- if (options->BridgeRelay == 1 && ! options->ORPort_set)
- REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid "
- "combination.");
-
if (options_validate_scheduler(options, msg) < 0) {
return -1;
}
@@ -4578,50 +4392,6 @@ compute_real_max_mem_in_queues(const uint64_t val, int log_guess)
}
}
-/* If we have less than 300 MB suggest disabling dircache */
-#define DIRCACHE_MIN_MEM_MB 300
-#define DIRCACHE_MIN_MEM_BYTES (DIRCACHE_MIN_MEM_MB*ONE_MEGABYTE)
-#define STRINGIFY(val) #val
-
-/** Create a warning message for emitting if we are a dircache but may not have
- * enough system memory, or if we are not a dircache but probably should be.
- * Return -1 when a message is returned in *msg*, else return 0. */
-STATIC int
-have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
- char **msg)
-{
- *msg = NULL;
- /* XXX We should possibly be looking at MaxMemInQueues here
- * unconditionally. Or we should believe total_mem unconditionally. */
- if (total_mem == 0) {
- if (get_total_system_memory(&total_mem) < 0) {
- total_mem = options->MaxMemInQueues >= SIZE_MAX ?
- SIZE_MAX : (size_t)options->MaxMemInQueues;
- }
- }
- if (options->DirCache) {
- if (total_mem < DIRCACHE_MIN_MEM_BYTES) {
- if (options->BridgeRelay) {
- tor_asprintf(msg, "Running a Bridge with less than %d MB of memory "
- "is not recommended.", DIRCACHE_MIN_MEM_MB);
- } else {
- tor_asprintf(msg, "Being a directory cache (default) with less than "
- "%d MB of memory is not recommended and may consume "
- "most of the available resources. Consider disabling "
- "this functionality by setting the DirCache option "
- "to 0.", DIRCACHE_MIN_MEM_MB);
- }
- }
- } else {
- if (total_mem >= DIRCACHE_MIN_MEM_BYTES) {
- *msg = tor_strdup("DirCache is disabled and we are configured as a "
- "relay. We will not become a Guard.");
- }
- }
- return *msg == NULL ? 0 : -1;
-}
-#undef STRINGIFY
-
/** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
* equal strings. */
static int
@@ -4866,85 +4636,6 @@ get_default_conf_file(int defaults_file)
#endif /* defined(DISABLE_SYSTEM_TORRC) || ... */
}
-/** Verify whether lst is a list of strings containing valid-looking
- * comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$'
- * to any nickname or fingerprint that needs it. Also splits comma-separated
- * list elements into multiple elements. Return 0 on success.
- * Warn and return -1 on failure.
- */
-static int
-normalize_nickname_list(config_line_t **normalized_out,
- const config_line_t *lst, const char *name,
- char **msg)
-{
- if (!lst)
- return 0;
-
- config_line_t *new_nicknames = NULL;
- config_line_t **new_nicknames_next = &new_nicknames;
-
- const config_line_t *cl;
- for (cl = lst; cl; cl = cl->next) {
- const char *line = cl->value;
- if (!line)
- continue;
-
- int valid_line = 1;
- smartlist_t *sl = smartlist_new();
- smartlist_split_string(sl, line, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
- SMARTLIST_FOREACH_BEGIN(sl, char *, s)
- {
- char *normalized = NULL;
- if (!is_legal_nickname_or_hexdigest(s)) {
- // check if first char is dollar
- if (s[0] != '$') {
- // Try again but with a dollar symbol prepended
- char *prepended;
- tor_asprintf(&prepended, "$%s", s);
-
- if (is_legal_nickname_or_hexdigest(prepended)) {
- // The nickname is valid when it's prepended, set it as the
- // normalized version
- normalized = prepended;
- } else {
- // Still not valid, free and fallback to error message
- tor_free(prepended);
- }
- }
-
- if (!normalized) {
- tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
- valid_line = 0;
- break;
- }
- } else {
- normalized = tor_strdup(s);
- }
-
- config_line_t *next = tor_malloc_zero(sizeof(*next));
- next->key = tor_strdup(cl->key);
- next->value = normalized;
- next->next = NULL;
-
- *new_nicknames_next = next;
- new_nicknames_next = &next->next;
- } SMARTLIST_FOREACH_END(s);
-
- SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
- smartlist_free(sl);
-
- if (!valid_line) {
- config_free_lines(new_nicknames);
- return -1;
- }
- }
-
- *normalized_out = new_nicknames;
-
- return 0;
-}
-
/** Learn config file name from command line arguments, or use the default.
*
* If <b>defaults_file</b> is true, we're looking for torrc-defaults;
@@ -6672,55 +6363,6 @@ warn_client_dns_cache(const char *option, int disabling)
}
/**
- * Validate the configured bridge distribution method from a BridgeDistribution
- * config line.
- *
- * The input <b>bd</b>, is a string taken from the BridgeDistribution config
- * line (if present). If the option wasn't set, return 0 immediately. The
- * BridgeDistribution option is then validated. Currently valid, recognised
- * options are:
- *
- * - "none"
- * - "any"
- * - "https"
- * - "email"
- * - "moat"
- * - "hyphae"
- *
- * If the option string is unrecognised, a warning will be logged and 0 is
- * returned. If the option string contains an invalid character, -1 is
- * returned.
- **/
-STATIC int
-check_bridge_distribution_setting(const char *bd)
-{
- if (bd == NULL)
- return 0;
-
- const char *RECOGNIZED[] = {
- "none", "any", "https", "email", "moat", "hyphae"
- };
- unsigned i;
- for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) {
- if (!strcmp(bd, RECOGNIZED[i]))
- return 0;
- }
-
- const char *cp = bd;
- // Method = (KeywordChar | "_") +
- while (TOR_ISALNUM(*cp) || *cp == '-' || *cp == '_')
- ++cp;
-
- if (*cp == 0) {
- log_warn(LD_CONFIG, "Unrecognized BridgeDistribution value %s. I'll "
- "assume you know what you are doing...", escaped(bd));
- return 0; // we reached the end of the string; all is well
- } else {
- return -1; // we found a bad character in the string.
- }
-}
-
-/**
* Parse port configuration for a single port type.
*
* Read entries of the "FooPort" type from the list <b>ports</b>. Syntax is
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 11ee0d786..e2174b127 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -304,10 +304,6 @@ STATIC int parse_dir_authority_line(const char *line,
dirinfo_type_t required_type,
int validate_only);
STATIC int parse_dir_fallback_line(const char *line, int validate_only);
-STATIC int have_enough_mem_for_dircache(const or_options_t *options,
- size_t total_mem, char **msg);
-
-STATIC int check_bridge_distribution_setting(const char *bd);
STATIC uint64_t compute_real_max_mem_in_queues(const uint64_t val,
int log_guess);
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index 6ec802fc5..1d33f12b3 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -10,12 +10,14 @@
**/
#include "orconfig.h"
+#define RELAY_CONFIG_PRIVATE
#include "feature/relay/relay_config.h"
#include "lib/encoding/confline.h"
-#include "lib/confmgt/confmgt.h"
#include "lib/container/smartlist.h"
+#include "lib/meminfo/meminfo.h"
+#include "lib/osinfo/uname.h"
#include "lib/process/setuid.h"
/* Required for dirinfo_type_t in or_options_t */
@@ -25,10 +27,22 @@
#include "core/mainloop/connection.h"
#include "core/or/port_cfg_st.h"
+#include "feature/nodelist/nickname.h"
+
#include "feature/relay/dns.h"
-#include "feature/relay/ext_orport.h"
#include "feature/relay/routermode.h"
+/* Copied from config.c, we will refactor later in 29211. */
+#define REJECT(arg) \
+ STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
+#if defined(__GNUC__) && __GNUC__ <= 3
+#define COMPLAIN(args...) \
+ STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END
+#else
+#define COMPLAIN(args, ...) \
+ STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
+#endif /* defined(__GNUC__) && __GNUC__ <= 3 */
+
/** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal
* consistency and warn as appropriate. On Unix-based OSes, set
* *<b>n_low_ports_out</b> to the number of sub-1024 ports we will be
@@ -220,3 +234,518 @@ update_port_set_relay(or_options_t *options,
options->ExtORPort_set =
!! count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER, 0);
}
+
+/**
+ * Legacy validation function, which checks that the current OS is usable in
+ * relay mode, if options is set to a relay mode.
+ *
+ * Warns about OSes with potential issues. Always returns 0.
+ */
+int
+options_validate_relay_os(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ const char *uname = get_uname();
+
+ if (server_mode(options) &&
+ (!strcmpstart(uname, "Windows 95") ||
+ !strcmpstart(uname, "Windows 98") ||
+ !strcmpstart(uname, "Windows Me"))) {
+ log_warn(LD_CONFIG, "Tor is running as a server, but you are "
+ "running %s; this probably won't work. See "
+ "https://www.torproject.org/docs/faq.html#BestOSForRelay "
+ "for details.", uname);
+ }
+
+ return 0;
+}
+
+/**
+ * Legacy validation/normalization function for the relay info options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_info(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (options->Nickname == NULL) {
+ if (server_mode(options)) {
+ options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
+ }
+ } else {
+ if (!is_legal_nickname(options->Nickname)) {
+ tor_asprintf(msg,
+ "Nickname '%s', nicknames must be between 1 and 19 characters "
+ "inclusive, and must contain only the characters [a-zA-Z0-9].",
+ options->Nickname);
+ return -1;
+ }
+ }
+
+ if (server_mode(options) && !options->ContactInfo)
+ log_notice(LD_CONFIG, "Your ContactInfo config option is not set. "
+ "Please consider setting it, so we can contact you if your server is "
+ "misconfigured or something else goes wrong.");
+
+ const char *ContactInfo = options->ContactInfo;
+ if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
+ REJECT("ContactInfo config option must be UTF-8.");
+
+ return 0;
+}
+
+/** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
+ * and write it to <b>options</b>-\>PublishServerDescriptor_. Treat "1"
+ * as "v3" unless BridgeRelay is 1, in which case treat it as "bridge".
+ * Treat "0" as "".
+ * Return 0 on success or -1 if not a recognized authority type (in which
+ * case the value of PublishServerDescriptor_ is undefined). */
+static int
+compute_publishserverdescriptor(or_options_t *options)
+{
+ smartlist_t *list = options->PublishServerDescriptor;
+ dirinfo_type_t *auth = &options->PublishServerDescriptor_;
+ *auth = NO_DIRINFO;
+ if (!list) /* empty list, answer is none */
+ return 0;
+ SMARTLIST_FOREACH_BEGIN(list, const char *, string) {
+ if (!strcasecmp(string, "v1"))
+ log_warn(LD_CONFIG, "PublishServerDescriptor v1 has no effect, because "
+ "there are no v1 directory authorities anymore.");
+ else if (!strcmp(string, "1"))
+ if (options->BridgeRelay)
+ *auth |= BRIDGE_DIRINFO;
+ else
+ *auth |= V3_DIRINFO;
+ else if (!strcasecmp(string, "v2"))
+ log_warn(LD_CONFIG, "PublishServerDescriptor v2 has no effect, because "
+ "there are no v2 directory authorities anymore.");
+ else if (!strcasecmp(string, "v3"))
+ *auth |= V3_DIRINFO;
+ else if (!strcasecmp(string, "bridge"))
+ *auth |= BRIDGE_DIRINFO;
+ else if (!strcasecmp(string, "hidserv"))
+ log_warn(LD_CONFIG,
+ "PublishServerDescriptor hidserv is invalid. See "
+ "PublishHidServDescriptors.");
+ else if (!strcasecmp(string, "") || !strcmp(string, "0"))
+ /* no authority */;
+ else
+ return -1;
+ } SMARTLIST_FOREACH_END(string);
+ return 0;
+}
+
+/**
+ * Validate the configured bridge distribution method from a BridgeDistribution
+ * config line.
+ *
+ * The input <b>bd</b>, is a string taken from the BridgeDistribution config
+ * line (if present). If the option wasn't set, return 0 immediately. The
+ * BridgeDistribution option is then validated. Currently valid, recognised
+ * options are:
+ *
+ * - "none"
+ * - "any"
+ * - "https"
+ * - "email"
+ * - "moat"
+ * - "hyphae"
+ *
+ * If the option string is unrecognised, a warning will be logged and 0 is
+ * returned. If the option string contains an invalid character, -1 is
+ * returned.
+ **/
+STATIC int
+check_bridge_distribution_setting(const char *bd)
+{
+ if (bd == NULL)
+ return 0;
+
+ const char *RECOGNIZED[] = {
+ "none", "any", "https", "email", "moat", "hyphae"
+ };
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) {
+ if (!strcmp(bd, RECOGNIZED[i]))
+ return 0;
+ }
+
+ const char *cp = bd;
+ // Method = (KeywordChar | "_") +
+ while (TOR_ISALNUM(*cp) || *cp == '-' || *cp == '_')
+ ++cp;
+
+ if (*cp == 0) {
+ log_warn(LD_CONFIG, "Unrecognized BridgeDistribution value %s. I'll "
+ "assume you know what you are doing...", escaped(bd));
+ return 0; // we reached the end of the string; all is well
+ } else {
+ return -1; // we found a bad character in the string.
+ }
+}
+
+/**
+ * Legacy validation/normalization function for the bridge relay options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_publish_server(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (compute_publishserverdescriptor(options) < 0) {
+ tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
+ return -1;
+ }
+
+ if ((options->BridgeRelay
+ || options->PublishServerDescriptor_ & BRIDGE_DIRINFO)
+ && (options->PublishServerDescriptor_ & V3_DIRINFO)) {
+ REJECT("Bridges are not supposed to publish router descriptors to the "
+ "directory authorities. Please correct your "
+ "PublishServerDescriptor line.");
+ }
+
+ if (options->BridgeDistribution) {
+ if (!options->BridgeRelay) {
+ REJECT("You set BridgeDistribution, but you didn't set BridgeRelay!");
+ }
+ if (check_bridge_distribution_setting(options->BridgeDistribution) < 0) {
+ REJECT("Invalid BridgeDistribution value.");
+ }
+ }
+
+ if (options->PublishServerDescriptor)
+ SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
+ if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
+ if (smartlist_len(options->PublishServerDescriptor) > 1) {
+ COMPLAIN("You have passed a list of multiple arguments to the "
+ "PublishServerDescriptor option that includes 0 or 1. "
+ "0 or 1 should only be used as the sole argument. "
+ "This configuration will be rejected in a future release.");
+ break;
+ }
+ });
+
+ return 0;
+}
+
+/**
+ * Legacy validation/normalization function for the relay padding options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_padding(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (server_mode(options) && options->ConnectionPadding != -1) {
+ REJECT("Relays must use 'auto' for the ConnectionPadding setting.");
+ }
+
+ if (server_mode(options) && options->ReducedConnectionPadding != 0) {
+ REJECT("Relays cannot set ReducedConnectionPadding. ");
+ }
+
+ if (server_mode(options) && options->CircuitPadding == 0) {
+ REJECT("Relays cannot set CircuitPadding to 0. ");
+ }
+
+ if (server_mode(options) && options->ReducedCircuitPadding == 1) {
+ REJECT("Relays cannot set ReducedCircuitPadding. ");
+ }
+
+ return 0;
+}
+
+/**
+ * Legacy validation/normalization function for the relay bandwidth options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_bandwidth(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (server_mode(options)) {
+ const unsigned required_min_bw =
+ public_server_mode(options) ?
+ RELAY_REQUIRED_MIN_BANDWIDTH : BRIDGE_REQUIRED_MIN_BANDWIDTH;
+ const char * const optbridge =
+ public_server_mode(options) ? "" : "bridge ";
+ if (options->BandwidthRate < required_min_bw) {
+ tor_asprintf(msg,
+ "BandwidthRate is set to %d bytes/second. "
+ "For %sservers, it must be at least %u.",
+ (int)options->BandwidthRate, optbridge,
+ required_min_bw);
+ return -1;
+ } else if (options->MaxAdvertisedBandwidth <
+ required_min_bw/2) {
+ tor_asprintf(msg,
+ "MaxAdvertisedBandwidth is set to %d bytes/second. "
+ "For %sservers, it must be at least %u.",
+ (int)options->MaxAdvertisedBandwidth, optbridge,
+ required_min_bw/2);
+ return -1;
+ }
+ if (options->RelayBandwidthRate &&
+ options->RelayBandwidthRate < required_min_bw) {
+ tor_asprintf(msg,
+ "RelayBandwidthRate is set to %d bytes/second. "
+ "For %sservers, it must be at least %u.",
+ (int)options->RelayBandwidthRate, optbridge,
+ required_min_bw);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/** Verify whether lst is a list of strings containing valid-looking
+ * comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$'
+ * to any nickname or fingerprint that needs it. Also splits comma-separated
+ * list elements into multiple elements. Return 0 on success.
+ * Warn and return -1 on failure.
+ */
+static int
+normalize_nickname_list(config_line_t **normalized_out,
+ const config_line_t *lst, const char *name,
+ char **msg)
+{
+ if (!lst)
+ return 0;
+
+ config_line_t *new_nicknames = NULL;
+ config_line_t **new_nicknames_next = &new_nicknames;
+
+ const config_line_t *cl;
+ for (cl = lst; cl; cl = cl->next) {
+ const char *line = cl->value;
+ if (!line)
+ continue;
+
+ int valid_line = 1;
+ smartlist_t *sl = smartlist_new();
+ smartlist_split_string(sl, line, ",",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
+ SMARTLIST_FOREACH_BEGIN(sl, char *, s)
+ {
+ char *normalized = NULL;
+ if (!is_legal_nickname_or_hexdigest(s)) {
+ // check if first char is dollar
+ if (s[0] != '$') {
+ // Try again but with a dollar symbol prepended
+ char *prepended;
+ tor_asprintf(&prepended, "$%s", s);
+
+ if (is_legal_nickname_or_hexdigest(prepended)) {
+ // The nickname is valid when it's prepended, set it as the
+ // normalized version
+ normalized = prepended;
+ } else {
+ // Still not valid, free and fallback to error message
+ tor_free(prepended);
+ }
+ }
+
+ if (!normalized) {
+ tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
+ valid_line = 0;
+ break;
+ }
+ } else {
+ normalized = tor_strdup(s);
+ }
+
+ config_line_t *next = tor_malloc_zero(sizeof(*next));
+ next->key = tor_strdup(cl->key);
+ next->value = normalized;
+ next->next = NULL;
+
+ *new_nicknames_next = next;
+ new_nicknames_next = &next->next;
+ } SMARTLIST_FOREACH_END(s);
+
+ SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
+ smartlist_free(sl);
+
+ if (!valid_line) {
+ config_free_lines(new_nicknames);
+ return -1;
+ }
+ }
+
+ *normalized_out = new_nicknames;
+
+ return 0;
+}
+
+#define ONE_MEGABYTE (UINT64_C(1) << 20)
+
+/* If we have less than 300 MB suggest disabling dircache */
+#define DIRCACHE_MIN_MEM_MB 300
+#define DIRCACHE_MIN_MEM_BYTES (DIRCACHE_MIN_MEM_MB*ONE_MEGABYTE)
+#define STRINGIFY(val) #val
+
+/** Create a warning message for emitting if we are a dircache but may not have
+ * enough system memory, or if we are not a dircache but probably should be.
+ * Return -1 when a message is returned in *msg*, else return 0. */
+STATIC int
+have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
+ char **msg)
+{
+ *msg = NULL;
+ /* XXX We should possibly be looking at MaxMemInQueues here
+ * unconditionally. Or we should believe total_mem unconditionally. */
+ if (total_mem == 0) {
+ if (get_total_system_memory(&total_mem) < 0) {
+ total_mem = options->MaxMemInQueues >= SIZE_MAX ?
+ SIZE_MAX : (size_t)options->MaxMemInQueues;
+ }
+ }
+ if (options->DirCache) {
+ if (total_mem < DIRCACHE_MIN_MEM_BYTES) {
+ if (options->BridgeRelay) {
+ tor_asprintf(msg, "Running a Bridge with less than %d MB of memory "
+ "is not recommended.", DIRCACHE_MIN_MEM_MB);
+ } else {
+ tor_asprintf(msg, "Being a directory cache (default) with less than "
+ "%d MB of memory is not recommended and may consume "
+ "most of the available resources. Consider disabling "
+ "this functionality by setting the DirCache option "
+ "to 0.", DIRCACHE_MIN_MEM_MB);
+ }
+ }
+ } else {
+ if (total_mem >= DIRCACHE_MIN_MEM_BYTES) {
+ *msg = tor_strdup("DirCache is disabled and we are configured as a "
+ "relay. We will not become a Guard.");
+ }
+ }
+ return *msg == NULL ? 0 : -1;
+}
+#undef STRINGIFY
+
+/**
+ * Legacy validation/normalization function for the relay mode options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_mode(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (options->BridgeRelay && options->DirPort_set) {
+ log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
+ "DirPort");
+ config_free_lines(options->DirPort_lines);
+ options->DirPort_lines = NULL;
+ options->DirPort_set = 0;
+ }
+
+ if (options->DirPort_set && !options->DirCache) {
+ REJECT("DirPort configured but DirCache disabled. DirPort requires "
+ "DirCache.");
+ }
+
+ if (options->BridgeRelay && !options->DirCache) {
+ REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires "
+ "DirCache.");
+ }
+
+ if (options->BridgeRelay == 1 && ! options->ORPort_set)
+ REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid "
+ "combination.");
+
+ if (server_mode(options)) {
+ char *dircache_msg = NULL;
+ if (have_enough_mem_for_dircache(options, 0, &dircache_msg)) {
+ log_warn(LD_CONFIG, "%s", dircache_msg);
+ tor_free(dircache_msg);
+ }
+ }
+
+ if (options->MyFamily_lines && options->BridgeRelay) {
+ log_warn(LD_CONFIG, "Listing a family for a bridge relay is not "
+ "supported: it can reveal bridge fingerprints to censors. "
+ "You should also make sure you aren't listing this bridge's "
+ "fingerprint in any other MyFamily.");
+ }
+ if (options->MyFamily_lines && !options->ContactInfo) {
+ log_warn(LD_CONFIG, "MyFamily is set but ContactInfo is not configured. "
+ "ContactInfo should always be set when MyFamily option is too.");
+ }
+ if (normalize_nickname_list(&options->MyFamily,
+ options->MyFamily_lines, "MyFamily", msg))
+ return -1;
+
+ return 0;
+}
diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h
index 1b46e825a..93fcd4acb 100644
--- a/src/feature/relay/relay_config.h
+++ b/src/feature/relay/relay_config.h
@@ -12,6 +12,9 @@
#ifndef TOR_FEATURE_RELAY_RELAY_CONFIG_H
#define TOR_FEATURE_RELAY_RELAY_CONFIG_H
+#include "lib/cc/torint.h"
+#include "lib/testsupport/testsupport.h"
+
typedef struct or_options_t or_options_t;
typedef struct smartlist_t smartlist_t;
@@ -22,4 +25,36 @@ int parse_ports_relay(or_options_t *options,
void update_port_set_relay(or_options_t *options,
const smartlist_t *ports);
+int options_validate_relay_os(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+int options_validate_relay_info(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+int options_validate_publish_server(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+int options_validate_relay_padding(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+int options_validate_relay_bandwidth(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+int options_validate_relay_mode(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+#ifdef RELAY_CONFIG_PRIVATE
+
+STATIC int check_bridge_distribution_setting(const char *bd);
+STATIC int have_enough_mem_for_dircache(const or_options_t *options,
+ size_t total_mem, char **msg);
+
+#endif
+
#endif /* !defined(TOR_FEATURE_RELAY_RELAY_CONFIG_H) */
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 83f3c50ca..df025fb8f 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -6,6 +6,7 @@
#include "orconfig.h"
#define CONFIG_PRIVATE
+#define RELAY_CONFIG_PRIVATE
#define PT_PRIVATE
#define ROUTERSET_PRIVATE
#include "core/or/or.h"
@@ -16,6 +17,7 @@
#include "core/or/circuitmux_ewma.h"
#include "core/or/circuitbuild.h"
#include "app/config/config.h"
+#include "feature/relay/relay_config.h"
#include "lib/confmgt/confmgt.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
diff --git a/src/test/test_options.c b/src/test/test_options.c
index ae26cf31b..c1168a19b 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -4,10 +4,12 @@
/* See LICENSE for licensing information */
#define CONFIG_PRIVATE
+#define RELAY_CONFIG_PRIVATE
#define LOG_PRIVATE
#include "core/or/or.h"
#include "lib/confmgt/confmgt.h"
#include "app/config/config.h"
+#include "feature/relay/relay_config.h"
#include "test/test.h"
#include "lib/geoip/geoip.h"
1
0

[tor/master] config: Move server transport config into the relay module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit 11f283f56139e823d77942276d6229d6c39abd9f
Author: teor <teor(a)torproject.org>
Date: Tue Oct 29 16:25:08 2019 +1000
config: Move server transport config into the relay module
This commit:
* creates feature/relay/transport_config.[ch],
* moves server transport config checks into them,
* exposes some code from src/app/config.c
(we'll refactor it later in 29211), and
* adds thin wrappers to make the moved code compile.
No functional changes: the moved code is still enabled,
even if the relay module is disabled. (Some of the checks
are re-ordered, so the order of some warnings may change.)
Part of 32213.
---
src/app/config/config.c | 199 +---------------------------
src/app/config/config.h | 11 +-
src/app/config/statefile.c | 1 +
src/core/include.am | 2 +
src/feature/client/transports.c | 2 +
src/feature/relay/transport_config.c | 247 +++++++++++++++++++++++++++++++++++
src/feature/relay/transport_config.h | 27 ++++
src/test/test_config.c | 1 +
8 files changed, 287 insertions(+), 203 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 3d6ba00ef..4ec38e30c 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -103,6 +103,7 @@
#include "feature/relay/ext_orport.h"
#include "feature/relay/routermode.h"
#include "feature/relay/relay_config.h"
+#include "feature/relay/transport_config.h"
#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"
#include "lib/geoip/geoip.h"
@@ -827,8 +828,6 @@ static int options_transition_affects_workers(
const or_options_t *old_options, const or_options_t *new_options);
static int options_transition_affects_descriptor(
const or_options_t *old_options, const or_options_t *new_options);
-static char *get_bindaddr_from_transport_listen_line(const char *line,
- const char *transport);
static int parse_ports(or_options_t *options, int validate_only,
char **msg_out, int *n_ports_out,
int *world_writable_control_socket);
@@ -4108,46 +4107,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
REJECT("Invalid client transport line. See logs for details.");
}
- for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
- if (parse_transport_line(options, cl->value, 1, 1) < 0)
- REJECT("Invalid server transport line. See logs for details.");
- }
-
- if (options->ServerTransportPlugin && !server_mode(options)) {
- log_notice(LD_GENERAL, "Tor is not configured as a relay but you specified"
- " a ServerTransportPlugin line (%s). The ServerTransportPlugin "
- "line will be ignored.",
- escaped(options->ServerTransportPlugin->value));
- }
-
- for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
- /** If get_bindaddr_from_transport_listen_line() fails with
- 'transport' being NULL, it means that something went wrong
- while parsing the ServerTransportListenAddr line. */
- char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
- if (!bindaddr)
- REJECT("ServerTransportListenAddr did not parse. See logs for details.");
- tor_free(bindaddr);
- }
-
- if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
- log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
- "specify a transport listen address. The "
- "ServerTransportListenAddr line will be ignored.");
- }
-
- for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
- /** If get_options_from_transport_options_line() fails with
- 'transport' being NULL, it means that something went wrong
- while parsing the ServerTransportOptions line. */
- smartlist_t *options_sl =
- get_options_from_transport_options_line(cl->value, NULL);
- if (!options_sl)
- REJECT("ServerTransportOptions did not parse. See logs for details.");
-
- SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
- smartlist_free(options_sl);
- }
+ if (options_validate_server_transport(old_options, options, msg) < 0)
+ return -1;
if (options->ConstrainedSockets) {
/* If the user wants to constrain socket buffer use, make sure the desired
@@ -5564,8 +5525,7 @@ parse_bridge_line(const char *line)
* our internal transport list.
* - If it's a managed proxy line, launch the managed proxy.
*/
-
-STATIC int
+int
parse_transport_line(const or_options_t *options,
const char *line, int validate_only,
int server)
@@ -5759,157 +5719,6 @@ parse_transport_line(const or_options_t *options,
return r;
}
-/** Given a ServerTransportListenAddr <b>line</b>, return its
- * <address:port> string. Return NULL if the line was not
- * well-formed.
- *
- * If <b>transport</b> is set, return NULL if the line is not
- * referring to <b>transport</b>.
- *
- * The returned string is allocated on the heap and it's the
- * responsibility of the caller to free it. */
-static char *
-get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
-{
- smartlist_t *items = NULL;
- const char *parsed_transport = NULL;
- char *addrport = NULL;
- tor_addr_t addr;
- uint16_t port = 0;
-
- items = smartlist_new();
- smartlist_split_string(items, line, NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
-
- if (smartlist_len(items) < 2) {
- log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
- goto err;
- }
-
- parsed_transport = smartlist_get(items, 0);
- addrport = tor_strdup(smartlist_get(items, 1));
-
- /* If 'transport' is given, check if it matches the one on the line */
- if (transport && strcmp(transport, parsed_transport))
- goto err;
-
- /* Validate addrport */
- if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
- log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
- "address '%s'", addrport);
- goto err;
- }
-
- goto done;
-
- err:
- tor_free(addrport);
- addrport = NULL;
-
- done:
- SMARTLIST_FOREACH(items, char*, s, tor_free(s));
- smartlist_free(items);
-
- return addrport;
-}
-
-/** Given a ServerTransportOptions <b>line</b>, return a smartlist
- * with the options. Return NULL if the line was not well-formed.
- *
- * If <b>transport</b> is set, return NULL if the line is not
- * referring to <b>transport</b>.
- *
- * The returned smartlist and its strings are allocated on the heap
- * and it's the responsibility of the caller to free it. */
-smartlist_t *
-get_options_from_transport_options_line(const char *line,const char *transport)
-{
- smartlist_t *items = smartlist_new();
- smartlist_t *options = smartlist_new();
- const char *parsed_transport = NULL;
-
- smartlist_split_string(items, line, NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
-
- if (smartlist_len(items) < 2) {
- log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
- goto err;
- }
-
- parsed_transport = smartlist_get(items, 0);
- /* If 'transport' is given, check if it matches the one on the line */
- if (transport && strcmp(transport, parsed_transport))
- goto err;
-
- SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
- if (option_sl_idx == 0) /* skip the transport field (first field)*/
- continue;
-
- /* validate that it's a k=v value */
- if (!string_is_key_value(LOG_WARN, option)) {
- log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
- goto err;
- }
-
- /* add it to the options smartlist */
- smartlist_add_strdup(options, option);
- log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
- } SMARTLIST_FOREACH_END(option);
-
- goto done;
-
- err:
- SMARTLIST_FOREACH(options, char*, s, tor_free(s));
- smartlist_free(options);
- options = NULL;
-
- done:
- SMARTLIST_FOREACH(items, char*, s, tor_free(s));
- smartlist_free(items);
-
- return options;
-}
-
-/** Given the name of a pluggable transport in <b>transport</b>, check
- * the configuration file to see if the user has explicitly asked for
- * it to listen on a specific port. Return a <address:port> string if
- * so, otherwise NULL. */
-char *
-get_transport_bindaddr_from_config(const char *transport)
-{
- config_line_t *cl;
- const or_options_t *options = get_options();
-
- for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
- char *bindaddr =
- get_bindaddr_from_transport_listen_line(cl->value, transport);
- if (bindaddr)
- return bindaddr;
- }
-
- return NULL;
-}
-
-/** Given the name of a pluggable transport in <b>transport</b>, check
- * the configuration file to see if the user has asked us to pass any
- * parameters to the pluggable transport. Return a smartlist
- * containing the parameters, otherwise NULL. */
-smartlist_t *
-get_options_for_server_transport(const char *transport)
-{
- config_line_t *cl;
- const or_options_t *options = get_options();
-
- for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
- smartlist_t *options_sl =
- get_options_from_transport_options_line(cl->value, transport);
- if (options_sl)
- return options_sl;
- }
-
- return NULL;
-}
-
/** Read the contents of a DirAuthority line from <b>line</b>. If
* <b>validate_only</b> is 0, and the line is well-formed, and it
* shares any bits with <b>required_type</b> or <b>required_type</b>
diff --git a/src/app/config/config.h b/src/app/config/config.h
index e2174b127..0ab25344a 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -192,8 +192,6 @@ int getinfo_helper_config(control_connection_t *conn,
uint32_t get_effective_bwrate(const or_options_t *options);
uint32_t get_effective_bwburst(const or_options_t *options);
-char *get_transport_bindaddr_from_config(const char *transport);
-
int init_cookie_authentication(const char *fname, const char *header,
int cookie_len, int group_readable,
uint8_t **cookie_out, int *cookie_is_set_out);
@@ -248,9 +246,6 @@ void bridge_line_free_(bridge_line_t *bridge_line);
#define bridge_line_free(line) \
FREE_AND_NULL(bridge_line_t, bridge_line_free_, (line))
bridge_line_t *parse_bridge_line(const char *line);
-smartlist_t *get_options_from_transport_options_line(const char *line,
- const char *transport);
-smartlist_t *get_options_for_server_transport(const char *transport);
/* Port helper functions. */
int options_any_client_port_set(const or_options_t *options);
@@ -279,6 +274,9 @@ void port_cfg_free_(port_cfg_t *port);
int count_real_listeners(const smartlist_t *ports,
int listenertype,
int count_sockets);
+int parse_transport_line(const or_options_t *options,
+ const char *line, int validate_only,
+ int server);
#ifdef CONFIG_PRIVATE
@@ -293,9 +291,6 @@ STATIC const struct config_mgr_t *get_options_mgr(void);
STATIC void or_options_free_(or_options_t *options);
STATIC int options_validate_single_onion(or_options_t *options,
char **msg);
-STATIC int parse_transport_line(const or_options_t *options,
- const char *line, int validate_only,
- int server);
STATIC int consider_adding_dir_servers(const or_options_t *options,
const or_options_t *old_options);
STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type);
diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c
index 1d6f63cde..c4504b3ca 100644
--- a/src/app/config/statefile.c
+++ b/src/app/config/statefile.c
@@ -32,6 +32,7 @@
#include "core/or/or.h"
#include "core/or/circuitstats.h"
#include "app/config/config.h"
+#include "feature/relay/transport_config.h"
#include "lib/confmgt/confmgt.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/netstatus.h"
diff --git a/src/core/include.am b/src/core/include.am
index b08f14d49..eda929df4 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -149,6 +149,7 @@ LIBTOR_APP_A_SOURCES = \
src/feature/relay/router.c \
src/feature/relay/routerkeys.c \
src/feature/relay/selftest.c \
+ src/feature/relay/transport_config.c \
src/feature/rend/rendcache.c \
src/feature/rend/rendclient.c \
src/feature/rend/rendcommon.c \
@@ -438,6 +439,7 @@ noinst_HEADERS += \
src/feature/relay/routerkeys.h \
src/feature/relay/routermode.h \
src/feature/relay/selftest.h \
+ src/feature/relay/transport_config.h \
src/feature/rend/rend_authorized_client_st.h \
src/feature/rend/rend_encoded_v2_service_descriptor_st.h \
src/feature/rend/rend_intro_point_st.h \
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 3f731ac7d..1640c943a 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -97,6 +97,8 @@
#include "core/or/circuitbuild.h"
#include "feature/client/transports.h"
#include "feature/relay/router.h"
+/* 31851: split the server transport code out of the client module */
+#include "feature/relay/transport_config.h"
#include "app/config/statefile.h"
#include "core/or/connection_or.h"
#include "feature/relay/ext_orport.h"
diff --git a/src/feature/relay/transport_config.c b/src/feature/relay/transport_config.c
new file mode 100644
index 000000000..b323f4299
--- /dev/null
+++ b/src/feature/relay/transport_config.c
@@ -0,0 +1,247 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file transport_config.c
+ * @brief Code to interpret the user's configuration of Tor's server
+ * pluggable transports.
+ **/
+
+#include "orconfig.h"
+#include "feature/relay/transport_config.h"
+
+#include "lib/encoding/confline.h"
+#include "lib/encoding/keyval.h"
+
+#include "lib/container/smartlist.h"
+
+/* Required for dirinfo_type_t in or_options_t */
+#include "core/or/or.h"
+#include "app/config/config.h"
+
+#include "feature/relay/ext_orport.h"
+#include "feature/relay/routermode.h"
+
+/* Copied from config.c, we will refactor later in 29211. */
+#define REJECT(arg) \
+ STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
+
+/** Given a ServerTransportListenAddr <b>line</b>, return its
+ * <address:port> string. Return NULL if the line was not
+ * well-formed.
+ *
+ * If <b>transport</b> is set, return NULL if the line is not
+ * referring to <b>transport</b>.
+ *
+ * The returned string is allocated on the heap and it's the
+ * responsibility of the caller to free it. */
+static char *
+get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
+{
+ smartlist_t *items = NULL;
+ const char *parsed_transport = NULL;
+ char *addrport = NULL;
+ tor_addr_t addr;
+ uint16_t port = 0;
+
+ items = smartlist_new();
+ smartlist_split_string(items, line, NULL,
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+
+ if (smartlist_len(items) < 2) {
+ log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
+ goto err;
+ }
+
+ parsed_transport = smartlist_get(items, 0);
+ addrport = tor_strdup(smartlist_get(items, 1));
+
+ /* If 'transport' is given, check if it matches the one on the line */
+ if (transport && strcmp(transport, parsed_transport))
+ goto err;
+
+ /* Validate addrport */
+ if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
+ log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
+ "address '%s'", addrport);
+ goto err;
+ }
+
+ goto done;
+
+ err:
+ tor_free(addrport);
+ addrport = NULL;
+
+ done:
+ SMARTLIST_FOREACH(items, char*, s, tor_free(s));
+ smartlist_free(items);
+
+ return addrport;
+}
+
+/** Given the name of a pluggable transport in <b>transport</b>, check
+ * the configuration file to see if the user has explicitly asked for
+ * it to listen on a specific port. Return a <address:port> string if
+ * so, otherwise NULL. */
+char *
+get_transport_bindaddr_from_config(const char *transport)
+{
+ config_line_t *cl;
+ const or_options_t *options = get_options();
+
+ for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
+ char *bindaddr =
+ get_bindaddr_from_transport_listen_line(cl->value, transport);
+ if (bindaddr)
+ return bindaddr;
+ }
+
+ return NULL;
+}
+
+/** Given a ServerTransportOptions <b>line</b>, return a smartlist
+ * with the options. Return NULL if the line was not well-formed.
+ *
+ * If <b>transport</b> is set, return NULL if the line is not
+ * referring to <b>transport</b>.
+ *
+ * The returned smartlist and its strings are allocated on the heap
+ * and it's the responsibility of the caller to free it. */
+smartlist_t *
+get_options_from_transport_options_line(const char *line,const char *transport)
+{
+ smartlist_t *items = smartlist_new();
+ smartlist_t *options = smartlist_new();
+ const char *parsed_transport = NULL;
+
+ smartlist_split_string(items, line, NULL,
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+
+ if (smartlist_len(items) < 2) {
+ log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
+ goto err;
+ }
+
+ parsed_transport = smartlist_get(items, 0);
+ /* If 'transport' is given, check if it matches the one on the line */
+ if (transport && strcmp(transport, parsed_transport))
+ goto err;
+
+ SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
+ if (option_sl_idx == 0) /* skip the transport field (first field)*/
+ continue;
+
+ /* validate that it's a k=v value */
+ if (!string_is_key_value(LOG_WARN, option)) {
+ log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
+ goto err;
+ }
+
+ /* add it to the options smartlist */
+ smartlist_add_strdup(options, option);
+ log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
+ } SMARTLIST_FOREACH_END(option);
+
+ goto done;
+
+ err:
+ SMARTLIST_FOREACH(options, char*, s, tor_free(s));
+ smartlist_free(options);
+ options = NULL;
+
+ done:
+ SMARTLIST_FOREACH(items, char*, s, tor_free(s));
+ smartlist_free(items);
+
+ return options;
+}
+
+/** Given the name of a pluggable transport in <b>transport</b>, check
+ * the configuration file to see if the user has asked us to pass any
+ * parameters to the pluggable transport. Return a smartlist
+ * containing the parameters, otherwise NULL. */
+smartlist_t *
+get_options_for_server_transport(const char *transport)
+{
+ config_line_t *cl;
+ const or_options_t *options = get_options();
+
+ for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
+ smartlist_t *options_sl =
+ get_options_from_transport_options_line(cl->value, transport);
+ if (options_sl)
+ return options_sl;
+ }
+
+ return NULL;
+}
+
+/**
+ * Legacy validation/normalization function for the server transport options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_server_transport(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ config_line_t *cl;
+
+ for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
+ if (parse_transport_line(options, cl->value, 1, 1) < 0)
+ REJECT("Invalid server transport line. See logs for details.");
+ }
+
+ if (options->ServerTransportPlugin && !server_mode(options)) {
+ log_notice(LD_GENERAL, "Tor is not configured as a relay but you specified"
+ " a ServerTransportPlugin line (%s). The ServerTransportPlugin "
+ "line will be ignored.",
+ escaped(options->ServerTransportPlugin->value));
+ }
+
+ for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
+ /** If get_bindaddr_from_transport_listen_line() fails with
+ 'transport' being NULL, it means that something went wrong
+ while parsing the ServerTransportListenAddr line. */
+ char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
+ if (!bindaddr)
+ REJECT("ServerTransportListenAddr did not parse. See logs for details.");
+ tor_free(bindaddr);
+ }
+
+ if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
+ log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
+ "specify a transport listen address. The "
+ "ServerTransportListenAddr line will be ignored.");
+ }
+
+ for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
+ /** If get_options_from_transport_options_line() fails with
+ 'transport' being NULL, it means that something went wrong
+ while parsing the ServerTransportOptions line. */
+ smartlist_t *options_sl =
+ get_options_from_transport_options_line(cl->value, NULL);
+ if (!options_sl)
+ REJECT("ServerTransportOptions did not parse. See logs for details.");
+
+ SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
+ smartlist_free(options_sl);
+ }
+
+ return 0;
+}
diff --git a/src/feature/relay/transport_config.h b/src/feature/relay/transport_config.h
new file mode 100644
index 000000000..6ef1bc402
--- /dev/null
+++ b/src/feature/relay/transport_config.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file transport_config.h
+ * @brief Header for feature/relay/transport_config.c
+ **/
+
+#ifndef TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H
+#define TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H
+
+typedef struct or_options_t or_options_t;
+typedef struct smartlist_t smartlist_t;
+
+char *get_transport_bindaddr_from_config(const char *transport);
+smartlist_t *get_options_from_transport_options_line(const char *line,
+ const char *transport);
+smartlist_t *get_options_for_server_transport(const char *transport);
+
+int options_validate_server_transport(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
+#endif /* !defined(TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H) */
diff --git a/src/test/test_config.c b/src/test/test_config.c
index df025fb8f..fce6ad97d 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -18,6 +18,7 @@
#include "core/or/circuitbuild.h"
#include "app/config/config.h"
#include "feature/relay/relay_config.h"
+#include "feature/relay/transport_config.h"
#include "lib/confmgt/confmgt.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
1
0

[tor/master] config: Move bw & other configs into the dirauth module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit 0a511778eb6f3ca00d0e3da99327cce2cf179830
Author: teor <teor(a)torproject.org>
Date: Tue Oct 29 17:57:04 2019 +1000
config: Move bw & other configs into the dirauth module
This commit:
* moves bandwidth checks into dirauth_config, and
* moves some other minor checks into dirauth_config.
The moved code is disabled when the dirauth module is disabled.
(And some of the checks are re-ordered, so the order of some
warnings may change.)
Part of 32213.
---
src/app/config/config.c | 22 ++----------------
src/feature/dirauth/dirauth_config.c | 45 ++++++++++++++++++++++++++++++++++++
src/feature/dirauth/dirauth_config.h | 7 ++++++
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index b9a15a682..7c31a4443 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -3418,13 +3418,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options_init_logs(old_options, options, 1)<0)
REJECT("Failed to validate Log options. See logs for details.");
- if (authdir_mode(options)) {
- /* confirm that our address isn't broken, so we can complain now */
- uint32_t tmp;
- if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0)
- REJECT("Failed to resolve/guess local address. See logs for details.");
- }
-
/* XXXX require that the only port not be DirPort? */
/* XXXX require that at least one port be listened-upon. */
if (n_ports == 0 && !options->RendConfigLines)
@@ -3649,12 +3642,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options_validate_relay_padding(old_options, options, msg) < 0)
return -1;
- if (options->MinUptimeHidServDirectoryV2 < 0) {
- log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
- "least 0 seconds. Changing to 0.");
- options->MinUptimeHidServDirectoryV2 = 0;
- }
-
const int min_rendpostperiod =
options->TestingTorNetwork ?
MIN_REND_POST_PERIOD_TESTING : MIN_REND_POST_PERIOD;
@@ -3833,16 +3820,11 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (ensure_bandwidth_cap(&options->BandwidthBurst,
"BandwidthBurst", msg) < 0)
return -1;
- if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
- "AuthDirFastGuarantee", msg) < 0)
- return -1;
- if (ensure_bandwidth_cap(&options->AuthDirGuardBWGuarantee,
- "AuthDirGuardBWGuarantee", msg) < 0)
- return -1;
-
if (options_validate_relay_bandwidth(old_options, options, msg) < 0)
return -1;
+ if (options_validate_dirauth_bandwidth(old_options, options, msg) < 0)
+ return -1;
if (options->BandwidthRate > options->BandwidthBurst)
REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 56a71e950..6574edb54 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -61,6 +61,11 @@ options_validate_dirauth_mode(const or_options_t *old_options,
return -1;
if (options->AuthoritativeDir) {
+ /* confirm that our address isn't broken, so we can complain now */
+ uint32_t tmp;
+ if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0)
+ REJECT("Failed to resolve/guess local address. See logs for details.");
+
if (!options->ContactInfo && !options->TestingTorNetwork)
REJECT("Authoritative directory servers must set ContactInfo");
if (!options->RecommendedClientVersions)
@@ -117,6 +122,46 @@ options_validate_dirauth_mode(const or_options_t *old_options,
REJECT("Running as authoritative directory, but ClientOnly also set.");
}
+ /* 31851: the tests expect us to validate these options, even when we are
+ * not in authority mode. */
+ if (options->MinUptimeHidServDirectoryV2 < 0) {
+ log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
+ "least 0 seconds. Changing to 0.");
+ options->MinUptimeHidServDirectoryV2 = 0;
+ }
+
+ return 0;
+}
+
+/**
+ * Legacy validation/normalization function for the dirauth bandwidth options
+ * in options. Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_dirauth_bandwidth(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ /* 31851: the tests expect us to validate these options, even when we are
+ * not in authority mode. */
+ if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
+ "AuthDirFastGuarantee", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->AuthDirGuardBWGuarantee,
+ "AuthDirGuardBWGuarantee", msg) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index 95aef3de9..2c67c62ec 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -20,6 +20,10 @@ int options_validate_dirauth_mode(const or_options_t *old_options,
or_options_t *options,
char **msg);
+int options_validate_dirauth_bandwidth(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
int options_validate_dirauth_schedule(const or_options_t *old_options,
or_options_t *options,
char **msg);
@@ -56,6 +60,9 @@ options_validate_dirauth_mode(const or_options_t *old_options,
return 0;
}
+#define options_validate_dirauth_bandwidth(old_options, options, msg) \
+ (((void)(old_options)),((void)(options)),((void)(msg)),0)
+
#define options_validate_dirauth_schedule(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
1
0

[tor/master] config: Move accounting/bandwidth config into the relay module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit d5ca56e2543fb988de34b10d1d868c2c2e96cd51
Author: teor <teor(a)torproject.org>
Date: Tue Oct 29 17:54:18 2019 +1000
config: Move accounting/bandwidth config into the relay module
This commit:
* moves accounting and bandwidth checks into relay_config,
* moves testing options checks into relay_config,
* moves some other minor checks into relay_config,
* exposes some code from src/app/config.c
(we'll refactor it later in 29211), and
* adds thin wrappers to make the moved code compile.
No functional changes: the moved code is still enabled,
even if the relay module is disabled. (Some of the checks
are re-ordered, so the order of some warnings may change.)
Part of 32213.
---
src/app/config/config.c | 117 +++------------------------
src/app/config/config.h | 4 +-
src/feature/relay/relay_config.c | 167 +++++++++++++++++++++++++++++++++++++++
src/feature/relay/relay_config.h | 10 +++
src/feature/relay/router.c | 1 +
5 files changed, 188 insertions(+), 111 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 4ec38e30c..b9a15a682 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -1747,32 +1747,6 @@ options_need_geoip_info(const or_options_t *options, const char **reason_out)
return bridge_usage || routerset_usage;
}
-/** Return the bandwidthrate that we are going to report to the authorities
- * based on the config options. */
-uint32_t
-get_effective_bwrate(const or_options_t *options)
-{
- uint64_t bw = options->BandwidthRate;
- if (bw > options->MaxAdvertisedBandwidth)
- bw = options->MaxAdvertisedBandwidth;
- if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
- bw = options->RelayBandwidthRate;
- /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
- return (uint32_t)bw;
-}
-
-/** Return the bandwidthburst that we are going to report to the authorities
- * based on the config options. */
-uint32_t
-get_effective_bwburst(const or_options_t *options)
-{
- uint64_t bw = options->BandwidthBurst;
- if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
- bw = options->RelayBandwidthBurst;
- /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
- return (uint32_t)bw;
-}
-
/* Used in the various options_transition_affects* functions. */
#define YES_IF_CHANGED_BOOL(opt) \
if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1;
@@ -3091,7 +3065,7 @@ validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
* a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
* Else return 0.
*/
-static int
+int
ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
{
if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
@@ -3418,6 +3392,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options_validate_relay_os(old_options, options, msg) < 0)
return -1;
+ /* 31851: OutboundBindAddressExit is unused in client mode */
if (parse_outbound_addresses(options, 1, msg) < 0)
return -1;
@@ -3426,6 +3401,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
/* need to check for relative paths after we populate
* options->DataDirectory (just above). */
+ /* 31851: some paths are unused in client mode */
if (warn_about_relative_paths(options) && options->RunAsDaemon) {
REJECT("You have specified at least one relative path (see above) "
"with the RunAsDaemon option. RunAsDaemon is not compatible "
@@ -3435,6 +3411,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (options_validate_relay_info(old_options, options, msg) < 0)
return -1;
+ /* 31851: this function is currently a no-op in client mode */
check_network_configuration(server_mode(options));
/* Validate the tor_log(s) */
@@ -3448,13 +3425,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
REJECT("Failed to resolve/guess local address. See logs for details.");
}
- if (server_mode(options) && options->RendConfigLines)
- log_warn(LD_CONFIG,
- "Tor is currently configured as a relay and a hidden service. "
- "That's not very secure: you should probably run your hidden service "
- "in a separate Tor process, at least -- see "
- "https://trac.torproject.org/8742");
-
/* XXXX require that the only port not be DirPort? */
/* XXXX require that at least one port be listened-upon. */
if (n_ports == 0 && !options->RendConfigLines)
@@ -3863,21 +3833,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (ensure_bandwidth_cap(&options->BandwidthBurst,
"BandwidthBurst", msg) < 0)
return -1;
- if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
- "MaxAdvertisedBandwidth", msg) < 0)
- return -1;
- if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
- "RelayBandwidthRate", msg) < 0)
- return -1;
- if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
- "RelayBandwidthBurst", msg) < 0)
- return -1;
- if (ensure_bandwidth_cap(&options->PerConnBWRate,
- "PerConnBWRate", msg) < 0)
- return -1;
- if (ensure_bandwidth_cap(&options->PerConnBWBurst,
- "PerConnBWBurst", msg) < 0)
- return -1;
if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
"AuthDirFastGuarantee", msg) < 0)
return -1;
@@ -3885,58 +3840,15 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
"AuthDirGuardBWGuarantee", msg) < 0)
return -1;
- if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
- options->RelayBandwidthBurst = options->RelayBandwidthRate;
- if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
- options->RelayBandwidthRate = options->RelayBandwidthBurst;
if (options_validate_relay_bandwidth(old_options, options, msg) < 0)
return -1;
- if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
- REJECT("RelayBandwidthBurst must be at least equal "
- "to RelayBandwidthRate.");
-
if (options->BandwidthRate > options->BandwidthBurst)
REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
- /* if they set relaybandwidth* really high but left bandwidth*
- * at the default, raise the defaults. */
- if (options->RelayBandwidthRate > options->BandwidthRate)
- options->BandwidthRate = options->RelayBandwidthRate;
- if (options->RelayBandwidthBurst > options->BandwidthBurst)
- options->BandwidthBurst = options->RelayBandwidthBurst;
-
- if (accounting_parse_options(options, 1)<0)
- REJECT("Failed to parse accounting options. See logs for details.");
-
- if (options->AccountingMax) {
- if (options->RendConfigLines && server_mode(options)) {
- log_warn(LD_CONFIG, "Using accounting with a hidden service and an "
- "ORPort is risky: your hidden service(s) and your public "
- "address will all turn off at the same time, which may alert "
- "observers that they are being run by the same party.");
- } else if (config_count_key(options->RendConfigLines,
- "HiddenServiceDir") > 1) {
- log_warn(LD_CONFIG, "Using accounting with multiple hidden services is "
- "risky: they will all turn off at the same time, which may "
- "alert observers that they are being run by the same party.");
- }
- }
-
- options->AccountingRule = ACCT_MAX;
- if (options->AccountingRule_option) {
- if (!strcmp(options->AccountingRule_option, "sum"))
- options->AccountingRule = ACCT_SUM;
- else if (!strcmp(options->AccountingRule_option, "max"))
- options->AccountingRule = ACCT_MAX;
- else if (!strcmp(options->AccountingRule_option, "in"))
- options->AccountingRule = ACCT_IN;
- else if (!strcmp(options->AccountingRule_option, "out"))
- options->AccountingRule = ACCT_OUT;
- else
- REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
- }
+ if (options_validate_relay_accounting(old_options, options, msg) < 0)
+ return -1;
if (options_validate_relay_mode(old_options, options, msg) < 0)
return -1;
@@ -4122,14 +4034,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
return -1;
}
- if (options->DirPort_set) {
- /* Providing cached directory entries while system TCP buffers are scarce
- * will exacerbate the socket errors. Suggest that this be disabled. */
- COMPLAIN("You have requested constrained socket buffers while also "
- "serving directory entries via DirPort. It is strongly "
- "suggested that you disable serving directory requests when "
- "system TCP buffer resources are scarce.");
- }
}
if (options_validate_dirauth_schedule(old_options, options, msg) < 0)
@@ -4174,6 +4078,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
if (! options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
or_options_t *dflt_options = options_new();
options_init(dflt_options);
+ /* 31851: some of these options are dirauth or relay only */
CHECK_DEFAULT(TestingV3AuthInitialVotingInterval);
CHECK_DEFAULT(TestingV3AuthInitialVoteDelay);
CHECK_DEFAULT(TestingV3AuthInitialDistDelay);
@@ -4201,13 +4106,9 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
!(options->DirAuthorities ||
(options->AlternateDirAuthority && options->AlternateBridgeAuthority)))
REJECT("ClientDNSRejectInternalAddresses used for default network.");
- if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
- REJECT("SigningKeyLifetime is too short.");
- if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2)
- REJECT("LinkCertLifetime is too short.");
- if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
- REJECT("TestingAuthKeyLifetime is too short.");
+ if (options_validate_relay_testing(old_options, options, msg) < 0)
+ return -1;
if (options_validate_dirauth_testing(old_options, options, msg) < 0)
return -1;
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 0ab25344a..e49da6aa8 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -189,9 +189,6 @@ int getinfo_helper_config(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg);
-uint32_t get_effective_bwrate(const or_options_t *options);
-uint32_t get_effective_bwburst(const or_options_t *options);
-
int init_cookie_authentication(const char *fname, const char *header,
int cookie_len, int group_readable,
uint8_t **cookie_out, int *cookie_is_set_out);
@@ -277,6 +274,7 @@ int count_real_listeners(const smartlist_t *ports,
int parse_transport_line(const or_options_t *options,
const char *line, int validate_only,
int server);
+int ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg);
#ifdef CONFIG_PRIVATE
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index 1d33f12b3..7f1f04665 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -27,6 +27,7 @@
#include "core/mainloop/connection.h"
#include "core/or/port_cfg_st.h"
+#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/nickname.h"
#include "feature/relay/dns.h"
@@ -522,6 +523,29 @@ options_validate_relay_bandwidth(const or_options_t *old_options,
if (BUG(!msg))
return -1;
+ /* 31851: the tests expect us to validate bandwidths, even when we are not
+ * in relay mode. */
+ if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
+ "MaxAdvertisedBandwidth", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
+ "RelayBandwidthRate", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
+ "RelayBandwidthBurst", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->PerConnBWRate,
+ "PerConnBWRate", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->PerConnBWBurst,
+ "PerConnBWBurst", msg) < 0)
+ return -1;
+
+ if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
+ options->RelayBandwidthBurst = options->RelayBandwidthRate;
+ if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
+ options->RelayBandwidthRate = options->RelayBandwidthBurst;
+
if (server_mode(options)) {
const unsigned required_min_bw =
public_server_mode(options) ?
@@ -555,6 +579,101 @@ options_validate_relay_bandwidth(const or_options_t *old_options,
}
}
+ /* 31851: the tests expect us to validate bandwidths, even when we are not
+ * in relay mode. */
+ if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
+ REJECT("RelayBandwidthBurst must be at least equal "
+ "to RelayBandwidthRate.");
+
+ /* if they set relaybandwidth* really high but left bandwidth*
+ * at the default, raise the defaults. */
+ if (options->RelayBandwidthRate > options->BandwidthRate)
+ options->BandwidthRate = options->RelayBandwidthRate;
+ if (options->RelayBandwidthBurst > options->BandwidthBurst)
+ options->BandwidthBurst = options->RelayBandwidthBurst;
+
+ return 0;
+}
+
+/** Return the bandwidthrate that we are going to report to the authorities
+ * based on the config options. */
+uint32_t
+get_effective_bwrate(const or_options_t *options)
+{
+ uint64_t bw = options->BandwidthRate;
+ if (bw > options->MaxAdvertisedBandwidth)
+ bw = options->MaxAdvertisedBandwidth;
+ if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
+ bw = options->RelayBandwidthRate;
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
+}
+
+/** Return the bandwidthburst that we are going to report to the authorities
+ * based on the config options. */
+uint32_t
+get_effective_bwburst(const or_options_t *options)
+{
+ uint64_t bw = options->BandwidthBurst;
+ if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
+ bw = options->RelayBandwidthBurst;
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
+}
+
+/**
+ * Legacy validation/normalization function for the relay bandwidth accounting
+ * options. Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_accounting(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ /* 31851: the tests expect us to validate accounting, even when we are not
+ * in relay mode. */
+ if (accounting_parse_options(options, 1)<0)
+ REJECT("Failed to parse accounting options. See logs for details.");
+
+ if (options->AccountingMax) {
+ if (options->RendConfigLines && server_mode(options)) {
+ log_warn(LD_CONFIG, "Using accounting with a hidden service and an "
+ "ORPort is risky: your hidden service(s) and your public "
+ "address will all turn off at the same time, which may alert "
+ "observers that they are being run by the same party.");
+ } else if (config_count_key(options->RendConfigLines,
+ "HiddenServiceDir") > 1) {
+ log_warn(LD_CONFIG, "Using accounting with multiple hidden services is "
+ "risky: they will all turn off at the same time, which may "
+ "alert observers that they are being run by the same party.");
+ }
+ }
+
+ options->AccountingRule = ACCT_MAX;
+ if (options->AccountingRule_option) {
+ if (!strcmp(options->AccountingRule_option, "sum"))
+ options->AccountingRule = ACCT_SUM;
+ else if (!strcmp(options->AccountingRule_option, "max"))
+ options->AccountingRule = ACCT_MAX;
+ else if (!strcmp(options->AccountingRule_option, "in"))
+ options->AccountingRule = ACCT_IN;
+ else if (!strcmp(options->AccountingRule_option, "out"))
+ options->AccountingRule = ACCT_OUT;
+ else
+ REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
+ }
+
return 0;
}
@@ -703,6 +822,13 @@ options_validate_relay_mode(const or_options_t *old_options,
if (BUG(!msg))
return -1;
+ if (server_mode(options) && options->RendConfigLines)
+ log_warn(LD_CONFIG,
+ "Tor is currently configured as a relay and a hidden service. "
+ "That's not very secure: you should probably run your hidden service "
+ "in a separate Tor process, at least -- see "
+ "https://trac.torproject.org/8742");
+
if (options->BridgeRelay && options->DirPort_set) {
log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
"DirPort");
@@ -747,5 +873,46 @@ options_validate_relay_mode(const or_options_t *old_options,
options->MyFamily_lines, "MyFamily", msg))
return -1;
+ if (options->ConstrainedSockets) {
+ if (options->DirPort_set) {
+ /* Providing cached directory entries while system TCP buffers are scarce
+ * will exacerbate the socket errors. Suggest that this be disabled. */
+ COMPLAIN("You have requested constrained socket buffers while also "
+ "serving directory entries via DirPort. It is strongly "
+ "suggested that you disable serving directory requests when "
+ "system TCP buffer resources are scarce.");
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Legacy validation/normalization function for the relay testing options
+ * in options. Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_relay_testing(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg)
+{
+ (void)old_options;
+
+ if (BUG(!options))
+ return -1;
+
+ if (BUG(!msg))
+ return -1;
+
+ if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
+ REJECT("SigningKeyLifetime is too short.");
+ if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2)
+ REJECT("LinkCertLifetime is too short.");
+ if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
+ REJECT("TestingAuthKeyLifetime is too short.");
+
return 0;
}
diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h
index 93fcd4acb..83ff3a2a8 100644
--- a/src/feature/relay/relay_config.h
+++ b/src/feature/relay/relay_config.h
@@ -44,11 +44,21 @@ int options_validate_relay_padding(const or_options_t *old_options,
int options_validate_relay_bandwidth(const or_options_t *old_options,
or_options_t *options,
char **msg);
+uint32_t get_effective_bwrate(const or_options_t *options);
+uint32_t get_effective_bwburst(const or_options_t *options);
+
+int options_validate_relay_accounting(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
int options_validate_relay_mode(const or_options_t *old_options,
or_options_t *options,
char **msg);
+int options_validate_relay_testing(const or_options_t *old_options,
+ or_options_t *options,
+ char **msg);
+
#ifdef RELAY_CONFIG_PRIVATE
STATIC int check_bridge_distribution_setting(const char *bd);
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 5c7901093..c80a8b8c0 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -35,6 +35,7 @@
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/torcert.h"
#include "feature/relay/dns.h"
+#include "feature/relay/relay_config.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
#include "feature/relay/routermode.h"
1
0

[tor/master] config: Move server transport actions into the relay module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit 6d03c0566568f4a56efb4aea2f32bcd86c090a22
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 13:55:49 2019 +1000
config: Move server transport actions into the relay module
This commit:
* moves server transport config checks into transport_config.c,
* adds thin wrappers to make the moved code compile.
No functional changes: the moved code is still enabled,
even if the relay module is disabled. (Some of the checks
are re-ordered, so the order of some warnings may change.)
Part of 32213.
---
src/app/config/config.c | 38 ++++--------------------
src/feature/relay/transport_config.c | 57 ++++++++++++++++++++++++++++++++++++
src/feature/relay/transport_config.h | 2 ++
3 files changed, 64 insertions(+), 33 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 7c31a4443..b257603b0 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -1865,19 +1865,6 @@ options_act,(const or_options_t *old_options))
"in a non-anonymous mode. It will provide NO ANONYMITY.");
}
- /* If we are a bridge with a pluggable transport proxy but no
- Extended ORPort, inform the user that they are missing out. */
- if (server_mode(options) && options->ServerTransportPlugin &&
- !options->ExtORPort_lines) {
- log_notice(LD_CONFIG, "We use pluggable transports but the Extended "
- "ORPort is disabled. Tor and your pluggable transports proxy "
- "communicate with each other via the Extended ORPort so it "
- "is suggested you enable it: it will also allow your Bridge "
- "to collect statistics about its clients that use pluggable "
- "transports. Please enable it using the ExtORPort torrc option "
- "(e.g. set 'ExtORPort auto').");
- }
-
if (options->Bridges) {
mark_bridge_list();
for (cl = options->Bridges; cl; cl = cl->next) {
@@ -1930,13 +1917,7 @@ options_act,(const or_options_t *old_options))
rep_hist_load_mtbf_data(time(NULL));
}
- /* If we have an ExtORPort, initialize its auth cookie. */
- if (running_tor &&
- init_ext_or_cookie_authentication(!!options->ExtORPort_lines) < 0) {
- log_warn(LD_CONFIG,"Error creating Extended ORPort cookie file.");
- return -1;
- }
-
+ /* 31851: some of the code in these functions is relay-only */
mark_transport_list();
pt_prepare_proxy_list_for_config_read();
if (!options->DisableNetwork) {
@@ -1952,20 +1933,11 @@ options_act,(const or_options_t *old_options))
}
}
}
-
- if (options->ServerTransportPlugin && server_mode(options)) {
- for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
- if (parse_transport_line(options, cl->value, 0, 1) < 0) {
- // LCOV_EXCL_START
- log_warn(LD_BUG,
- "Previously validated ServerTransportPlugin line "
- "could not be added!");
- return -1;
- // LCOV_EXCL_STOP
- }
- }
- }
}
+
+ if (options_act_server_transport(old_options) < 0)
+ return -1;
+
sweep_transport_list();
sweep_proxy_list();
diff --git a/src/feature/relay/transport_config.c b/src/feature/relay/transport_config.c
index b323f4299..4ce00ec6c 100644
--- a/src/feature/relay/transport_config.c
+++ b/src/feature/relay/transport_config.c
@@ -245,3 +245,60 @@ options_validate_server_transport(const or_options_t *old_options,
return 0;
}
+
+/** Fetch the active option list, and take server pluggable transport actions
+ * based on it. All of the things we do should survive being done repeatedly.
+ * If present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_server_transport(const or_options_t *old_options)
+{
+ (void)old_options;
+
+ config_line_t *cl;
+ const or_options_t *options = get_options();
+ int running_tor = options->command == CMD_RUN_TOR;
+
+ /* If we are a bridge with a pluggable transport proxy but no
+ Extended ORPort, inform the user that they are missing out. */
+ if (server_mode(options) && options->ServerTransportPlugin &&
+ !options->ExtORPort_lines) {
+ log_notice(LD_CONFIG, "We use pluggable transports but the Extended "
+ "ORPort is disabled. Tor and your pluggable transports proxy "
+ "communicate with each other via the Extended ORPort so it "
+ "is suggested you enable it: it will also allow your Bridge "
+ "to collect statistics about its clients that use pluggable "
+ "transports. Please enable it using the ExtORPort torrc option "
+ "(e.g. set 'ExtORPort auto').");
+ }
+
+ /* If we have an ExtORPort, initialize its auth cookie. */
+ if (running_tor &&
+ init_ext_or_cookie_authentication(!!options->ExtORPort_lines) < 0) {
+ log_warn(LD_CONFIG,"Error creating Extended ORPort cookie file.");
+ return -1;
+ }
+
+ if (!options->DisableNetwork) {
+ if (options->ServerTransportPlugin && server_mode(options)) {
+ for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
+ if (parse_transport_line(options, cl->value, 0, 1) < 0) {
+ // LCOV_EXCL_START
+ log_warn(LD_BUG,
+ "Previously validated ServerTransportPlugin line "
+ "could not be added!");
+ return -1;
+ // LCOV_EXCL_STOP
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/feature/relay/transport_config.h b/src/feature/relay/transport_config.h
index 6ef1bc402..d3ecc9338 100644
--- a/src/feature/relay/transport_config.h
+++ b/src/feature/relay/transport_config.h
@@ -24,4 +24,6 @@ int options_validate_server_transport(const or_options_t *old_options,
or_options_t *options,
char **msg);
+int options_act_server_transport(const or_options_t *old_options);
+
#endif /* !defined(TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H) */
1
0

[tor/master] config: Move relay config actions into the relay module
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit fc5da4ad048af372b7765aa0d10acba05bc6d2dc
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 15:30:11 2019 +1000
config: Move relay config actions into the relay module
This commit:
* moves relay config actions into relay_config,
* moves get_dirportfrontpage() into relay_config,
* adds thin wrappers to make the moved code compile.
No functional changes: the moved code is still enabled,
even if the relay module is disabled. (Some of the checks
are re-ordered, so the order of some warnings may change.)
Part of 32213.
---
src/app/config/config.c | 330 +++---------------------
src/app/config/config.h | 1 -
src/app/main/shutdown.c | 2 +
src/feature/dircache/dircache.c | 1 +
src/feature/relay/relay_config.c | 538 +++++++++++++++++++++++++++++++++++++--
src/feature/relay/relay_config.h | 20 +-
src/test/test_dir_handle_get.c | 1 +
7 files changed, 574 insertions(+), 319 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index b257603b0..4dc023c1a 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -40,9 +40,11 @@
* running.
* <li>options_transition_affects_workers(), in case changes in the option
* might require Tor to relaunch or reconfigure its worker threads.
+ * (This function is now in the relay module.)
* <li>options_transition_affects_descriptor(), in case changes in the
* option might require a Tor relay to build and publish a new server
* descriptor.
+ * (This function is now in the relay module.)
* <li>options_act() and/or options_act_reversible(), in case there's some
* action that needs to be taken immediately based on the option's
* value.
@@ -67,17 +69,14 @@
#include "app/main/main.h"
#include "app/main/subsysmgr.h"
#include "core/mainloop/connection.h"
-#include "core/mainloop/cpuworker.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/netstatus.h"
#include "core/or/channel.h"
-#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitmux.h"
#include "core/or/circuitmux_ewma.h"
#include "core/or/circuitstats.h"
#include "core/or/connection_edge.h"
-#include "core/or/connection_or.h"
#include "core/or/dos.h"
#include "core/or/policies.h"
#include "core/or/relay.h"
@@ -89,7 +88,6 @@
#include "feature/control/control.h"
#include "feature/control/control_auth.h"
#include "feature/control/control_events.h"
-#include "feature/dircache/consdiffmgr.h"
#include "feature/dircache/dirserv.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_config.h"
@@ -108,7 +106,6 @@
#include "feature/rend/rendservice.h"
#include "lib/geoip/geoip.h"
#include "feature/stats/geoip_stats.h"
-#include "feature/stats/predict_ports.h"
#include "feature/stats/rephist.h"
#include "lib/compress/compress.h"
#include "lib/confmgt/structvar.h"
@@ -824,10 +821,6 @@ static char *get_windows_conf_root(void);
static int options_check_transition_cb(const void *old,
const void *new,
char **msg);
-static int options_transition_affects_workers(
- const or_options_t *old_options, const or_options_t *new_options);
-static int options_transition_affects_descriptor(
- const or_options_t *old_options, const or_options_t *new_options);
static int parse_ports(or_options_t *options, int validate_only,
char **msg_out, int *n_ports_out,
int *world_writable_control_socket);
@@ -885,8 +878,6 @@ static char *torrc_fname = NULL;
static char *torrc_defaults_fname = NULL;
/** Result of parsing the command line. */
static parsed_cmdline_t *global_cmdline = NULL;
-/** Contents of most recently read DirPortFrontPage file. */
-static char *global_dirfrontpagecontents = NULL;
/** List of port_cfg_t for all configured ports. */
static smartlist_t *configured_ports = NULL;
/** True iff we're currently validating options, and any calls to
@@ -913,13 +904,6 @@ get_options_mgr(void)
config_check_toplevel_magic(get_options_mgr(), (opt)); \
STMT_END
-/** Return the contents of our frontpage string, or NULL if not configured. */
-MOCK_IMPL(const char*,
-get_dirportfrontpage, (void))
-{
- return global_dirfrontpagecontents;
-}
-
/** Returns the currently configured options. */
MOCK_IMPL(or_options_t *,
get_options_mutable, (void))
@@ -1074,7 +1058,6 @@ config_free_all(void)
tor_free(torrc_fname);
tor_free(torrc_defaults_fname);
- tor_free(global_dirfrontpagecontents);
cleanup_protocol_warning_severity_level();
@@ -1497,6 +1480,7 @@ options_act_reversible,(const or_options_t *old_options, char **msg))
}
/* Adjust the port configuration so we can launch listeners. */
+ /* 31851: some ports are relay-only */
if (parse_ports(options, 0, msg, &n_ports, NULL)) {
if (!*msg)
*msg = tor_strdup("Unexpected problem parsing port config");
@@ -1510,6 +1494,7 @@ options_act_reversible,(const or_options_t *old_options, char **msg))
* ports under 1024.) We don't want to rebind if we're hibernating or
* shutting down. If networking is disabled, this will close all but the
* control listeners, but disable those. */
+ /* 31851: some listeners are relay-only */
if (!we_are_hibernating()) {
if (retry_all_listeners(new_listeners, options->DisableNetwork) < 0) {
*msg = tor_strdup("Failed to bind one of the listener ports.");
@@ -1806,8 +1791,6 @@ options_act,(const or_options_t *old_options))
or_options_t *options = get_options_mutable();
int running_tor = options->command == CMD_RUN_TOR;
char *msg=NULL;
- const int transition_affects_workers =
- old_options && options_transition_affects_workers(old_options, options);
const int transition_affects_guards =
old_options && options_transition_affects_guards(old_options, options);
@@ -1958,16 +1941,8 @@ options_act,(const or_options_t *old_options))
finish_daemon(options->DataDirectory);
}
- /* We want to reinit keys as needed before we do much of anything else:
- keys are important, and other things can depend on them. */
- if (transition_affects_workers ||
- (options->V3AuthoritativeDir && (!old_options ||
- !old_options->V3AuthoritativeDir))) {
- if (init_keys() < 0) {
- log_warn(LD_BUG,"Error initializing keys; exiting");
- return -1;
- }
- }
+ if (options_act_relay(old_options) < 0)
+ return -1;
/* Write our PID to the PID file. If we do not have write permissions we
* will log a warning and exit. */
@@ -1991,15 +1966,6 @@ options_act,(const or_options_t *old_options))
return -1;
}
- if (server_mode(options)) {
- static int cdm_initialized = 0;
- if (cdm_initialized == 0) {
- cdm_initialized = 1;
- consdiffmgr_configure(NULL);
- consdiffmgr_validate();
- }
- }
-
if (init_control_cookie_authentication(options->CookieAuthentication) < 0) {
log_warn(LD_CONFIG,"Error creating control cookie authentication file.");
return -1;
@@ -2017,15 +1983,8 @@ options_act,(const or_options_t *old_options))
* might be a change of scheduler or parameter. */
scheduler_conf_changed();
- /* Set up accounting */
- if (accounting_parse_options(options, 0)<0) {
- // LCOV_EXCL_START
- log_warn(LD_BUG,"Error in previously validated accounting options");
+ if (options_act_relay_accounting(old_options) < 0)
return -1;
- // LCOV_EXCL_STOP
- }
- if (accounting_is_enabled(options))
- configure_accounting(time(NULL));
/* Change the cell EWMA settings */
cmux_ewma_set_options(options, networkstatus_get_latest_consensus());
@@ -2049,6 +2008,7 @@ options_act,(const or_options_t *old_options))
tor_free(http_authenticator);
}
+ /* 31851: OutboundBindAddressExit is relay-only */
if (parse_outbound_addresses(options, 0, &msg) < 0) {
// LCOV_EXCL_START
log_warn(LD_BUG, "Failed parsing previously validated outbound "
@@ -2135,65 +2095,17 @@ options_act,(const or_options_t *old_options))
if (revise_automap_entries)
addressmap_clear_invalid_automaps(options);
-/* How long should we delay counting bridge stats after becoming a bridge?
- * We use this so we don't count clients who used our bridge thinking it is
- * a relay. If you change this, don't forget to change the log message
- * below. It's 4 hours (the time it takes to stop being used by clients)
- * plus some extra time for clock skew. */
-#define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
-
- if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
- int was_relay = 0;
- if (options->BridgeRelay) {
- time_t int_start = time(NULL);
- if (config_lines_eq(old_options->ORPort_lines,options->ORPort_lines)) {
- int_start += RELAY_BRIDGE_STATS_DELAY;
- was_relay = 1;
- }
- geoip_bridge_stats_init(int_start);
- log_info(LD_CONFIG, "We are acting as a bridge now. Starting new "
- "GeoIP stats interval%s.", was_relay ? " in 6 "
- "hours from now" : "");
- } else {
- geoip_bridge_stats_term();
- log_info(LD_GENERAL, "We are no longer acting as a bridge. "
- "Forgetting GeoIP stats.");
- }
- }
-
- if (transition_affects_workers) {
- log_info(LD_GENERAL,
- "Worker-related options changed. Rotating workers.");
- const int server_mode_turned_on =
- server_mode(options) && !server_mode(old_options);
- const int dir_server_mode_turned_on =
- dir_server_mode(options) && !dir_server_mode(old_options);
-
- if (server_mode_turned_on || dir_server_mode_turned_on) {
- cpu_init();
- }
+ if (options_act_bridge_stats(old_options) < 0)
+ return -1;
- if (server_mode_turned_on) {
- ip_address_changed(0);
- if (have_completed_a_circuit() || !any_predicted_circuits(time(NULL)))
- inform_testing_reachability();
- }
- cpuworkers_rotate_keyinfo();
- if (dns_reset())
- return -1;
- } else {
- if (dns_reset())
- return -1;
- }
+ if (dns_reset())
+ return -1;
- if (options->PerConnBWRate != old_options->PerConnBWRate ||
- options->PerConnBWBurst != old_options->PerConnBWBurst)
- connection_or_update_token_buckets(get_connection_array(), options);
+ if (options_act_relay_bandwidth(old_options) < 0)
+ return -1;
if (options->BandwidthRate != old_options->BandwidthRate ||
- options->BandwidthBurst != old_options->BandwidthBurst ||
- options->RelayBandwidthRate != old_options->RelayBandwidthRate ||
- options->RelayBandwidthBurst != old_options->RelayBandwidthBurst)
+ options->BandwidthBurst != old_options->BandwidthBurst)
connection_bucket_adjust(options);
if (options->MainloopStats != old_options->MainloopStats) {
@@ -2201,121 +2113,44 @@ options_act,(const or_options_t *old_options))
}
}
+ /* 31851: These options are relay-only, but we need to disable them if we
+ * are in client mode. In 29211, we will disable all relay options in
+ * client mode. */
/* Only collect directory-request statistics on relays and bridges. */
options->DirReqStatistics = options->DirReqStatistics_option &&
server_mode(options);
options->HiddenServiceStatistics =
options->HiddenServiceStatistics_option && server_mode(options);
- if (options->CellStatistics || options->DirReqStatistics ||
- options->EntryStatistics || options->ExitPortStatistics ||
- options->ConnDirectionStatistics ||
- options->HiddenServiceStatistics ||
- options->BridgeAuthoritativeDir) {
- time_t now = time(NULL);
- int print_notice = 0;
+ /* Only collect other relay-only statistics on relays. */
+ if (!public_server_mode(options)) {
+ options->CellStatistics = 0;
+ options->EntryStatistics = 0;
+ options->ConnDirectionStatistics = 0;
+ options->ExitPortStatistics = 0;
+ }
- /* Only collect other relay-only statistics on relays. */
- if (!public_server_mode(options)) {
- options->CellStatistics = 0;
- options->EntryStatistics = 0;
- options->ConnDirectionStatistics = 0;
- options->ExitPortStatistics = 0;
- }
+ bool print_notice = 0;
+ if (options->BridgeAuthoritativeDir) {
+ time_t now = time(NULL);
- if ((!old_options || !old_options->CellStatistics) &&
- options->CellStatistics) {
- rep_hist_buffer_stats_init(now);
- print_notice = 1;
- }
- if ((!old_options || !old_options->DirReqStatistics) &&
- options->DirReqStatistics) {
- if (geoip_is_loaded(AF_INET)) {
- geoip_dirreq_stats_init(now);
- print_notice = 1;
- } else {
- /* disable statistics collection since we have no geoip file */
- options->DirReqStatistics = 0;
- if (options->ORPort_set)
- log_notice(LD_CONFIG, "Configured to measure directory request "
- "statistics, but no GeoIP database found. "
- "Please specify a GeoIP database using the "
- "GeoIPFile option.");
- }
- }
- if ((!old_options || !old_options->EntryStatistics) &&
- options->EntryStatistics && !should_record_bridge_info(options)) {
- /* If we get here, we've started recording bridge info when we didn't
- * do so before. Note that "should_record_bridge_info()" will
- * always be false at this point, because of the earlier block
- * that cleared EntryStatistics when public_server_mode() was false.
- * We're leaving it in as defensive programming. */
- if (geoip_is_loaded(AF_INET) || geoip_is_loaded(AF_INET6)) {
- geoip_entry_stats_init(now);
- print_notice = 1;
- } else {
- options->EntryStatistics = 0;
- log_notice(LD_CONFIG, "Configured to measure entry node "
- "statistics, but no GeoIP database found. "
- "Please specify a GeoIP database using the "
- "GeoIPFile option.");
- }
- }
- if ((!old_options || !old_options->ExitPortStatistics) &&
- options->ExitPortStatistics) {
- rep_hist_exit_stats_init(now);
- print_notice = 1;
- }
- if ((!old_options || !old_options->ConnDirectionStatistics) &&
- options->ConnDirectionStatistics) {
- rep_hist_conn_stats_init(now);
- }
- if ((!old_options || !old_options->HiddenServiceStatistics) &&
- options->HiddenServiceStatistics) {
- log_info(LD_CONFIG, "Configured to measure hidden service statistics.");
- rep_hist_hs_stats_init(now);
- }
if ((!old_options || !old_options->BridgeAuthoritativeDir) &&
options->BridgeAuthoritativeDir) {
rep_hist_desc_stats_init(now);
print_notice = 1;
}
- if (print_notice)
- log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
- "the *-stats files that will first be written to the "
- "data directory in 24 hours from now.");
- }
-
- /* If we used to have statistics enabled but we just disabled them,
- stop gathering them. */
- if (old_options && old_options->CellStatistics &&
- !options->CellStatistics)
- rep_hist_buffer_stats_term();
- if (old_options && old_options->DirReqStatistics &&
- !options->DirReqStatistics)
- geoip_dirreq_stats_term();
- if (old_options && old_options->EntryStatistics &&
- !options->EntryStatistics)
- geoip_entry_stats_term();
- if (old_options && old_options->HiddenServiceStatistics &&
- !options->HiddenServiceStatistics)
- rep_hist_hs_stats_term();
- if (old_options && old_options->ExitPortStatistics &&
- !options->ExitPortStatistics)
- rep_hist_exit_stats_term();
- if (old_options && old_options->ConnDirectionStatistics &&
- !options->ConnDirectionStatistics)
- rep_hist_conn_stats_term();
+
if (old_options && old_options->BridgeAuthoritativeDir &&
!options->BridgeAuthoritativeDir)
rep_hist_desc_stats_term();
- /* Since our options changed, we might need to regenerate and upload our
- * server descriptor.
- */
- if (!old_options ||
- options_transition_affects_descriptor(old_options, options))
- mark_my_descriptor_dirty("config change");
+ if (options_act_relay_stats(old_options, &print_notice) < 0)
+ return -1;
+ if (print_notice)
+ options_act_relay_stats_msg();
+
+ if (options_act_relay_desc(old_options) < 0)
+ return -1;
if (options_act_dirauth(old_options) < 0)
return -1;
@@ -2335,29 +2170,10 @@ options_act,(const or_options_t *old_options))
}
}
- /* DoS mitigation subsystem only applies to public relay. */
- if (public_server_mode(options)) {
- /* If we are configured as a relay, initialize the subsystem. Even on HUP,
- * this is safe to call as it will load data from the current options
- * or/and the consensus. */
- dos_init();
- } else if (old_options && public_server_mode(old_options)) {
- /* Going from relay to non relay, clean it up. */
- dos_free_all();
- }
-
- /* Load the webpage we're going to serve every time someone asks for '/' on
- our DirPort. */
- tor_free(global_dirfrontpagecontents);
- if (options->DirPortFrontPage) {
- global_dirfrontpagecontents =
- read_file_to_str(options->DirPortFrontPage, 0, NULL);
- if (!global_dirfrontpagecontents) {
- log_warn(LD_CONFIG,
- "DirPortFrontPage file '%s' not found. Continuing anyway.",
- options->DirPortFrontPage);
- }
- }
+ if (options_act_relay_dos(old_options) < 0)
+ return -1;
+ if (options_act_relay_dir(old_options) < 0)
+ return -1;
return 0;
}
@@ -3373,7 +3189,6 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
/* need to check for relative paths after we populate
* options->DataDirectory (just above). */
- /* 31851: some paths are unused in client mode */
if (warn_about_relative_paths(options) && options->RunAsDaemon) {
REJECT("You have specified at least one relative path (see above) "
"with the RunAsDaemon option. RunAsDaemon is not compatible "
@@ -4303,71 +4118,6 @@ options_check_transition_cb(const void *old_,
return 0;
}
-/** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
- * will require us to rotate the CPU and DNS workers; else return 0. */
-static int
-options_transition_affects_workers(const or_options_t *old_options,
- const or_options_t *new_options)
-{
- YES_IF_CHANGED_STRING(DataDirectory);
- YES_IF_CHANGED_INT(NumCPUs);
- YES_IF_CHANGED_LINELIST(ORPort_lines);
- YES_IF_CHANGED_BOOL(ServerDNSSearchDomains);
- YES_IF_CHANGED_BOOL(SafeLogging_);
- YES_IF_CHANGED_BOOL(ClientOnly);
- YES_IF_CHANGED_BOOL(LogMessageDomains);
- YES_IF_CHANGED_LINELIST(Logs);
-
- if (server_mode(old_options) != server_mode(new_options) ||
- public_server_mode(old_options) != public_server_mode(new_options) ||
- dir_server_mode(old_options) != dir_server_mode(new_options))
- return 1;
-
- /* Nothing that changed matters. */
- return 0;
-}
-
-/** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
- * will require us to generate a new descriptor; else return 0. */
-static int
-options_transition_affects_descriptor(const or_options_t *old_options,
- const or_options_t *new_options)
-{
- /* XXX We can be smarter here. If your DirPort isn't being
- * published and you just turned it off, no need to republish. Etc. */
-
- YES_IF_CHANGED_STRING(DataDirectory);
- YES_IF_CHANGED_STRING(Nickname);
- YES_IF_CHANGED_STRING(Address);
- YES_IF_CHANGED_LINELIST(ExitPolicy);
- YES_IF_CHANGED_BOOL(ExitRelay);
- YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate);
- YES_IF_CHANGED_BOOL(ExitPolicyRejectLocalInterfaces);
- YES_IF_CHANGED_BOOL(IPv6Exit);
- YES_IF_CHANGED_LINELIST(ORPort_lines);
- YES_IF_CHANGED_LINELIST(DirPort_lines);
- YES_IF_CHANGED_LINELIST(DirPort_lines);
- YES_IF_CHANGED_BOOL(ClientOnly);
- YES_IF_CHANGED_BOOL(DisableNetwork);
- YES_IF_CHANGED_BOOL(PublishServerDescriptor_);
- YES_IF_CHANGED_STRING(ContactInfo);
- YES_IF_CHANGED_STRING(BridgeDistribution);
- YES_IF_CHANGED_LINELIST(MyFamily);
- YES_IF_CHANGED_STRING(AccountingStart);
- YES_IF_CHANGED_INT(AccountingMax);
- YES_IF_CHANGED_INT(AccountingRule);
- YES_IF_CHANGED_BOOL(DirCache);
- YES_IF_CHANGED_BOOL(AssumeReachable);
-
- if (get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
- get_effective_bwburst(old_options) !=
- get_effective_bwburst(new_options) ||
- public_server_mode(old_options) != public_server_mode(new_options))
- return 1;
-
- return 0;
-}
-
#ifdef _WIN32
/** Return the directory on windows where we expect to find our application
* data. */
diff --git a/src/app/config/config.h b/src/app/config/config.h
index e49da6aa8..12dd6e1ba 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -31,7 +31,6 @@
#define MAX_DEFAULT_MEMORY_QUEUE_SIZE (UINT64_C(2) << 30)
#endif
-MOCK_DECL(const char*, get_dirportfrontpage, (void));
MOCK_DECL(const or_options_t *, get_options, (void));
MOCK_DECL(or_options_t *, get_options_mutable, (void));
int set_options(or_options_t *new_val, char **msg);
diff --git a/src/app/main/shutdown.c b/src/app/main/shutdown.c
index 93d6351d1..cc07b921c 100644
--- a/src/app/main/shutdown.c
+++ b/src/app/main/shutdown.c
@@ -45,6 +45,7 @@
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/ext_orport.h"
+#include "feature/relay/relay_config.h"
#include "feature/rend/rendcache.h"
#include "feature/rend/rendclient.h"
#include "feature/stats/geoip_stats.h"
@@ -143,6 +144,7 @@ tor_free_all(int postfork)
if (!postfork) {
config_free_all();
+ relay_config_free_all();
or_state_free_all();
}
if (!postfork) {
diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c
index 795f1b8ed..c1dec2cfb 100644
--- a/src/feature/dircache/dircache.c
+++ b/src/feature/dircache/dircache.c
@@ -28,6 +28,7 @@
#include "feature/nodelist/authcert.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/routerlist.h"
+#include "feature/relay/relay_config.h"
#include "feature/relay/routermode.h"
#include "feature/rend/rendcache.h"
#include "feature/stats/geoip_stats.h"
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index 7f1f04665..ac00dbd14 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -14,8 +14,10 @@
#include "feature/relay/relay_config.h"
#include "lib/encoding/confline.h"
+#include "lib/confmgt/confmgt.h"
#include "lib/container/smartlist.h"
+#include "lib/geoip/geoip.h"
#include "lib/meminfo/meminfo.h"
#include "lib/osinfo/uname.h"
#include "lib/process/setuid.h"
@@ -25,14 +27,27 @@
#include "app/config/config.h"
#include "core/mainloop/connection.h"
+#include "core/mainloop/cpuworker.h"
+#include "core/mainloop/mainloop.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/connection_or.h"
#include "core/or/port_cfg_st.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/nickname.h"
+#include "feature/stats/geoip_stats.h"
+#include "feature/stats/predict_ports.h"
+#include "feature/stats/rephist.h"
+#include "feature/dirauth/authmode.h"
+
+#include "feature/dircache/consdiffmgr.h"
#include "feature/relay/dns.h"
#include "feature/relay/routermode.h"
+/** Contents of most recently read DirPortFrontPage file. */
+static char *global_dirfrontpagecontents = NULL;
+
/* Copied from config.c, we will refactor later in 29211. */
#define REJECT(arg) \
STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
@@ -44,6 +59,58 @@
STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
#endif /* defined(__GNUC__) && __GNUC__ <= 3 */
+/* Used in the various options_transition_affects* functions. */
+#define YES_IF_CHANGED_BOOL(opt) \
+ if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1;
+#define YES_IF_CHANGED_INT(opt) \
+ if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
+#define YES_IF_CHANGED_STRING(opt) \
+ if (!CFG_EQ_STRING(old_options, new_options, opt)) return 1;
+#define YES_IF_CHANGED_LINELIST(opt) \
+ if (!CFG_EQ_LINELIST(old_options, new_options, opt)) return 1;
+
+/** Return the contents of our frontpage string, or NULL if not configured. */
+MOCK_IMPL(const char*,
+get_dirportfrontpage, (void))
+{
+ return global_dirfrontpagecontents;
+}
+
+/** Release all memory and resources held by global relay configuration
+ * structures.
+ */
+void
+relay_config_free_all(void)
+{
+ tor_free(global_dirfrontpagecontents);
+}
+
+/** Return the bandwidthrate that we are going to report to the authorities
+ * based on the config options. */
+uint32_t
+get_effective_bwrate(const or_options_t *options)
+{
+ uint64_t bw = options->BandwidthRate;
+ if (bw > options->MaxAdvertisedBandwidth)
+ bw = options->MaxAdvertisedBandwidth;
+ if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
+ bw = options->RelayBandwidthRate;
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
+}
+
+/** Return the bandwidthburst that we are going to report to the authorities
+ * based on the config options. */
+uint32_t
+get_effective_bwburst(const or_options_t *options)
+{
+ uint64_t bw = options->BandwidthBurst;
+ if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
+ bw = options->RelayBandwidthBurst;
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
+}
+
/** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal
* consistency and warn as appropriate. On Unix-based OSes, set
* *<b>n_low_ports_out</b> to the number of sub-1024 ports we will be
@@ -595,32 +662,6 @@ options_validate_relay_bandwidth(const or_options_t *old_options,
return 0;
}
-/** Return the bandwidthrate that we are going to report to the authorities
- * based on the config options. */
-uint32_t
-get_effective_bwrate(const or_options_t *options)
-{
- uint64_t bw = options->BandwidthRate;
- if (bw > options->MaxAdvertisedBandwidth)
- bw = options->MaxAdvertisedBandwidth;
- if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
- bw = options->RelayBandwidthRate;
- /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
- return (uint32_t)bw;
-}
-
-/** Return the bandwidthburst that we are going to report to the authorities
- * based on the config options. */
-uint32_t
-get_effective_bwburst(const or_options_t *options)
-{
- uint64_t bw = options->BandwidthBurst;
- if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
- bw = options->RelayBandwidthBurst;
- /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
- return (uint32_t)bw;
-}
-
/**
* Legacy validation/normalization function for the relay bandwidth accounting
* options. Uses old_options as the previous options.
@@ -916,3 +957,448 @@ options_validate_relay_testing(const or_options_t *old_options,
return 0;
}
+
+/** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
+ * will require us to rotate the CPU and DNS workers; else return 0. */
+static int
+options_transition_affects_workers(const or_options_t *old_options,
+ const or_options_t *new_options)
+{
+ YES_IF_CHANGED_STRING(DataDirectory);
+ YES_IF_CHANGED_INT(NumCPUs);
+ YES_IF_CHANGED_LINELIST(ORPort_lines);
+ YES_IF_CHANGED_BOOL(ServerDNSSearchDomains);
+ YES_IF_CHANGED_BOOL(SafeLogging_);
+ YES_IF_CHANGED_BOOL(ClientOnly);
+ YES_IF_CHANGED_BOOL(LogMessageDomains);
+ YES_IF_CHANGED_LINELIST(Logs);
+
+ if (server_mode(old_options) != server_mode(new_options) ||
+ public_server_mode(old_options) != public_server_mode(new_options) ||
+ dir_server_mode(old_options) != dir_server_mode(new_options))
+ return 1;
+
+ /* Nothing that changed matters. */
+ return 0;
+}
+
+/** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
+ * will require us to generate a new descriptor; else return 0. */
+static int
+options_transition_affects_descriptor(const or_options_t *old_options,
+ const or_options_t *new_options)
+{
+ /* XXX We can be smarter here. If your DirPort isn't being
+ * published and you just turned it off, no need to republish. Etc. */
+
+ YES_IF_CHANGED_STRING(DataDirectory);
+ YES_IF_CHANGED_STRING(Nickname);
+ YES_IF_CHANGED_STRING(Address);
+ YES_IF_CHANGED_LINELIST(ExitPolicy);
+ YES_IF_CHANGED_BOOL(ExitRelay);
+ YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate);
+ YES_IF_CHANGED_BOOL(ExitPolicyRejectLocalInterfaces);
+ YES_IF_CHANGED_BOOL(IPv6Exit);
+ YES_IF_CHANGED_LINELIST(ORPort_lines);
+ YES_IF_CHANGED_LINELIST(DirPort_lines);
+ YES_IF_CHANGED_LINELIST(DirPort_lines);
+ YES_IF_CHANGED_BOOL(ClientOnly);
+ YES_IF_CHANGED_BOOL(DisableNetwork);
+ YES_IF_CHANGED_BOOL(PublishServerDescriptor_);
+ YES_IF_CHANGED_STRING(ContactInfo);
+ YES_IF_CHANGED_STRING(BridgeDistribution);
+ YES_IF_CHANGED_LINELIST(MyFamily);
+ YES_IF_CHANGED_STRING(AccountingStart);
+ YES_IF_CHANGED_INT(AccountingMax);
+ YES_IF_CHANGED_INT(AccountingRule);
+ YES_IF_CHANGED_BOOL(DirCache);
+ YES_IF_CHANGED_BOOL(AssumeReachable);
+
+ if (get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
+ get_effective_bwburst(old_options) !=
+ get_effective_bwburst(new_options) ||
+ public_server_mode(old_options) != public_server_mode(new_options))
+ return 1;
+
+ return 0;
+}
+
+/** Fetch the active option list, and take relay actions based on it. All of
+ * the things we do should survive being done repeatedly. If present,
+ * <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay(const or_options_t *old_options)
+{
+ const or_options_t *options = get_options();
+
+ const int transition_affects_workers =
+ old_options && options_transition_affects_workers(old_options, options);
+
+ /* We want to reinit keys as needed before we do much of anything else:
+ keys are important, and other things can depend on them. */
+ if (transition_affects_workers ||
+ (options->V3AuthoritativeDir && (!old_options ||
+ !old_options->V3AuthoritativeDir))) {
+ if (init_keys() < 0) {
+ log_warn(LD_BUG,"Error initializing keys; exiting");
+ return -1;
+ }
+ }
+
+ if (server_mode(options)) {
+ static int cdm_initialized = 0;
+ if (cdm_initialized == 0) {
+ cdm_initialized = 1;
+ consdiffmgr_configure(NULL);
+ consdiffmgr_validate();
+ }
+ }
+
+ /* Check for transitions that need action. */
+ if (old_options) {
+ if (transition_affects_workers) {
+ log_info(LD_GENERAL,
+ "Worker-related options changed. Rotating workers.");
+ const int server_mode_turned_on =
+ server_mode(options) && !server_mode(old_options);
+ const int dir_server_mode_turned_on =
+ dir_server_mode(options) && !dir_server_mode(old_options);
+
+ if (server_mode_turned_on || dir_server_mode_turned_on) {
+ cpu_init();
+ }
+
+ if (server_mode_turned_on) {
+ ip_address_changed(0);
+ if (have_completed_a_circuit() || !any_predicted_circuits(time(NULL)))
+ inform_testing_reachability();
+ }
+ cpuworkers_rotate_keyinfo();
+ }
+ }
+
+ return 0;
+}
+
+/** Fetch the active option list, and take relay accounting actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_accounting(const or_options_t *old_options)
+{
+ (void)old_options;
+
+ const or_options_t *options = get_options();
+
+ /* Set up accounting */
+ if (accounting_parse_options(options, 0)<0) {
+ // LCOV_EXCL_START
+ log_warn(LD_BUG,"Error in previously validated accounting options");
+ return -1;
+ // LCOV_EXCL_STOP
+ }
+ if (accounting_is_enabled(options))
+ configure_accounting(time(NULL));
+
+ return 0;
+}
+
+/** Fetch the active option list, and take relay bandwidth actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_bandwidth(const or_options_t *old_options)
+{
+ const or_options_t *options = get_options();
+
+ /* Check for transitions that need action. */
+ if (old_options) {
+ if (options->PerConnBWRate != old_options->PerConnBWRate ||
+ options->PerConnBWBurst != old_options->PerConnBWBurst)
+ connection_or_update_token_buckets(get_connection_array(), options);
+
+ if (options->RelayBandwidthRate != old_options->RelayBandwidthRate ||
+ options->RelayBandwidthBurst != old_options->RelayBandwidthBurst)
+ connection_bucket_adjust(options);
+ }
+
+ return 0;
+}
+
+/** Fetch the active option list, and take bridge statistics actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_bridge_stats(const or_options_t *old_options)
+{
+ const or_options_t *options = get_options();
+
+/* How long should we delay counting bridge stats after becoming a bridge?
+ * We use this so we don't count clients who used our bridge thinking it is
+ * a relay. If you change this, don't forget to change the log message
+ * below. It's 4 hours (the time it takes to stop being used by clients)
+ * plus some extra time for clock skew. */
+#define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
+
+ /* Check for transitions that need action. */
+ if (old_options) {
+ if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
+ int was_relay = 0;
+ if (options->BridgeRelay) {
+ time_t int_start = time(NULL);
+ if (config_lines_eq(old_options->ORPort_lines,options->ORPort_lines)) {
+ int_start += RELAY_BRIDGE_STATS_DELAY;
+ was_relay = 1;
+ }
+ geoip_bridge_stats_init(int_start);
+ log_info(LD_CONFIG, "We are acting as a bridge now. Starting new "
+ "GeoIP stats interval%s.", was_relay ? " in 6 "
+ "hours from now" : "");
+ } else {
+ geoip_bridge_stats_term();
+ log_info(LD_GENERAL, "We are no longer acting as a bridge. "
+ "Forgetting GeoIP stats.");
+ }
+ }
+ }
+
+ return 0;
+}
+
+/** Fetch the active option list, and take relay statistics actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Sets <b>*print_notice_out</b> if we enabled stats, and need to print
+ * a stats log using options_act_relay_stats_msg().
+ *
+ * If loading the GeoIP file failed, sets DirReqStatistics and
+ * EntryStatistics to 0. This breaks the normalization/act ordering
+ * introduced in 29211.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_stats(const or_options_t *old_options,
+ bool *print_notice_out)
+{
+ if (BUG(!print_notice_out))
+ return -1;
+
+ or_options_t *options = get_options_mutable();
+
+ if (options->CellStatistics || options->DirReqStatistics ||
+ options->EntryStatistics || options->ExitPortStatistics ||
+ options->ConnDirectionStatistics ||
+ options->HiddenServiceStatistics) {
+ time_t now = time(NULL);
+ int print_notice = 0;
+
+ if ((!old_options || !old_options->CellStatistics) &&
+ options->CellStatistics) {
+ rep_hist_buffer_stats_init(now);
+ print_notice = 1;
+ }
+ if ((!old_options || !old_options->DirReqStatistics) &&
+ options->DirReqStatistics) {
+ if (geoip_is_loaded(AF_INET)) {
+ geoip_dirreq_stats_init(now);
+ print_notice = 1;
+ } else {
+ /* disable statistics collection since we have no geoip file */
+ /* 29211: refactor to avoid the normalisation/act inversion */
+ options->DirReqStatistics = 0;
+ if (options->ORPort_set)
+ log_notice(LD_CONFIG, "Configured to measure directory request "
+ "statistics, but no GeoIP database found. "
+ "Please specify a GeoIP database using the "
+ "GeoIPFile option.");
+ }
+ }
+ if ((!old_options || !old_options->EntryStatistics) &&
+ options->EntryStatistics && !should_record_bridge_info(options)) {
+ /* If we get here, we've started recording bridge info when we didn't
+ * do so before. Note that "should_record_bridge_info()" will
+ * always be false at this point, because of the earlier block
+ * that cleared EntryStatistics when public_server_mode() was false.
+ * We're leaving it in as defensive programming. */
+ if (geoip_is_loaded(AF_INET) || geoip_is_loaded(AF_INET6)) {
+ geoip_entry_stats_init(now);
+ print_notice = 1;
+ } else {
+ options->EntryStatistics = 0;
+ log_notice(LD_CONFIG, "Configured to measure entry node "
+ "statistics, but no GeoIP database found. "
+ "Please specify a GeoIP database using the "
+ "GeoIPFile option.");
+ }
+ }
+ if ((!old_options || !old_options->ExitPortStatistics) &&
+ options->ExitPortStatistics) {
+ rep_hist_exit_stats_init(now);
+ print_notice = 1;
+ }
+ if ((!old_options || !old_options->ConnDirectionStatistics) &&
+ options->ConnDirectionStatistics) {
+ rep_hist_conn_stats_init(now);
+ }
+ if ((!old_options || !old_options->HiddenServiceStatistics) &&
+ options->HiddenServiceStatistics) {
+ log_info(LD_CONFIG, "Configured to measure hidden service statistics.");
+ rep_hist_hs_stats_init(now);
+ }
+ if (print_notice)
+ *print_notice_out = 1;
+ }
+
+ /* If we used to have statistics enabled but we just disabled them,
+ stop gathering them. */
+ if (old_options && old_options->CellStatistics &&
+ !options->CellStatistics)
+ rep_hist_buffer_stats_term();
+ if (old_options && old_options->DirReqStatistics &&
+ !options->DirReqStatistics)
+ geoip_dirreq_stats_term();
+ if (old_options && old_options->EntryStatistics &&
+ !options->EntryStatistics)
+ geoip_entry_stats_term();
+ if (old_options && old_options->HiddenServiceStatistics &&
+ !options->HiddenServiceStatistics)
+ rep_hist_hs_stats_term();
+ if (old_options && old_options->ExitPortStatistics &&
+ !options->ExitPortStatistics)
+ rep_hist_exit_stats_term();
+ if (old_options && old_options->ConnDirectionStatistics &&
+ !options->ConnDirectionStatistics)
+ rep_hist_conn_stats_term();
+
+ return 0;
+}
+
+/** Print a notice about relay/dirauth stats being enabled. */
+void
+options_act_relay_stats_msg(void)
+{
+ log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
+ "the *-stats files that will first be written to the "
+ "data directory in 24 hours from now.");
+}
+
+/** Fetch the active option list, and take relay descriptor actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_desc(const or_options_t *old_options)
+{
+ const or_options_t *options = get_options();
+
+ /* Since our options changed, we might need to regenerate and upload our
+ * server descriptor.
+ */
+ if (!old_options ||
+ options_transition_affects_descriptor(old_options, options))
+ mark_my_descriptor_dirty("config change");
+
+ return 0;
+}
+
+/** Fetch the active option list, and take relay DoS actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_dos(const or_options_t *old_options)
+{
+ const or_options_t *options = get_options();
+
+ /* DoS mitigation subsystem only applies to public relay. */
+ if (public_server_mode(options)) {
+ /* If we are configured as a relay, initialize the subsystem. Even on HUP,
+ * this is safe to call as it will load data from the current options
+ * or/and the consensus. */
+ dos_init();
+ } else if (old_options && public_server_mode(old_options)) {
+ /* Going from relay to non relay, clean it up. */
+ dos_free_all();
+ }
+
+ return 0;
+}
+
+/** Fetch the active option list, and take dirport actions based on
+ * it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_relay_dir(const or_options_t *old_options)
+{
+ (void)old_options;
+
+ const or_options_t *options = get_options();
+
+ /* Load the webpage we're going to serve every time someone asks for '/' on
+ our DirPort. */
+ tor_free(global_dirfrontpagecontents);
+ if (options->DirPortFrontPage) {
+ global_dirfrontpagecontents =
+ read_file_to_str(options->DirPortFrontPage, 0, NULL);
+ if (!global_dirfrontpagecontents) {
+ log_warn(LD_CONFIG,
+ "DirPortFrontPage file '%s' not found. Continuing anyway.",
+ options->DirPortFrontPage);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h
index 83ff3a2a8..3a9ea418b 100644
--- a/src/feature/relay/relay_config.h
+++ b/src/feature/relay/relay_config.h
@@ -18,6 +18,12 @@
typedef struct or_options_t or_options_t;
typedef struct smartlist_t smartlist_t;
+MOCK_DECL(const char*, get_dirportfrontpage, (void));
+void relay_config_free_all(void);
+
+uint32_t get_effective_bwrate(const or_options_t *options);
+uint32_t get_effective_bwburst(const or_options_t *options);
+
int parse_ports_relay(or_options_t *options,
char **msg,
smartlist_t *ports_out,
@@ -44,8 +50,6 @@ int options_validate_relay_padding(const or_options_t *old_options,
int options_validate_relay_bandwidth(const or_options_t *old_options,
or_options_t *options,
char **msg);
-uint32_t get_effective_bwrate(const or_options_t *options);
-uint32_t get_effective_bwburst(const or_options_t *options);
int options_validate_relay_accounting(const or_options_t *old_options,
or_options_t *options,
@@ -59,6 +63,18 @@ int options_validate_relay_testing(const or_options_t *old_options,
or_options_t *options,
char **msg);
+int options_act_relay(const or_options_t *old_options);
+int options_act_relay_accounting(const or_options_t *old_options);
+int options_act_relay_bandwidth(const or_options_t *old_options);
+int options_act_bridge_stats(const or_options_t *old_options);
+int options_act_relay_stats(const or_options_t *old_options,
+ bool *print_notice_out);
+void options_act_relay_stats_msg(void);
+
+int options_act_relay_desc(const or_options_t *old_options);
+int options_act_relay_dos(const or_options_t *old_options);
+int options_act_relay_dir(const or_options_t *old_options);
+
#ifdef RELAY_CONFIG_PRIVATE
STATIC int check_bridge_distribution_setting(const char *bd);
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index edfd0c74e..43b8324fc 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -20,6 +20,7 @@
#include "lib/compress/compress.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendcache.h"
+#include "feature/relay/relay_config.h"
#include "feature/relay/router.h"
#include "feature/nodelist/authcert.h"
#include "feature/nodelist/dirlist.h"
1
0

[tor/master] relay/config: Remove direct references to dirauth options
by teor@torproject.org 05 Nov '19
by teor@torproject.org 05 Nov '19
05 Nov '19
commit 23faa03ffc28e8d1132370e861756e84d659be5e
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 15:43:30 2019 +1000
relay/config: Remove direct references to dirauth options
All *AuthoritativeDir* options are now accessed via the authmode
functions in relay_config.c, relay/transport_config.c, and config.c.
Part of 32213.
---
src/feature/relay/relay_config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index ac00dbd14..7ef2a1513 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -1044,8 +1044,8 @@ options_act_relay(const or_options_t *old_options)
/* We want to reinit keys as needed before we do much of anything else:
keys are important, and other things can depend on them. */
if (transition_affects_workers ||
- (options->V3AuthoritativeDir && (!old_options ||
- !old_options->V3AuthoritativeDir))) {
+ (authdir_mode_v3(options) && (!old_options ||
+ !authdir_mode_v3(old_options)))) {
if (init_keys() < 0) {
log_warn(LD_BUG,"Error initializing keys; exiting");
return -1;
1
0
commit fd18d512706cbaef2d9f10071fb684c64c3db781
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 22:32:24 2019 +1000
dirauth: Refactor some code and tests
Minor simplification and refactoring.
Make the dirauth tests focus on testing the intention of the code,
rather than option processing order.
Part of 32213.
---
src/feature/dirauth/dirauth_config.c | 161 ++++++------
src/feature/dirauth/dirauth_config.h | 4 -
src/test/test_options.c | 475 +++++++++++++++++++++++------------
3 files changed, 401 insertions(+), 239 deletions(-)
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 99e3a45fc..a98ece814 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -61,70 +61,69 @@ options_validate_dirauth_mode(const or_options_t *old_options,
if (BUG(!msg))
return -1;
- if (options->AuthoritativeDir) {
- /* confirm that our address isn't broken, so we can complain now */
- uint32_t tmp;
- if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0)
- REJECT("Failed to resolve/guess local address. See logs for details.");
-
- if (!options->ContactInfo && !options->TestingTorNetwork)
- REJECT("Authoritative directory servers must set ContactInfo");
- if (!options->RecommendedClientVersions)
- options->RecommendedClientVersions =
- config_lines_dup(options->RecommendedVersions);
- if (!options->RecommendedServerVersions)
- options->RecommendedServerVersions =
- config_lines_dup(options->RecommendedVersions);
- if (options->VersioningAuthoritativeDir &&
- (!options->RecommendedClientVersions ||
- !options->RecommendedServerVersions))
- REJECT("Versioning authoritative dir servers must set "
- "Recommended*Versions.");
-
- char *t;
- /* Call these functions to produce warnings only. */
- t = format_recommended_version_list(options->RecommendedClientVersions, 1);
- tor_free(t);
- t = format_recommended_version_list(options->RecommendedServerVersions, 1);
- tor_free(t);
-
- if (options->UseEntryGuards) {
- log_info(LD_CONFIG, "Authoritative directory servers can't set "
- "UseEntryGuards. Disabling.");
- options->UseEntryGuards = 0;
- }
- if (!options->DownloadExtraInfo && authdir_mode_v3(options)) {
- log_info(LD_CONFIG, "Authoritative directories always try to download "
- "extra-info documents. Setting DownloadExtraInfo.");
- options->DownloadExtraInfo = 1;
- }
- if (!(options->BridgeAuthoritativeDir ||
- options->V3AuthoritativeDir))
- REJECT("AuthoritativeDir is set, but none of "
- "(Bridge/V3)AuthoritativeDir is set.");
-
- /* If we have a v3bandwidthsfile and it's broken, complain on startup */
- if (options->V3BandwidthsFile && !old_options) {
- dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL, NULL,
- NULL);
- }
- /* same for guardfraction file */
- if (options->GuardfractionFile && !old_options) {
- dirserv_read_guardfraction_file(options->GuardfractionFile, NULL);
- }
+ if (!authdir_mode(options))
+ return 0;
- if (!options->DirPort_set)
- REJECT("Running as authoritative directory, but no DirPort set.");
+ /* confirm that our address isn't broken, so we can complain now */
+ uint32_t tmp;
+ if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0)
+ REJECT("Failed to resolve/guess local address. See logs for details.");
+
+ if (!options->ContactInfo && !options->TestingTorNetwork)
+ REJECT("Authoritative directory servers must set ContactInfo");
+ if (!options->RecommendedClientVersions)
+ options->RecommendedClientVersions =
+ config_lines_dup(options->RecommendedVersions);
+ if (!options->RecommendedServerVersions)
+ options->RecommendedServerVersions =
+ config_lines_dup(options->RecommendedVersions);
+ if (options->VersioningAuthoritativeDir &&
+ (!options->RecommendedClientVersions ||
+ !options->RecommendedServerVersions))
+ REJECT("Versioning authoritative dir servers must set "
+ "Recommended*Versions.");
+
+ char *t;
+ /* Call these functions to produce warnings only. */
+ t = format_recommended_version_list(options->RecommendedClientVersions, 1);
+ tor_free(t);
+ t = format_recommended_version_list(options->RecommendedServerVersions, 1);
+ tor_free(t);
+
+ if (options->UseEntryGuards) {
+ log_info(LD_CONFIG, "Authoritative directory servers can't set "
+ "UseEntryGuards. Disabling.");
+ options->UseEntryGuards = 0;
+ }
+ if (!options->DownloadExtraInfo && authdir_mode_v3(options)) {
+ log_info(LD_CONFIG, "Authoritative directories always try to download "
+ "extra-info documents. Setting DownloadExtraInfo.");
+ options->DownloadExtraInfo = 1;
+ }
+ if (!(options->BridgeAuthoritativeDir ||
+ options->V3AuthoritativeDir))
+ REJECT("AuthoritativeDir is set, but none of "
+ "(Bridge/V3)AuthoritativeDir is set.");
+
+ /* If we have a v3bandwidthsfile and it's broken, complain on startup */
+ if (options->V3BandwidthsFile && !old_options) {
+ dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL, NULL,
+ NULL);
+ }
+ /* same for guardfraction file */
+ if (options->GuardfractionFile && !old_options) {
+ dirserv_read_guardfraction_file(options->GuardfractionFile, NULL);
+ }
- if (!options->ORPort_set)
- REJECT("Running as authoritative directory, but no ORPort set.");
+ if (!options->DirPort_set)
+ REJECT("Running as authoritative directory, but no DirPort set.");
- if (options->ClientOnly)
- REJECT("Running as authoritative directory, but ClientOnly also set.");
- }
+ if (!options->ORPort_set)
+ REJECT("Running as authoritative directory, but no ORPort set.");
+
+ if (options->ClientOnly)
+ REJECT("Running as authoritative directory, but ClientOnly also set.");
- /* 31851: the tests expect us to validate these options, even when we are
- * not in authority mode. */
if (options->MinUptimeHidServDirectoryV2 < 0) {
log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
"least 0 seconds. Changing to 0.");
@@ -154,8 +153,9 @@ options_validate_dirauth_bandwidth(const or_options_t *old_options,
if (BUG(!msg))
return -1;
- /* 31851: the tests expect us to validate these options, even when we are
- * not in authority mode. */
+ if (!authdir_mode(options))
+ return 0;
+
if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
"AuthDirFastGuarantee", msg) < 0)
return -1;
@@ -186,6 +186,9 @@ options_validate_dirauth_schedule(const or_options_t *old_options,
if (BUG(!msg))
return -1;
+ if (!authdir_mode_v3(options))
+ return 0;
+
if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
options->V3AuthVotingInterval/2) {
REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
@@ -224,7 +227,8 @@ options_validate_dirauth_schedule(const or_options_t *old_options,
if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
if (options->TestingTorNetwork) {
if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL_TESTING) {
- REJECT("V3AuthVotingInterval is insanely low.");
+ /* Unreachable, covered by earlier checks */
+ REJECT("V3AuthVotingInterval is insanely low."); /* LCOV_EXCL_LINE */
} else {
COMPLAIN("V3AuthVotingInterval is very low. "
"This may lead to failure to synchronise for a consensus.");
@@ -261,6 +265,18 @@ options_validate_dirauth_testing(const or_options_t *old_options,
if (BUG(!msg))
return -1;
+ if (!authdir_mode(options))
+ return 0;
+
+ if (options->TestingAuthDirTimeToLearnReachability < 0) {
+ REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
+ } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
+ COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
+ }
+
+ if (!authdir_mode_v3(options))
+ return 0;
+
if (options->TestingV3AuthInitialVotingInterval
< MIN_VOTE_INTERVAL_TESTING_INITIAL) {
REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
@@ -293,12 +309,6 @@ options_validate_dirauth_testing(const or_options_t *old_options,
REJECT("TestingV3AuthVotingStartOffset must be non-negative.");
}
- if (options->TestingAuthDirTimeToLearnReachability < 0) {
- REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
- } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
- COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
- }
-
return 0;
}
@@ -317,6 +327,7 @@ options_transition_affects_dirauth_timing(const or_options_t *old_options,
return 1;
if (! authdir_mode_v3(new_options))
return 0;
+
YES_IF_CHANGED_INT(V3AuthVotingInterval);
YES_IF_CHANGED_INT(V3AuthVoteDelay);
YES_IF_CHANGED_INT(V3AuthDistDelay);
@@ -374,6 +385,9 @@ options_act_dirauth_mtbf(const or_options_t *old_options)
const or_options_t *options = get_options();
int running_tor = options->command == CMD_RUN_TOR;
+ if (!authdir_mode(options))
+ return 0;
+
/* Load dirauth state */
if (running_tor) {
rep_hist_load_mtbf_data(time(NULL));
@@ -404,12 +418,11 @@ options_act_dirauth_stats(const or_options_t *old_options,
const or_options_t *options = get_options();
- if (options->BridgeAuthoritativeDir) {
+ if (authdir_mode_bridge(options)) {
time_t now = time(NULL);
int print_notice = 0;
- if ((!old_options || !old_options->BridgeAuthoritativeDir) &&
- options->BridgeAuthoritativeDir) {
+ if (!old_options || !authdir_mode_bridge(old_options)) {
rep_hist_desc_stats_init(now);
print_notice = 1;
}
@@ -419,8 +432,8 @@ options_act_dirauth_stats(const or_options_t *old_options,
/* If we used to have statistics enabled but we just disabled them,
stop gathering them. */
- if (old_options && old_options->BridgeAuthoritativeDir &&
- !options->BridgeAuthoritativeDir)
+ if (old_options && authdir_mode_bridge(old_options) &&
+ !authdir_mode_bridge(options))
rep_hist_desc_stats_term();
return 0;
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index 965472aa2..fbe4ec1a5 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -67,19 +67,15 @@ options_validate_dirauth_mode(const or_options_t *old_options,
#define options_validate_dirauth_bandwidth(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
-
#define options_validate_dirauth_schedule(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
-
#define options_validate_dirauth_testing(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
-
#define options_validate_dirauth_testing(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
#define options_act_dirauth(old_options) \
(((void)(old_options)),0)
-
#define options_act_dirauth_mtbf(old_options) \
(((void)(old_options)),0)
diff --git a/src/test/test_options.c b/src/test/test_options.c
index c1168a19b..8a85d4f54 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -9,6 +9,7 @@
#include "core/or/or.h"
#include "lib/confmgt/confmgt.h"
#include "app/config/config.h"
+#include "feature/dirauth/dirauth_config.h"
#include "feature/relay/relay_config.h"
#include "test/test.h"
#include "lib/geoip/geoip.h"
@@ -101,6 +102,50 @@ clear_log_messages(void)
options_init(opt); \
} while (0)
+#ifdef COCCI
+
+#define ENABLE_AUTHORITY_MIN ""
+#define ENABLE_AUTHORITY_V3_MIN ""
+#define ENABLE_AUTHORITY_BRIDGE_MIN ""
+#define AUTHORITY_OPT_REQ_ ""
+#define ENABLE_AUTHORITY ""
+#define ENABLE_AUTHORITY_V3 ""
+#define ENABLE_AUTHORITY_BRIDGE ""
+
+#else
+
+#define ENABLE_AUTHORITY_MIN \
+ "AuthoritativeDirectory 1\n"
+
+#define ENABLE_AUTHORITY_V3_MIN \
+ ENABLE_AUTHORITY_MIN \
+ "V3AuthoritativeDir 1\n"
+
+#define ENABLE_AUTHORITY_BRIDGE_MIN \
+ ENABLE_AUTHORITY_MIN \
+ "BridgeAuthoritativeDir 1\n"
+
+#define AUTHORITY_OPT_REQ_ \
+ "Address 192.0.2.111\n" \
+ "ContactInfo a(a)example.org\n" \
+ "DirPort 1025\n" \
+ "ORPort 1026\n"
+
+/* Not actually valid: requires v3 / bridge */
+#define ENABLE_AUTHORITY \
+ ENABLE_AUTHORITY_MIN \
+ AUTHORITY_OPT_REQ_
+
+#define ENABLE_AUTHORITY_V3 \
+ ENABLE_AUTHORITY_V3_MIN \
+ AUTHORITY_OPT_REQ_
+
+#define ENABLE_AUTHORITY_BRIDGE \
+ ENABLE_AUTHORITY_BRIDGE_MIN \
+ AUTHORITY_OPT_REQ_
+
+#endif
+
#define VALID_DIR_AUTH "DirAuthority dizum orport=443 v3ident=E8A9C45" \
"EDE6D711294FADF8E7951F4DE6CA56B58 194.109.206.212:80 7EA6 EAD6 FD83" \
" 083C 538F 4403 8BBF A077 587D D755\n"
@@ -712,7 +757,7 @@ test_options_validate__authdir(void *ignored)
char *msg;
setup_capture_of_logs(LOG_INFO);
options_test_data_t *tdata = get_options_test_data(
- "AuthoritativeDirectory 1\n"
+ ENABLE_AUTHORITY_V3_MIN
"Address this.should.not!exist!.example.org");
sandbox_disable_getaddrinfo_cache();
@@ -728,7 +773,7 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3_MIN
"Address 100.200.10.1");
mock_clean_saved_logs();
ret = options_validate(NULL, tdata->opt, &msg);
@@ -738,7 +783,7 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3_MIN
"Address 100.200.10.1\n");
mock_clean_saved_logs();
ret = options_validate(NULL, tdata->opt, &msg);
@@ -748,7 +793,7 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_MIN
"Address 100.200.10.1\n"
"TestingTorNetwork 1\n");
mock_clean_saved_logs();
@@ -759,9 +804,7 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY);
mock_clean_saved_logs();
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
@@ -770,10 +813,8 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "RecommendedVersions 1.2, 3.14\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "RecommendedVersions 1.2, 3.14\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "1.2, 3.14");
@@ -781,12 +822,10 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
"RecommendedVersions 1.2, 3.14\n"
"RecommendedClientVersions 25\n"
- "RecommendedServerVersions 4.18\n"
- "ContactInfo hello(a)hello.com\n");
+ "RecommendedServerVersions 4.18\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "25");
@@ -794,13 +833,11 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY
"VersioningAuthoritativeDirectory 1\n"
"RecommendedVersions 1.2, 3.14\n"
"RecommendedClientVersions 25\n"
- "RecommendedServerVersions 4.18\n"
- "ContactInfo hello(a)hello.com\n");
+ "RecommendedServerVersions 4.18\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
@@ -808,11 +845,9 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
"VersioningAuthoritativeDirectory 1\n"
- "RecommendedServerVersions 4.18\n"
- "ContactInfo hello(a)hello.com\n");
+ "RecommendedServerVersions 4.18\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set "
@@ -820,11 +855,9 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
"VersioningAuthoritativeDirectory 1\n"
- "RecommendedClientVersions 4.18\n"
- "ContactInfo hello(a)hello.com\n");
+ "RecommendedClientVersions 4.18\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set "
@@ -832,10 +865,8 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "UseEntryGuards 1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "UseEntryGuards 1\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
expect_log_msg("Authoritative directory servers "
@@ -844,10 +875,8 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "V3AuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "DownloadExtraInfo 0\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
expect_log_msg("Authoritative directories always try"
@@ -856,117 +885,110 @@ test_options_validate__authdir(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "DownloadExtraInfo 1\n"
- "V3AuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3BandwidthsFile non-existent-file\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
- expect_no_log_msg("Authoritative directories always try"
- " to download extra-info documents. Setting DownloadExtraInfo.\n");
- tt_int_op(tdata->opt->DownloadExtraInfo, OP_EQ, 1);
+ expect_log_msg("Can't open bandwidth file at configured location: "
+ "non-existent-file\n");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "GuardfractionFile non-existent-file\n");
mock_clean_saved_logs();
options_validate(NULL, tdata->opt, &msg);
- tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
- "AuthoritativeDir is set.");
+ expect_log_msg("Cannot open guardfraction file 'non-existent-file'. "
+ "Failing.\n");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3_MIN
"Address 100.200.10.1\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n"
- "V3BandwidthsFile non-existent-file\n");
+ "ORPort 2000\n"
+ "ContactInfo hello(a)hello.com\n");
mock_clean_saved_logs();
- options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ,
"Running as authoritative directory, but no DirPort set.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_BRIDGE_MIN
"Address 100.200.10.1\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n"
- "V3BandwidthsFile non-existent-file\n");
+ "ORPort 2000\n"
+ "ContactInfo hello(a)hello.com\n");
mock_clean_saved_logs();
- options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ,
"Running as authoritative directory, but no DirPort set.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3_MIN
"Address 100.200.10.1\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n"
- "GuardfractionFile non-existent-file\n");
+ "DirPort 999\n"
+ "ContactInfo hello(a)hello.com\n");
mock_clean_saved_logs();
- options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ,
- "Running as authoritative directory, but no DirPort set.");
+ "Running as authoritative directory, but no ORPort set.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_BRIDGE_MIN
"Address 100.200.10.1\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n"
- "GuardfractionFile non-existent-file\n");
+ "DirPort 999\n"
+ "ContactInfo hello(a)hello.com\n");
mock_clean_saved_logs();
- options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ,
- "Running as authoritative directory, but no DirPort set.");
+ "Running as authoritative directory, but no ORPort set.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "ClientOnly 1\n");
+ /* We have to call the dirauth-specific function, and fake port parsing,
+ * to hit this case */
+ tdata->opt->DirPort_set = 1;
+ tdata->opt->ORPort_set = 1;
mock_clean_saved_logs();
- ret = options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate_dirauth_mode(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ,
- "Running as authoritative directory, but no DirPort set.");
+ tt_str_op(msg, OP_EQ, "Running as authoritative directory, "
+ "but ClientOnly also set.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("AuthoritativeDirectory 1\n"
- "Address 100.200.10.1\n"
- "DirPort 999\n"
- "BridgeAuthoritativeDir 1\n"
- "ContactInfo hello(a)hello.com\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_BRIDGE
+ "ClientOnly 1\n");
+ /* We have to call the dirauth-specific function, and fake port parsing,
+ * to hit this case */
+ tdata->opt->DirPort_set = 1;
+ tdata->opt->ORPort_set = 1;
mock_clean_saved_logs();
- ret = options_validate(NULL, tdata->opt, &msg);
+ ret = options_validate_dirauth_mode(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ,
- "Running as authoritative directory, but no ORPort set.");
+ tt_str_op(msg, OP_EQ, "Running as authoritative directory, "
+ "but ClientOnly also set.");
tor_free(msg);
- // TODO: This case can't be reached, since clientonly is used to
- // check when parsing port lines as well.
- /* free_options_test_data(tdata); */
- /* tdata = get_options_test_data("AuthoritativeDirectory 1\n" */
- /* "Address 100.200.10.1\n" */
- /* "DirPort 999\n" */
- /* "ORPort 888\n" */
- /* "ClientOnly 1\n" */
- /* "BridgeAuthoritativeDir 1\n" */
- /* "ContactInfo hello(a)hello.com\n" ); */
- /* mock_clean_saved_logs(); */
- /* ret = options_validate(NULL, tdata->opt, */
- /* tdata->def_opt, 0, &msg); */
- /* tt_int_op(ret, OP_EQ, -1); */
- /* tt_str_op(msg, OP_EQ, "Running as authoritative directory, " */
- /* "but ClientOnly also set."); */
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3);
+ /* We have to set this value manually, because it won't parse */
+ tdata->opt->MinUptimeHidServDirectoryV2 = -1;
+ mock_clean_saved_logs();
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, 0);
+ expect_log_msg("MinUptimeHidServDirectoryV2 "
+ "option must be at least 0 seconds. Changing to 0.\n");
+ tt_int_op(tdata->opt->MinUptimeHidServDirectoryV2, OP_EQ, 0);
+ tor_free(msg);
done:
teardown_capture_of_logs();
@@ -2006,15 +2028,7 @@ test_options_validate__hidserv(void *ignored)
char *msg;
setup_capture_of_logs(LOG_WARN);
- options_test_data_t *tdata = get_options_test_data("");
-
- tdata->opt->MinUptimeHidServDirectoryV2 = -1;
- ret = options_validate(NULL, tdata->opt, &msg);
- tt_int_op(ret, OP_EQ, 0);
- expect_log_msg("MinUptimeHidServDirectoryV2 "
- "option must be at least 0 seconds. Changing to 0.\n");
- tt_int_op(tdata->opt->MinUptimeHidServDirectoryV2, OP_EQ, 0);
- tor_free(msg);
+ options_test_data_t *tdata = NULL;
free_options_test_data(tdata);
tdata = get_options_test_data("RendPostPeriod 1\n" );
@@ -2103,25 +2117,46 @@ test_options_validate__bandwidth(void *ignored)
char *msg;
options_test_data_t *tdata = NULL;
-#define ENSURE_BANDWIDTH_PARAM(p) \
- STMT_BEGIN \
+#define ENSURE_BANDWIDTH_PARAM(p, EXTRA_OPT_STR) \
+ STMT_BEGIN \
free_options_test_data(tdata); \
- tdata = get_options_test_data(#p " 3Gb\n"); \
- ret = options_validate(NULL, tdata->opt, &msg); \
+ tdata = get_options_test_data(EXTRA_OPT_STR \
+ #p " 3Gb\n"); \
+ ret = options_validate(NULL, tdata->opt, &msg); \
tt_int_op(ret, OP_EQ, -1); \
tt_mem_op(msg, OP_EQ, #p " (3221225471) must be at most 2147483647", 40); \
tor_free(msg); \
STMT_END
- ENSURE_BANDWIDTH_PARAM(BandwidthRate);
- ENSURE_BANDWIDTH_PARAM(BandwidthBurst);
- ENSURE_BANDWIDTH_PARAM(MaxAdvertisedBandwidth);
- ENSURE_BANDWIDTH_PARAM(RelayBandwidthRate);
- ENSURE_BANDWIDTH_PARAM(RelayBandwidthBurst);
- ENSURE_BANDWIDTH_PARAM(PerConnBWRate);
- ENSURE_BANDWIDTH_PARAM(PerConnBWBurst);
- ENSURE_BANDWIDTH_PARAM(AuthDirFastGuarantee);
- ENSURE_BANDWIDTH_PARAM(AuthDirGuardBWGuarantee);
+ ENSURE_BANDWIDTH_PARAM(BandwidthRate, "");
+ ENSURE_BANDWIDTH_PARAM(BandwidthBurst, "");
+
+ ENSURE_BANDWIDTH_PARAM(BandwidthRate, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(BandwidthBurst, ENABLE_AUTHORITY_V3);
+
+ ENSURE_BANDWIDTH_PARAM(BandwidthRate, ENABLE_AUTHORITY_BRIDGE);
+ ENSURE_BANDWIDTH_PARAM(BandwidthBurst, ENABLE_AUTHORITY_BRIDGE);
+
+ ENSURE_BANDWIDTH_PARAM(MaxAdvertisedBandwidth, "");
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthRate, "");
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthBurst, "");
+ ENSURE_BANDWIDTH_PARAM(PerConnBWRate, "");
+ ENSURE_BANDWIDTH_PARAM(PerConnBWBurst, "");
+
+ ENSURE_BANDWIDTH_PARAM(MaxAdvertisedBandwidth, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthRate, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthBurst, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(PerConnBWRate, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(PerConnBWBurst, ENABLE_AUTHORITY_V3);
+
+ ENSURE_BANDWIDTH_PARAM(MaxAdvertisedBandwidth, ENABLE_AUTHORITY_BRIDGE);
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthRate, ENABLE_AUTHORITY_BRIDGE);
+ ENSURE_BANDWIDTH_PARAM(RelayBandwidthBurst, ENABLE_AUTHORITY_BRIDGE);
+ ENSURE_BANDWIDTH_PARAM(PerConnBWRate, ENABLE_AUTHORITY_BRIDGE);
+ ENSURE_BANDWIDTH_PARAM(PerConnBWBurst, ENABLE_AUTHORITY_BRIDGE);
+
+ ENSURE_BANDWIDTH_PARAM(AuthDirFastGuarantee, ENABLE_AUTHORITY_V3);
+ ENSURE_BANDWIDTH_PARAM(AuthDirGuardBWGuarantee, ENABLE_AUTHORITY_V3);
free_options_test_data(tdata);
tdata = get_options_test_data("RelayBandwidthRate 1000\n");
@@ -3461,7 +3496,8 @@ test_options_validate__v3_auth(void *ignored)
setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 1000\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 1000\n"
"V3AuthDistDelay 1000\n"
"V3AuthVotingInterval 1000\n"
);
@@ -3473,14 +3509,16 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 1\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 1\n");
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ, "V3AuthVoteDelay is way too low.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 1\n"
"TestingTorNetwork 1\n");
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
@@ -3492,14 +3530,16 @@ test_options_validate__v3_auth(void *ignored)
// since they are the same
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthDistDelay 1\n");
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthDistDelay 1\n");
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
tt_str_op(msg, OP_EQ, "V3AuthDistDelay is way too low.");
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthDistDelay 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthDistDelay 1\n"
"TestingTorNetwork 1\n"
);
ret = options_validate(NULL, tdata->opt, &msg);
@@ -3507,12 +3547,13 @@ test_options_validate__v3_auth(void *ignored)
tt_str_op(msg, OP_EQ, "V3AuthDistDelay is way too low.");
tor_free(msg);
- // TODO: we can't reach the case of v3authdistdelay lower than
+ // We can't reach the case of v3authdistdelay lower than
// MIN_DIST_SECONDS but not lower than MIN_DIST_SECONDS_TESTING,
// since they are the same
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthNIntervalsValid 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthNIntervalsValid 1\n"
);
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, -1);
@@ -3520,7 +3561,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 49\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 49\n"
"V3AuthDistDelay 49\n"
"V3AuthVotingInterval 200\n"
);
@@ -3530,7 +3572,49 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 49\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "V3AuthVoteDelay 49\n"
+ "V3AuthDistDelay 49\n"
+ "V3AuthVotingInterval 200\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_ptr_op(msg, OP_EQ, NULL);
+ tor_free(msg);
+
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "V3AuthVoteDelay 2\n"
+ "V3AuthDistDelay 2\n"
+ "V3AuthVotingInterval 9\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_str_op(msg, OP_EQ,
+ "V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
+ "V3AuthVotingInterval");
+ tor_free(msg);
+
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "V3AuthVoteDelay 2\n"
+ "V3AuthDistDelay 2\n"
+ "V3AuthVotingInterval 10\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_ptr_op(msg, OP_EQ, NULL);
+ tor_free(msg);
+
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 49\n"
"V3AuthDistDelay 49\n"
"V3AuthVotingInterval 200000\n"
);
@@ -3540,7 +3624,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 49\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 49\n"
"V3AuthDistDelay 49\n"
"V3AuthVotingInterval 1441\n"
);
@@ -3552,7 +3637,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 49\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 49\n"
"V3AuthDistDelay 49\n"
"V3AuthVotingInterval 1440\n"
);
@@ -3564,7 +3650,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("V3AuthVoteDelay 49\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 49\n"
"V3AuthDistDelay 49\n"
"V3AuthVotingInterval 299\n"
VALID_DIR_AUTH
@@ -3577,23 +3664,23 @@ test_options_validate__v3_auth(void *ignored)
"This may lead to failure to synchronise for a consensus.\n");
tor_free(msg);
- // TODO: It is impossible to reach the case of testingtor network, with
- // v3authvotinginterval too low
- /* free_options_test_data(tdata); */
- /* tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES */
- /* "V3AuthVoteDelay 1\n" */
- /* "V3AuthDistDelay 1\n" */
- /* "V3AuthVotingInterval 9\n" */
- /* VALID_DIR_AUTH */
- /* "TestingTorNetwork 1\n" */
- /* ); */
- /* ret = options_validate(NULL, tdata->opt, */
- /* tdata->def_opt, 0, &msg); */
- /* tt_int_op(ret, OP_EQ, -1); */
- /* tt_str_op(msg, OP_EQ, "V3AuthVotingInterval is insanely low."); */
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "V3AuthVoteDelay 1\n"
+ "V3AuthDistDelay 1\n"
+ "V3AuthVotingInterval 9\n"
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ );
+ /* We have to call the dirauth-specific function to reach this case */
+ ret = options_validate_dirauth_schedule(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_str_op(msg, OP_EQ, "V3AuthVoteDelay is way too low.");
+ tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("TestingV3AuthInitialVoteDelay 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "TestingV3AuthInitialVoteDelay 1\n"
VALID_DIR_AUTH
"TestingTorNetwork 1\n"
);
@@ -3603,7 +3690,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data("TestingV3AuthInitialDistDelay 1\n"
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ "TestingV3AuthInitialDistDelay 1\n"
VALID_DIR_AUTH
"TestingTorNetwork 1\n"
);
@@ -3613,7 +3701,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data(VALID_DIR_AUTH
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
"TestingTorNetwork 1\n"
);
tdata->opt->TestingV3AuthVotingStartOffset = 100000;
@@ -3624,7 +3713,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data(VALID_DIR_AUTH
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
"TestingTorNetwork 1\n"
);
tdata->opt->TestingV3AuthVotingStartOffset = -1;
@@ -3635,7 +3725,8 @@ test_options_validate__v3_auth(void *ignored)
tor_free(msg);
free_options_test_data(tdata);
- tdata = get_options_test_data(VALID_DIR_AUTH
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
"TestingTorNetwork 1\n"
"TestingV3AuthInitialVotingInterval 4\n"
);
@@ -3644,6 +3735,48 @@ test_options_validate__v3_auth(void *ignored)
tt_str_op(msg, OP_EQ, "TestingV3AuthInitialVotingInterval is insanely low.");
tor_free(msg);
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "TestingV3AuthInitialVoteDelay 2\n"
+ "TestingV3AuthInitialDistDelay 2\n"
+ "TestingV3AuthInitialVotingInterval 5\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_ptr_op(msg, OP_EQ, NULL);
+ tor_free(msg);
+
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "TestingV3AuthInitialVotingInterval 7\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_str_op(msg, OP_EQ,
+ "TestingV3AuthInitialVotingInterval does not divide evenly into "
+ "30 minutes.");
+ tor_free(msg);
+
+ free_options_test_data(tdata);
+ tdata = get_options_test_data(ENABLE_AUTHORITY_V3
+ VALID_DIR_AUTH
+ "TestingTorNetwork 1\n"
+ "TestingV3AuthInitialVoteDelay 3\n"
+ "TestingV3AuthInitialDistDelay 3\n"
+ "TestingV3AuthInitialVotingInterval 5\n"
+ );
+ ret = options_validate(NULL, tdata->opt, &msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_str_op(msg, OP_EQ,
+ "TestingV3AuthInitialVoteDelay plus "
+ "TestingV3AuthInitialDistDelay must be less than "
+ "TestingV3AuthInitialVotingInterval");
+ tor_free(msg);
+
done:
policies_free_all();
teardown_capture_of_logs();
@@ -3690,10 +3823,11 @@ test_options_validate__testing_options(void *ignored)
options_test_data_t *tdata = NULL;
setup_capture_of_logs(LOG_WARN);
-#define TEST_TESTING_OPTION(name, low_val, high_val, err_low) \
+#define TEST_TESTING_OPTION(name, low_val, high_val, err_low, EXTRA_OPT_STR) \
STMT_BEGIN \
free_options_test_data(tdata); \
- tdata = get_options_test_data(VALID_DIR_AUTH \
+ tdata = get_options_test_data(EXTRA_OPT_STR \
+ VALID_DIR_AUTH \
"TestingTorNetwork 1\n" \
); \
tdata->opt-> name = low_val; \
@@ -3703,25 +3837,44 @@ test_options_validate__testing_options(void *ignored)
tor_free(msg); \
\
free_options_test_data(tdata); \
- tdata = get_options_test_data(VALID_DIR_AUTH \
+ tdata = get_options_test_data(EXTRA_OPT_STR \
+ VALID_DIR_AUTH \
"TestingTorNetwork 1\n" \
); \
tdata->opt-> name = high_val; \
mock_clean_saved_logs(); \
ret = options_validate(NULL, tdata->opt, &msg); \
tt_int_op(ret, OP_EQ, 0); \
+ tt_ptr_op(msg, OP_EQ, NULL); \
expect_log_msg( #name " is insanely high.\n"); \
tor_free(msg); \
STMT_END
TEST_TESTING_OPTION(TestingAuthDirTimeToLearnReachability, -1, 8000,
- "must be non-negative.");
+ "must be non-negative.", ENABLE_AUTHORITY_V3);
+ TEST_TESTING_OPTION(TestingAuthDirTimeToLearnReachability, -1, 8000,
+ "must be non-negative.", ENABLE_AUTHORITY_BRIDGE);
+
+ TEST_TESTING_OPTION(TestingEstimatedDescriptorPropagationTime, -1, 3601,
+ "must be non-negative.", "");
+ TEST_TESTING_OPTION(TestingClientMaxIntervalWithoutRequest, -1, 3601,
+ "is way too low.", "");
+ TEST_TESTING_OPTION(TestingDirConnectionMaxStall, 1, 3601,
+ "is way too low.", "");
+
+ TEST_TESTING_OPTION(TestingEstimatedDescriptorPropagationTime, -1, 3601,
+ "must be non-negative.", ENABLE_AUTHORITY_V3);
+ TEST_TESTING_OPTION(TestingClientMaxIntervalWithoutRequest, -1, 3601,
+ "is way too low.", ENABLE_AUTHORITY_V3);
+ TEST_TESTING_OPTION(TestingDirConnectionMaxStall, 1, 3601,
+ "is way too low.", ENABLE_AUTHORITY_V3);
+
TEST_TESTING_OPTION(TestingEstimatedDescriptorPropagationTime, -1, 3601,
- "must be non-negative.");
+ "must be non-negative.", ENABLE_AUTHORITY_BRIDGE);
TEST_TESTING_OPTION(TestingClientMaxIntervalWithoutRequest, -1, 3601,
- "is way too low.");
+ "is way too low.", ENABLE_AUTHORITY_BRIDGE);
TEST_TESTING_OPTION(TestingDirConnectionMaxStall, 1, 3601,
- "is way too low.");
+ "is way too low.", ENABLE_AUTHORITY_BRIDGE);
free_options_test_data(tdata);
tdata = get_options_test_data("TestingEnableConnBwEvent 1\n");
1
0

05 Nov '19
commit d6654580851425a67686de2122cd6978e2809667
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 16:50:20 2019 +1000
config: Delete get_list_of_ports_to_forward()
Tor has not supported automatic port forwarding for some time.
---
src/app/config/config.c | 37 -------------------------------------
src/app/config/config.h | 2 --
2 files changed, 39 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index e568d0a58..0fda62d4d 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -6890,43 +6890,6 @@ write_to_data_subdir(const char* subdir, const char* fname,
return return_val;
}
-/** Return a smartlist of ports that must be forwarded by
- * tor-fw-helper. The smartlist contains the ports in a string format
- * that is understandable by tor-fw-helper. */
-smartlist_t *
-get_list_of_ports_to_forward(void)
-{
- smartlist_t *ports_to_forward = smartlist_new();
- int port = 0;
-
- /** XXX TODO tor-fw-helper does not support forwarding ports to
- other hosts than the local one. If the user is binding to a
- different IP address, tor-fw-helper won't work. */
- port = router_get_advertised_or_port(get_options()); /* Get ORPort */
- if (port)
- smartlist_add_asprintf(ports_to_forward, "%d:%d", port, port);
-
- port = router_get_advertised_dir_port(get_options(), 0); /* Get DirPort */
- if (port)
- smartlist_add_asprintf(ports_to_forward, "%d:%d", port, port);
-
- /* Get ports of transport proxies */
- {
- smartlist_t *transport_ports = get_transport_proxy_ports();
- if (transport_ports) {
- smartlist_add_all(ports_to_forward, transport_ports);
- smartlist_free(transport_ports);
- }
- }
-
- if (!smartlist_len(ports_to_forward)) {
- smartlist_free(ports_to_forward);
- ports_to_forward = NULL;
- }
-
- return ports_to_forward;
-}
-
/** Helper to implement GETINFO functions about configuration variables (not
* their values). Given a "config/names" question, set *<b>answer</b> to a
* new string describing the supported configuration variables and their
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 12dd6e1ba..a1963b745 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -182,8 +182,6 @@ char *get_first_listener_addrport_string(int listener_type);
int options_need_geoip_info(const or_options_t *options,
const char **reason_out);
-smartlist_t *get_list_of_ports_to_forward(void);
-
int getinfo_helper_config(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg);
1
0

05 Nov '19
commit 1d4d2deea1987171dea64bf3e563b24194b6ac84
Author: teor <teor(a)torproject.org>
Date: Wed Oct 30 15:38:23 2019 +1000
config: Move dirauth stats actions into the module
This commit:
* moves dirauth stats and mtbf config actions into dirauth_config,
* adds thin wrappers to make the moved code compile.
The moved code is disabled when the dirauth module is disabled.
Part of 32213.
---
src/app/config/config.c | 19 ++--------
src/feature/dirauth/dirauth_config.c | 73 ++++++++++++++++++++++++++++++++++++
src/feature/dirauth/dirauth_config.h | 11 ++++++
3 files changed, 88 insertions(+), 15 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 4dc023c1a..901ed92e5 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -106,7 +106,6 @@
#include "feature/rend/rendservice.h"
#include "lib/geoip/geoip.h"
#include "feature/stats/geoip_stats.h"
-#include "feature/stats/rephist.h"
#include "lib/compress/compress.h"
#include "lib/confmgt/structvar.h"
#include "lib/crypt_ops/crypto_init.h"
@@ -1897,7 +1896,8 @@ options_act,(const or_options_t *old_options))
if (! or_state_loaded() && running_tor) {
if (or_state_load())
return -1;
- rep_hist_load_mtbf_data(time(NULL));
+ if (options_act_dirauth_mtbf(options) < 0)
+ return -1;
}
/* 31851: some of the code in these functions is relay-only */
@@ -2131,21 +2131,10 @@ options_act,(const or_options_t *old_options))
}
bool print_notice = 0;
- if (options->BridgeAuthoritativeDir) {
- time_t now = time(NULL);
-
- if ((!old_options || !old_options->BridgeAuthoritativeDir) &&
- options->BridgeAuthoritativeDir) {
- rep_hist_desc_stats_init(now);
- print_notice = 1;
- }
-
- if (old_options && old_options->BridgeAuthoritativeDir &&
- !options->BridgeAuthoritativeDir)
- rep_hist_desc_stats_term();
-
if (options_act_relay_stats(old_options, &print_notice) < 0)
return -1;
+ if (options_act_dirauth_stats(old_options, &print_notice) < 0)
+ return -1;
if (print_notice)
options_act_relay_stats_msg();
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 6574edb54..99e3a45fc 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -21,6 +21,7 @@
#include "app/config/config.h"
#include "feature/dircommon/voting_schedule.h"
+#include "feature/stats/rephist.h"
#include "feature/dirauth/authmode.h"
#include "feature/dirauth/bwauth.h"
@@ -352,3 +353,75 @@ options_act_dirauth(const or_options_t *old_options)
return 0;
}
+
+/** Fetch the active option list, and take dirauth mtbf actions based on it.
+ * All of the things we do should survive being done repeatedly. If present,
+ * <b>old_options</b> contains the previous value of the options.
+ *
+ * Must be called immediately after a successful or_state_load().
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_dirauth_mtbf(const or_options_t *old_options)
+{
+ (void)old_options;
+
+ const or_options_t *options = get_options();
+ int running_tor = options->command == CMD_RUN_TOR;
+
+ /* Load dirauth state */
+ if (running_tor) {
+ rep_hist_load_mtbf_data(time(NULL));
+ }
+
+ return 0;
+}
+
+/** Fetch the active option list, and take dirauth statistics actions based
+ * on it. All of the things we do should survive being done repeatedly. If
+ * present, <b>old_options</b> contains the previous value of the options.
+ *
+ * Sets <b>*print_notice_out</b> if we enabled stats, and need to print
+ * a stats log using options_act_relay_stats_msg().
+ *
+ * Return 0 if all goes well, return -1 if it's time to die.
+ *
+ * Note: We haven't moved all the "act on new configuration" logic
+ * into the options_act* functions yet. Some is still in do_hup() and other
+ * places.
+ */
+int
+options_act_dirauth_stats(const or_options_t *old_options,
+ bool *print_notice_out)
+{
+ if (BUG(!print_notice_out))
+ return -1;
+
+ const or_options_t *options = get_options();
+
+ if (options->BridgeAuthoritativeDir) {
+ time_t now = time(NULL);
+ int print_notice = 0;
+
+ if ((!old_options || !old_options->BridgeAuthoritativeDir) &&
+ options->BridgeAuthoritativeDir) {
+ rep_hist_desc_stats_init(now);
+ print_notice = 1;
+ }
+ if (print_notice)
+ *print_notice_out = 1;
+ }
+
+ /* If we used to have statistics enabled but we just disabled them,
+ stop gathering them. */
+ if (old_options && old_options->BridgeAuthoritativeDir &&
+ !options->BridgeAuthoritativeDir)
+ rep_hist_desc_stats_term();
+
+ return 0;
+}
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index 2c67c62ec..965472aa2 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -16,6 +16,8 @@ typedef struct or_options_t or_options_t;
#ifdef HAVE_MODULE_DIRAUTH
+#include "lib/cc/torint.h"
+
int options_validate_dirauth_mode(const or_options_t *old_options,
or_options_t *options,
char **msg);
@@ -33,6 +35,9 @@ int options_validate_dirauth_testing(const or_options_t *old_options,
char **msg);
int options_act_dirauth(const or_options_t *old_options);
+int options_act_dirauth_mtbf(const or_options_t *old_options);
+int options_act_dirauth_stats(const or_options_t *old_options,
+ bool *print_notice_out);
#else
@@ -75,6 +80,12 @@ options_validate_dirauth_mode(const or_options_t *old_options,
#define options_act_dirauth(old_options) \
(((void)(old_options)),0)
+#define options_act_dirauth_mtbf(old_options) \
+ (((void)(old_options)),0)
+
+#define options_act_dirauth_stats(old_options, print_notice_out) \
+ (((void)(old_options)),((void)(print_notice_out)),0)
+
#endif /* defined(HAVE_MODULE_DIRAUTH) */
#endif /* !defined(TOR_FEATURE_DIRAUTH_DIRAUTH_CONFIG_H) */
1
0