relay/dirauth: Set some output arguments in stubs
[tor.git] / src / feature / relay / relay_config.c
blob3e9961f47e3affdb46155e60393478cff4a5f06c
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2020, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * @file relay_config.c
9 * @brief Code to interpret the user's configuration of Tor's relay module.
10 **/
12 #include "orconfig.h"
13 #define RELAY_CONFIG_PRIVATE
14 #include "feature/relay/relay_config.h"
16 #include "lib/encoding/confline.h"
17 #include "lib/confmgt/confmgt.h"
19 #include "lib/container/smartlist.h"
20 #include "lib/geoip/geoip.h"
21 #include "lib/meminfo/meminfo.h"
22 #include "lib/osinfo/uname.h"
23 #include "lib/process/setuid.h"
25 /* Required for dirinfo_type_t in or_options_t */
26 #include "core/or/or.h"
27 #include "app/config/config.h"
29 #include "core/mainloop/connection.h"
30 #include "core/mainloop/cpuworker.h"
31 #include "core/mainloop/mainloop.h"
32 #include "core/or/circuitbuild.h"
33 #include "core/or/connection_or.h"
34 #include "core/or/port_cfg_st.h"
36 #include "feature/hibernate/hibernate.h"
37 #include "feature/nodelist/nickname.h"
38 #include "feature/stats/geoip_stats.h"
39 #include "feature/stats/predict_ports.h"
40 #include "feature/stats/rephist.h"
42 #include "feature/dirauth/authmode.h"
44 #include "feature/dircache/consdiffmgr.h"
45 #include "feature/relay/dns.h"
46 #include "feature/relay/routermode.h"
48 /** Contents of most recently read DirPortFrontPage file. */
49 static char *global_dirfrontpagecontents = NULL;
51 /* Copied from config.c, we will refactor later in 29211. */
52 #define REJECT(arg) \
53 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
54 #if defined(__GNUC__) && __GNUC__ <= 3
55 #define COMPLAIN(args...) \
56 STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END
57 #else
58 #define COMPLAIN(args, ...) \
59 STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
60 #endif /* defined(__GNUC__) && __GNUC__ <= 3 */
62 /* Used in the various options_transition_affects* functions. */
63 #define YES_IF_CHANGED_BOOL(opt) \
64 if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1;
65 #define YES_IF_CHANGED_INT(opt) \
66 if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
67 #define YES_IF_CHANGED_STRING(opt) \
68 if (!CFG_EQ_STRING(old_options, new_options, opt)) return 1;
69 #define YES_IF_CHANGED_LINELIST(opt) \
70 if (!CFG_EQ_LINELIST(old_options, new_options, opt)) return 1;
72 /** Return the contents of our frontpage string, or NULL if not configured. */
73 MOCK_IMPL(const char*,
74 relay_get_dirportfrontpage, (void))
76 return global_dirfrontpagecontents;
79 /** Release all memory and resources held by global relay configuration
80 * structures.
82 void
83 relay_config_free_all(void)
85 tor_free(global_dirfrontpagecontents);
88 /** Return the bandwidthrate that we are going to report to the authorities
89 * based on the config options. */
90 uint32_t
91 relay_get_effective_bwrate(const or_options_t *options)
93 uint64_t bw = options->BandwidthRate;
94 if (bw > options->MaxAdvertisedBandwidth)
95 bw = options->MaxAdvertisedBandwidth;
96 if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
97 bw = options->RelayBandwidthRate;
98 /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */
99 return (uint32_t)bw;
102 /** Return the bandwidthburst that we are going to report to the authorities
103 * based on the config options. */
104 uint32_t
105 relay_get_effective_bwburst(const or_options_t *options)
107 uint64_t bw = options->BandwidthBurst;
108 if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
109 bw = options->RelayBandwidthBurst;
110 /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */
111 return (uint32_t)bw;
114 /** Warn for every Extended ORPort port in <b>ports</b> that is on a
115 * publicly routable address. */
116 void
117 port_warn_nonlocal_ext_orports(const smartlist_t *ports, const char *portname)
119 SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
120 if (port->type != CONN_TYPE_EXT_OR_LISTENER)
121 continue;
122 if (port->is_unix_addr)
123 continue;
124 /* XXX maybe warn even if address is RFC1918? */
125 if (!tor_addr_is_internal(&port->addr, 1)) {
126 log_warn(LD_CONFIG, "You specified a public address '%s' for %sPort. "
127 "This is not advised; this address is supposed to only be "
128 "exposed on localhost so that your pluggable transport "
129 "proxies can connect to it.",
130 fmt_addrport(&port->addr, port->port), portname);
132 } SMARTLIST_FOREACH_END(port);
135 /** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal
136 * consistency and warn as appropriate. On Unix-based OSes, set
137 * *<b>n_low_ports_out</b> to the number of sub-1024 ports we will be
138 * binding, and warn if we may be unable to re-bind after hibernation. */
139 static int
140 check_server_ports(const smartlist_t *ports,
141 const or_options_t *options,
142 int *n_low_ports_out)
144 if (BUG(!ports))
145 return -1;
147 if (BUG(!options))
148 return -1;
150 if (BUG(!n_low_ports_out))
151 return -1;
153 int n_orport_advertised = 0;
154 int n_orport_advertised_ipv4 = 0;
155 int n_orport_listeners = 0;
156 int n_dirport_advertised = 0;
157 int n_dirport_listeners = 0;
158 int n_low_port = 0;
159 int r = 0;
161 SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
162 if (port->type == CONN_TYPE_DIR_LISTENER) {
163 if (! port->server_cfg.no_advertise)
164 ++n_dirport_advertised;
165 if (! port->server_cfg.no_listen)
166 ++n_dirport_listeners;
167 } else if (port->type == CONN_TYPE_OR_LISTENER) {
168 if (! port->server_cfg.no_advertise) {
169 ++n_orport_advertised;
170 if (port_binds_ipv4(port))
171 ++n_orport_advertised_ipv4;
173 if (! port->server_cfg.no_listen)
174 ++n_orport_listeners;
175 } else {
176 continue;
178 #ifndef _WIN32
179 if (!port->server_cfg.no_listen && port->port < 1024)
180 ++n_low_port;
181 #endif
182 } SMARTLIST_FOREACH_END(port);
184 if (n_orport_advertised && !n_orport_listeners) {
185 log_warn(LD_CONFIG, "We are advertising an ORPort, but not actually "
186 "listening on one.");
187 r = -1;
189 if (n_orport_listeners && !n_orport_advertised) {
190 log_warn(LD_CONFIG, "We are listening on an ORPort, but not advertising "
191 "any ORPorts. This will keep us from building a %s "
192 "descriptor, and make us impossible to use.",
193 options->BridgeRelay ? "bridge" : "router");
194 r = -1;
196 if (n_dirport_advertised && !n_dirport_listeners) {
197 log_warn(LD_CONFIG, "We are advertising a DirPort, but not actually "
198 "listening on one.");
199 r = -1;
201 if (n_dirport_advertised > 1) {
202 log_warn(LD_CONFIG, "Can't advertise more than one DirPort.");
203 r = -1;
205 if (n_orport_advertised && !n_orport_advertised_ipv4 &&
206 !options->BridgeRelay) {
207 log_warn(LD_CONFIG, "Configured public relay to listen only on an IPv6 "
208 "address. Tor needs to listen on an IPv4 address too.");
209 r = -1;
212 if (n_low_port && options->AccountingMax &&
213 (!have_capability_support() || options->KeepBindCapabilities == 0)) {
214 const char *extra = "";
215 if (options->KeepBindCapabilities == 0 && have_capability_support())
216 extra = ", and you have disabled KeepBindCapabilities.";
217 log_warn(LD_CONFIG,
218 "You have set AccountingMax to use hibernation. You have also "
219 "chosen a low DirPort or OrPort%s."
220 "This combination can make Tor stop "
221 "working when it tries to re-attach the port after a period of "
222 "hibernation. Please choose a different port or turn off "
223 "hibernation unless you know this combination will work on your "
224 "platform.", extra);
227 if (n_low_ports_out)
228 *n_low_ports_out = n_low_port;
230 return r;
233 /** Parse all relay ports from <b>options</b>. On success, add parsed ports to
234 * <b>ports</b>, and return 0. On failure, set *<b>msg</b> to a newly
235 * allocated string describing the problem, and return -1.
238 port_parse_ports_relay(or_options_t *options,
239 char **msg,
240 smartlist_t *ports_out,
241 int *have_low_ports_out)
243 int retval = -1;
244 smartlist_t *ports = smartlist_new();
245 int n_low_ports = 0;
247 if (BUG(!options))
248 goto err;
250 if (BUG(!msg))
251 goto err;
253 if (BUG(!ports_out))
254 goto err;
256 if (BUG(!have_low_ports_out))
257 goto err;
259 if (options->ClientOnly) {
260 retval = 0;
261 goto err;
264 if (port_parse_config(ports,
265 options->ORPort_lines,
266 "OR", CONN_TYPE_OR_LISTENER,
267 "0.0.0.0", 0,
268 CL_PORT_SERVER_OPTIONS) < 0) {
269 *msg = tor_strdup("Invalid ORPort configuration");
270 goto err;
272 if (port_parse_config(ports,
273 options->ExtORPort_lines,
274 "ExtOR", CONN_TYPE_EXT_OR_LISTENER,
275 "127.0.0.1", 0,
276 CL_PORT_SERVER_OPTIONS|CL_PORT_WARN_NONLOCAL) < 0) {
277 *msg = tor_strdup("Invalid ExtORPort configuration");
278 goto err;
280 if (port_parse_config(ports,
281 options->DirPort_lines,
282 "Dir", CONN_TYPE_DIR_LISTENER,
283 "0.0.0.0", 0,
284 CL_PORT_SERVER_OPTIONS) < 0) {
285 *msg = tor_strdup("Invalid DirPort configuration");
286 goto err;
289 if (check_server_ports(ports, options, &n_low_ports) < 0) {
290 *msg = tor_strdup("Misconfigured server ports");
291 goto err;
294 smartlist_add_all(ports_out, ports);
295 smartlist_free(ports);
296 ports = NULL;
297 retval = 0;
299 err:
300 if (*have_low_ports_out < 0)
301 *have_low_ports_out = (n_low_ports > 0);
302 if (ports) {
303 SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p));
304 smartlist_free(ports);
306 return retval;
309 /** Update the relay *Port_set values in <b>options</b> from <b>ports</b>. */
310 void
311 port_update_port_set_relay(or_options_t *options,
312 const smartlist_t *ports)
314 if (BUG(!options))
315 return;
317 if (BUG(!ports))
318 return;
320 if (options->ClientOnly)
321 return;
323 /* Update the relay *Port_set options. The !! here is to force a boolean
324 * out of an integer. */
325 options->ORPort_set =
326 !! port_count_real_listeners(ports, CONN_TYPE_OR_LISTENER, 0);
327 options->DirPort_set =
328 !! port_count_real_listeners(ports, CONN_TYPE_DIR_LISTENER, 0);
329 options->ExtORPort_set =
330 !! port_count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER, 0);
334 * Legacy validation function, which checks that the current OS is usable in
335 * relay mode, if options is set to a relay mode.
337 * Warns about OSes with potential issues. Does not set *<b>msg</b>.
338 * Always returns 0.
341 options_validate_relay_os(const or_options_t *old_options,
342 or_options_t *options,
343 char **msg)
345 (void)old_options;
347 if (BUG(!options))
348 return -1;
350 if (BUG(!msg))
351 return -1;
353 if (!server_mode(options))
354 return 0;
356 const char *uname = get_uname();
358 if (!strcmpstart(uname, "Windows 95") ||
359 !strcmpstart(uname, "Windows 98") ||
360 !strcmpstart(uname, "Windows Me")) {
361 log_warn(LD_CONFIG, "Tor is running as a server, but you are "
362 "running %s; this probably won't work. See "
363 "https://www.torproject.org/docs/faq.html#BestOSForRelay "
364 "for details.", uname);
367 return 0;
371 * Legacy validation/normalization function for the relay info options.
372 * Uses old_options as the previous options.
374 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
375 * on error.
378 options_validate_relay_info(const or_options_t *old_options,
379 or_options_t *options,
380 char **msg)
382 (void)old_options;
384 if (BUG(!options))
385 return -1;
387 if (BUG(!msg))
388 return -1;
390 if (options->Nickname == NULL) {
391 if (server_mode(options)) {
392 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
394 } else {
395 if (!is_legal_nickname(options->Nickname)) {
396 tor_asprintf(msg,
397 "Nickname '%s', nicknames must be between 1 and 19 characters "
398 "inclusive, and must contain only the characters [a-zA-Z0-9].",
399 options->Nickname);
400 return -1;
404 if (server_mode(options) && !options->ContactInfo) {
405 log_warn(LD_CONFIG,
406 "Your ContactInfo config option is not set. Please strongly "
407 "consider setting it, so we can contact you if your relay is "
408 "misconfigured, end-of-life, or something else goes wrong. "
409 "It is also possible that your relay might get rejected from "
410 "the network due to a missing valid contact address.");
413 const char *ContactInfo = options->ContactInfo;
414 if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
415 REJECT("ContactInfo config option must be UTF-8.");
417 return 0;
420 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
421 * and write it to <b>options</b>-\>PublishServerDescriptor_. Treat "1"
422 * as "v3" unless BridgeRelay is 1, in which case treat it as "bridge".
423 * Treat "0" as "".
424 * Return 0 on success or -1 if not a recognized authority type (in which
425 * case the value of PublishServerDescriptor_ is undefined). */
426 static int
427 compute_publishserverdescriptor(or_options_t *options)
429 smartlist_t *list = options->PublishServerDescriptor;
430 dirinfo_type_t *auth = &options->PublishServerDescriptor_;
431 *auth = NO_DIRINFO;
432 if (!list) /* empty list, answer is none */
433 return 0;
434 SMARTLIST_FOREACH_BEGIN(list, const char *, string) {
435 if (!strcasecmp(string, "v1"))
436 log_warn(LD_CONFIG, "PublishServerDescriptor v1 has no effect, because "
437 "there are no v1 directory authorities anymore.");
438 else if (!strcmp(string, "1"))
439 if (options->BridgeRelay)
440 *auth |= BRIDGE_DIRINFO;
441 else
442 *auth |= V3_DIRINFO;
443 else if (!strcasecmp(string, "v2"))
444 log_warn(LD_CONFIG, "PublishServerDescriptor v2 has no effect, because "
445 "there are no v2 directory authorities anymore.");
446 else if (!strcasecmp(string, "v3"))
447 *auth |= V3_DIRINFO;
448 else if (!strcasecmp(string, "bridge"))
449 *auth |= BRIDGE_DIRINFO;
450 else if (!strcasecmp(string, "hidserv"))
451 log_warn(LD_CONFIG,
452 "PublishServerDescriptor hidserv is invalid. See "
453 "PublishHidServDescriptors.");
454 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
455 /* no authority */;
456 else
457 return -1;
458 } SMARTLIST_FOREACH_END(string);
459 return 0;
463 * Validate the configured bridge distribution method from a BridgeDistribution
464 * config line.
466 * The input <b>bd</b>, is a string taken from the BridgeDistribution config
467 * line (if present). If the option wasn't set, return 0 immediately. The
468 * BridgeDistribution option is then validated. Currently valid, recognised
469 * options are:
471 * - "none"
472 * - "any"
473 * - "https"
474 * - "email"
475 * - "moat"
477 * If the option string is unrecognised, a warning will be logged and 0 is
478 * returned. If the option string contains an invalid character, -1 is
479 * returned.
481 STATIC int
482 check_bridge_distribution_setting(const char *bd)
484 if (bd == NULL)
485 return 0;
487 const char *RECOGNIZED[] = {
488 "none", "any", "https", "email", "moat"
490 unsigned i;
491 for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) {
492 if (!strcasecmp(bd, RECOGNIZED[i]))
493 return 0;
496 const char *cp = bd;
497 // Method = (KeywordChar | "_") +
498 while (TOR_ISALNUM(*cp) || *cp == '-' || *cp == '_')
499 ++cp;
501 if (*cp == 0) {
502 log_warn(LD_CONFIG, "Unrecognized BridgeDistribution value %s. I'll "
503 "assume you know what you are doing...", escaped(bd));
504 return 0; // we reached the end of the string; all is well
505 } else {
506 return -1; // we found a bad character in the string.
511 * Legacy validation/normalization function for the bridge relay options.
512 * Uses old_options as the previous options.
514 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
515 * on error.
518 options_validate_publish_server(const or_options_t *old_options,
519 or_options_t *options,
520 char **msg)
522 (void)old_options;
524 if (BUG(!options))
525 return -1;
527 if (BUG(!msg))
528 return -1;
530 if (compute_publishserverdescriptor(options) < 0) {
531 tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
532 return -1;
535 if ((options->BridgeRelay
536 || options->PublishServerDescriptor_ & BRIDGE_DIRINFO)
537 && (options->PublishServerDescriptor_ & V3_DIRINFO)) {
538 REJECT("Bridges are not supposed to publish router descriptors to the "
539 "directory authorities. Please correct your "
540 "PublishServerDescriptor line.");
543 if (options->BridgeDistribution) {
544 if (!options->BridgeRelay) {
545 REJECT("You set BridgeDistribution, but you didn't set BridgeRelay!");
547 if (check_bridge_distribution_setting(options->BridgeDistribution) < 0) {
548 REJECT("Invalid BridgeDistribution value.");
552 if (options->PublishServerDescriptor)
553 SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
554 if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
555 if (smartlist_len(options->PublishServerDescriptor) > 1) {
556 COMPLAIN("You have passed a list of multiple arguments to the "
557 "PublishServerDescriptor option that includes 0 or 1. "
558 "0 or 1 should only be used as the sole argument. "
559 "This configuration will be rejected in a future release.");
560 break;
564 return 0;
568 * Legacy validation/normalization function for the relay padding options.
569 * Uses old_options as the previous options.
571 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
572 * on error.
575 options_validate_relay_padding(const or_options_t *old_options,
576 or_options_t *options,
577 char **msg)
579 (void)old_options;
581 if (BUG(!options))
582 return -1;
584 if (BUG(!msg))
585 return -1;
587 if (!server_mode(options))
588 return 0;
590 if (options->ConnectionPadding != -1) {
591 REJECT("Relays must use 'auto' for the ConnectionPadding setting.");
594 if (options->ReducedConnectionPadding != 0) {
595 REJECT("Relays cannot set ReducedConnectionPadding. ");
598 if (options->CircuitPadding == 0) {
599 REJECT("Relays cannot set CircuitPadding to 0. ");
602 if (options->ReducedCircuitPadding == 1) {
603 REJECT("Relays cannot set ReducedCircuitPadding. ");
606 return 0;
610 * Legacy validation/normalization function for the relay bandwidth options.
611 * Uses old_options as the previous options.
613 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
614 * on error.
617 options_validate_relay_bandwidth(const or_options_t *old_options,
618 or_options_t *options,
619 char **msg)
621 (void)old_options;
623 if (BUG(!options))
624 return -1;
626 if (BUG(!msg))
627 return -1;
629 /* 31851: the tests expect us to validate bandwidths, even when we are not
630 * in relay mode. */
631 if (config_ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
632 "MaxAdvertisedBandwidth", msg) < 0)
633 return -1;
634 if (config_ensure_bandwidth_cap(&options->RelayBandwidthRate,
635 "RelayBandwidthRate", msg) < 0)
636 return -1;
637 if (config_ensure_bandwidth_cap(&options->RelayBandwidthBurst,
638 "RelayBandwidthBurst", msg) < 0)
639 return -1;
640 if (config_ensure_bandwidth_cap(&options->PerConnBWRate,
641 "PerConnBWRate", msg) < 0)
642 return -1;
643 if (config_ensure_bandwidth_cap(&options->PerConnBWBurst,
644 "PerConnBWBurst", msg) < 0)
645 return -1;
647 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
648 options->RelayBandwidthBurst = options->RelayBandwidthRate;
649 if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
650 options->RelayBandwidthRate = options->RelayBandwidthBurst;
652 if (server_mode(options)) {
653 const unsigned required_min_bw =
654 public_server_mode(options) ?
655 RELAY_REQUIRED_MIN_BANDWIDTH : BRIDGE_REQUIRED_MIN_BANDWIDTH;
656 const char * const optbridge =
657 public_server_mode(options) ? "" : "bridge ";
658 if (options->BandwidthRate < required_min_bw) {
659 tor_asprintf(msg,
660 "BandwidthRate is set to %d bytes/second. "
661 "For %sservers, it must be at least %u.",
662 (int)options->BandwidthRate, optbridge,
663 required_min_bw);
664 return -1;
665 } else if (options->MaxAdvertisedBandwidth <
666 required_min_bw/2) {
667 tor_asprintf(msg,
668 "MaxAdvertisedBandwidth is set to %d bytes/second. "
669 "For %sservers, it must be at least %u.",
670 (int)options->MaxAdvertisedBandwidth, optbridge,
671 required_min_bw/2);
672 return -1;
674 if (options->RelayBandwidthRate &&
675 options->RelayBandwidthRate < required_min_bw) {
676 tor_asprintf(msg,
677 "RelayBandwidthRate is set to %d bytes/second. "
678 "For %sservers, it must be at least %u.",
679 (int)options->RelayBandwidthRate, optbridge,
680 required_min_bw);
681 return -1;
685 /* 31851: the tests expect us to validate bandwidths, even when we are not
686 * in relay mode. */
687 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
688 REJECT("RelayBandwidthBurst must be at least equal "
689 "to RelayBandwidthRate.");
691 /* if they set relaybandwidth* really high but left bandwidth*
692 * at the default, raise the defaults. */
693 if (options->RelayBandwidthRate > options->BandwidthRate)
694 options->BandwidthRate = options->RelayBandwidthRate;
695 if (options->RelayBandwidthBurst > options->BandwidthBurst)
696 options->BandwidthBurst = options->RelayBandwidthBurst;
698 return 0;
702 * Legacy validation/normalization function for the relay bandwidth accounting
703 * options. Uses old_options as the previous options.
705 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
706 * on error.
709 options_validate_relay_accounting(const or_options_t *old_options,
710 or_options_t *options,
711 char **msg)
713 (void)old_options;
715 if (BUG(!options))
716 return -1;
718 if (BUG(!msg))
719 return -1;
721 /* 31851: the tests expect us to validate accounting, even when we are not
722 * in relay mode. */
723 if (accounting_parse_options(options, 1)<0)
724 REJECT("Failed to parse accounting options. See logs for details.");
726 if (options->AccountingMax) {
727 if (options->RendConfigLines && server_mode(options)) {
728 log_warn(LD_CONFIG, "Using accounting with a hidden service and an "
729 "ORPort is risky: your hidden service(s) and your public "
730 "address will all turn off at the same time, which may alert "
731 "observers that they are being run by the same party.");
732 } else if (config_count_key(options->RendConfigLines,
733 "HiddenServiceDir") > 1) {
734 log_warn(LD_CONFIG, "Using accounting with multiple hidden services is "
735 "risky: they will all turn off at the same time, which may "
736 "alert observers that they are being run by the same party.");
740 options->AccountingRule = ACCT_MAX;
741 if (options->AccountingRule_option) {
742 if (!strcmp(options->AccountingRule_option, "sum"))
743 options->AccountingRule = ACCT_SUM;
744 else if (!strcmp(options->AccountingRule_option, "max"))
745 options->AccountingRule = ACCT_MAX;
746 else if (!strcmp(options->AccountingRule_option, "in"))
747 options->AccountingRule = ACCT_IN;
748 else if (!strcmp(options->AccountingRule_option, "out"))
749 options->AccountingRule = ACCT_OUT;
750 else
751 REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
754 return 0;
757 /** Verify whether lst is a list of strings containing valid-looking
758 * comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$'
759 * to any nickname or fingerprint that needs it. Also splits comma-separated
760 * list elements into multiple elements. Return 0 on success.
761 * Warn and return -1 on failure.
763 static int
764 normalize_nickname_list(config_line_t **normalized_out,
765 const config_line_t *lst, const char *name,
766 char **msg)
768 if (!lst)
769 return 0;
771 config_line_t *new_nicknames = NULL;
772 config_line_t **new_nicknames_next = &new_nicknames;
774 const config_line_t *cl;
775 for (cl = lst; cl; cl = cl->next) {
776 const char *line = cl->value;
777 if (!line)
778 continue;
780 int valid_line = 1;
781 smartlist_t *sl = smartlist_new();
782 smartlist_split_string(sl, line, ",",
783 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
784 SMARTLIST_FOREACH_BEGIN(sl, char *, s)
786 char *normalized = NULL;
787 if (!is_legal_nickname_or_hexdigest(s)) {
788 // check if first char is dollar
789 if (s[0] != '$') {
790 // Try again but with a dollar symbol prepended
791 char *prepended;
792 tor_asprintf(&prepended, "$%s", s);
794 if (is_legal_nickname_or_hexdigest(prepended)) {
795 // The nickname is valid when it's prepended, set it as the
796 // normalized version
797 normalized = prepended;
798 } else {
799 // Still not valid, free and fallback to error message
800 tor_free(prepended);
804 if (!normalized) {
805 tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
806 valid_line = 0;
807 break;
809 } else {
810 normalized = tor_strdup(s);
813 config_line_t *next = tor_malloc_zero(sizeof(*next));
814 next->key = tor_strdup(cl->key);
815 next->value = normalized;
816 next->next = NULL;
818 *new_nicknames_next = next;
819 new_nicknames_next = &next->next;
820 } SMARTLIST_FOREACH_END(s);
822 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
823 smartlist_free(sl);
825 if (!valid_line) {
826 config_free_lines(new_nicknames);
827 return -1;
831 *normalized_out = new_nicknames;
833 return 0;
836 #define ONE_MEGABYTE (UINT64_C(1) << 20)
838 /* If we have less than 300 MB suggest disabling dircache */
839 #define DIRCACHE_MIN_MEM_MB 300
840 #define DIRCACHE_MIN_MEM_BYTES (DIRCACHE_MIN_MEM_MB*ONE_MEGABYTE)
841 #define STRINGIFY(val) #val
843 /** Create a warning message for emitting if we are a dircache but may not have
844 * enough system memory, or if we are not a dircache but probably should be.
845 * Return -1 when a message is returned in *msg*, else return 0. */
846 STATIC int
847 have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
848 char **msg)
850 *msg = NULL;
851 /* XXX We should possibly be looking at MaxMemInQueues here
852 * unconditionally. Or we should believe total_mem unconditionally. */
853 if (total_mem == 0) {
854 if (get_total_system_memory(&total_mem) < 0) {
855 total_mem = options->MaxMemInQueues >= SIZE_MAX ?
856 SIZE_MAX : (size_t)options->MaxMemInQueues;
859 if (options->DirCache) {
860 if (total_mem < DIRCACHE_MIN_MEM_BYTES) {
861 if (options->BridgeRelay) {
862 tor_asprintf(msg, "Running a Bridge with less than %d MB of memory "
863 "is not recommended.", DIRCACHE_MIN_MEM_MB);
864 } else {
865 tor_asprintf(msg, "Being a directory cache (default) with less than "
866 "%d MB of memory is not recommended and may consume "
867 "most of the available resources. Consider disabling "
868 "this functionality by setting the DirCache option "
869 "to 0.", DIRCACHE_MIN_MEM_MB);
872 } else {
873 if (total_mem >= DIRCACHE_MIN_MEM_BYTES) {
874 *msg = tor_strdup("DirCache is disabled and we are configured as a "
875 "relay. We will not become a Guard.");
878 return *msg == NULL ? 0 : -1;
880 #undef STRINGIFY
883 * Legacy validation/normalization function for the relay mode options.
884 * Uses old_options as the previous options.
886 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
887 * on error.
890 options_validate_relay_mode(const or_options_t *old_options,
891 or_options_t *options,
892 char **msg)
894 (void)old_options;
896 if (BUG(!options))
897 return -1;
899 if (BUG(!msg))
900 return -1;
902 if (server_mode(options) && options->RendConfigLines)
903 log_warn(LD_CONFIG,
904 "Tor is currently configured as a relay and a hidden service. "
905 "That's not very secure: you should probably run your hidden service "
906 "in a separate Tor process, at least -- see "
907 "https://trac.torproject.org/8742");
909 if (options->BridgeRelay && options->DirPort_set) {
910 log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
911 "DirPort");
912 config_free_lines(options->DirPort_lines);
913 options->DirPort_lines = NULL;
914 options->DirPort_set = 0;
917 if (options->DirPort_set && !options->DirCache) {
918 REJECT("DirPort configured but DirCache disabled. DirPort requires "
919 "DirCache.");
922 if (options->BridgeRelay && !options->DirCache) {
923 REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires "
924 "DirCache.");
927 if (options->BridgeRelay == 1 && ! options->ORPort_set)
928 REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid "
929 "combination.");
931 if (server_mode(options)) {
932 char *dircache_msg = NULL;
933 if (have_enough_mem_for_dircache(options, 0, &dircache_msg)) {
934 log_warn(LD_CONFIG, "%s", dircache_msg);
935 tor_free(dircache_msg);
939 if (options->MyFamily_lines && options->BridgeRelay) {
940 log_warn(LD_CONFIG, "Listing a family for a bridge relay is not "
941 "supported: it can reveal bridge fingerprints to censors. "
942 "You should also make sure you aren't listing this bridge's "
943 "fingerprint in any other MyFamily.");
945 if (options->MyFamily_lines && !options->ContactInfo) {
946 log_warn(LD_CONFIG, "MyFamily is set but ContactInfo is not configured. "
947 "ContactInfo should always be set when MyFamily option is too.");
949 if (normalize_nickname_list(&options->MyFamily,
950 options->MyFamily_lines, "MyFamily", msg))
951 return -1;
953 if (options->ConstrainedSockets) {
954 if (options->DirPort_set) {
955 /* Providing cached directory entries while system TCP buffers are scarce
956 * will exacerbate the socket errors. Suggest that this be disabled. */
957 COMPLAIN("You have requested constrained socket buffers while also "
958 "serving directory entries via DirPort. It is strongly "
959 "suggested that you disable serving directory requests when "
960 "system TCP buffer resources are scarce.");
964 return 0;
968 * Legacy validation/normalization function for the relay testing options
969 * in options. Uses old_options as the previous options.
971 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
972 * on error.
975 options_validate_relay_testing(const or_options_t *old_options,
976 or_options_t *options,
977 char **msg)
979 (void)old_options;
981 if (BUG(!options))
982 return -1;
984 if (BUG(!msg))
985 return -1;
987 if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
988 REJECT("SigningKeyLifetime is too short.");
989 if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2)
990 REJECT("LinkCertLifetime is too short.");
991 if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
992 REJECT("TestingAuthKeyLifetime is too short.");
994 return 0;
997 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
998 * will require us to rotate the CPU and DNS workers; else return 0. */
999 static int
1000 options_transition_affects_workers(const or_options_t *old_options,
1001 const or_options_t *new_options)
1003 YES_IF_CHANGED_STRING(DataDirectory);
1004 YES_IF_CHANGED_INT(NumCPUs);
1005 YES_IF_CHANGED_LINELIST(ORPort_lines);
1006 YES_IF_CHANGED_BOOL(ServerDNSSearchDomains);
1007 YES_IF_CHANGED_BOOL(SafeLogging_);
1008 YES_IF_CHANGED_BOOL(ClientOnly);
1009 YES_IF_CHANGED_BOOL(LogMessageDomains);
1010 YES_IF_CHANGED_LINELIST(Logs);
1012 if (server_mode(old_options) != server_mode(new_options) ||
1013 public_server_mode(old_options) != public_server_mode(new_options) ||
1014 dir_server_mode(old_options) != dir_server_mode(new_options))
1015 return 1;
1017 /* Nothing that changed matters. */
1018 return 0;
1021 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
1022 * will require us to generate a new descriptor; else return 0. */
1023 static int
1024 options_transition_affects_descriptor(const or_options_t *old_options,
1025 const or_options_t *new_options)
1027 /* XXX We can be smarter here. If your DirPort isn't being
1028 * published and you just turned it off, no need to republish. Etc. */
1030 YES_IF_CHANGED_STRING(DataDirectory);
1031 YES_IF_CHANGED_STRING(Nickname);
1032 YES_IF_CHANGED_STRING(Address);
1033 YES_IF_CHANGED_LINELIST(ExitPolicy);
1034 YES_IF_CHANGED_BOOL(ExitRelay);
1035 YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate);
1036 YES_IF_CHANGED_BOOL(ExitPolicyRejectLocalInterfaces);
1037 YES_IF_CHANGED_BOOL(IPv6Exit);
1038 YES_IF_CHANGED_LINELIST(ORPort_lines);
1039 YES_IF_CHANGED_LINELIST(DirPort_lines);
1040 YES_IF_CHANGED_LINELIST(DirPort_lines);
1041 YES_IF_CHANGED_BOOL(ClientOnly);
1042 YES_IF_CHANGED_BOOL(DisableNetwork);
1043 YES_IF_CHANGED_BOOL(PublishServerDescriptor_);
1044 YES_IF_CHANGED_STRING(ContactInfo);
1045 YES_IF_CHANGED_STRING(BridgeDistribution);
1046 YES_IF_CHANGED_LINELIST(MyFamily);
1047 YES_IF_CHANGED_STRING(AccountingStart);
1048 YES_IF_CHANGED_INT(AccountingMax);
1049 YES_IF_CHANGED_INT(AccountingRule);
1050 YES_IF_CHANGED_BOOL(DirCache);
1051 YES_IF_CHANGED_BOOL(AssumeReachable);
1053 if (relay_get_effective_bwrate(old_options) !=
1054 relay_get_effective_bwrate(new_options) ||
1055 relay_get_effective_bwburst(old_options) !=
1056 relay_get_effective_bwburst(new_options) ||
1057 public_server_mode(old_options) != public_server_mode(new_options))
1058 return 1;
1060 return 0;
1063 /** Fetch the active option list, and take relay actions based on it. All of
1064 * the things we do should survive being done repeatedly. If present,
1065 * <b>old_options</b> contains the previous value of the options.
1067 * Return 0 if all goes well, return -1 if it's time to die.
1069 * Note: We haven't moved all the "act on new configuration" logic
1070 * into the options_act* functions yet. Some is still in do_hup() and other
1071 * places.
1074 options_act_relay(const or_options_t *old_options)
1076 const or_options_t *options = get_options();
1078 const int transition_affects_workers =
1079 old_options && options_transition_affects_workers(old_options, options);
1081 /* We want to reinit keys as needed before we do much of anything else:
1082 keys are important, and other things can depend on them. */
1083 if (transition_affects_workers ||
1084 (authdir_mode_v3(options) && (!old_options ||
1085 !authdir_mode_v3(old_options)))) {
1086 if (init_keys() < 0) {
1087 log_warn(LD_BUG,"Error initializing keys; exiting");
1088 return -1;
1092 if (server_mode(options)) {
1093 static int cdm_initialized = 0;
1094 if (cdm_initialized == 0) {
1095 cdm_initialized = 1;
1096 consdiffmgr_configure(NULL);
1097 consdiffmgr_validate();
1101 /* Check for transitions that need action. */
1102 if (old_options) {
1103 if (transition_affects_workers) {
1104 log_info(LD_GENERAL,
1105 "Worker-related options changed. Rotating workers.");
1106 const int server_mode_turned_on =
1107 server_mode(options) && !server_mode(old_options);
1108 const int dir_server_mode_turned_on =
1109 dir_server_mode(options) && !dir_server_mode(old_options);
1111 if (server_mode_turned_on || dir_server_mode_turned_on) {
1112 cpu_init();
1115 if (server_mode_turned_on) {
1116 ip_address_changed(0);
1117 if (have_completed_a_circuit() || !any_predicted_circuits(time(NULL)))
1118 inform_testing_reachability();
1120 cpuworkers_rotate_keyinfo();
1124 return 0;
1127 /** Fetch the active option list, and take relay accounting actions based on
1128 * it. All of the things we do should survive being done repeatedly. If
1129 * present, <b>old_options</b> contains the previous value of the options.
1131 * Return 0 if all goes well, return -1 if it's time to die.
1133 * Note: We haven't moved all the "act on new configuration" logic
1134 * into the options_act* functions yet. Some is still in do_hup() and other
1135 * places.
1138 options_act_relay_accounting(const or_options_t *old_options)
1140 (void)old_options;
1142 const or_options_t *options = get_options();
1144 /* Set up accounting */
1145 if (accounting_parse_options(options, 0)<0) {
1146 // LCOV_EXCL_START
1147 log_warn(LD_BUG,"Error in previously validated accounting options");
1148 return -1;
1149 // LCOV_EXCL_STOP
1151 if (accounting_is_enabled(options))
1152 configure_accounting(time(NULL));
1154 return 0;
1157 /** Fetch the active option list, and take relay bandwidth actions based on
1158 * it. All of the things we do should survive being done repeatedly. If
1159 * present, <b>old_options</b> contains the previous value of the options.
1161 * Return 0 if all goes well, return -1 if it's time to die.
1163 * Note: We haven't moved all the "act on new configuration" logic
1164 * into the options_act* functions yet. Some is still in do_hup() and other
1165 * places.
1168 options_act_relay_bandwidth(const or_options_t *old_options)
1170 const or_options_t *options = get_options();
1172 /* Check for transitions that need action. */
1173 if (old_options) {
1174 if (options->PerConnBWRate != old_options->PerConnBWRate ||
1175 options->PerConnBWBurst != old_options->PerConnBWBurst)
1176 connection_or_update_token_buckets(get_connection_array(), options);
1178 if (options->RelayBandwidthRate != old_options->RelayBandwidthRate ||
1179 options->RelayBandwidthBurst != old_options->RelayBandwidthBurst)
1180 connection_bucket_adjust(options);
1183 return 0;
1186 /** Fetch the active option list, and take bridge statistics actions based on
1187 * it. All of the things we do should survive being done repeatedly. If
1188 * present, <b>old_options</b> contains the previous value of the options.
1190 * Return 0 if all goes well, return -1 if it's time to die.
1192 * Note: We haven't moved all the "act on new configuration" logic
1193 * into the options_act* functions yet. Some is still in do_hup() and other
1194 * places.
1197 options_act_bridge_stats(const or_options_t *old_options)
1199 const or_options_t *options = get_options();
1201 /* How long should we delay counting bridge stats after becoming a bridge?
1202 * We use this so we don't count clients who used our bridge thinking it is
1203 * a relay. If you change this, don't forget to change the log message
1204 * below. It's 4 hours (the time it takes to stop being used by clients)
1205 * plus some extra time for clock skew. */
1206 #define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
1208 /* Check for transitions that need action. */
1209 if (old_options) {
1210 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1211 int was_relay = 0;
1212 if (options->BridgeRelay) {
1213 time_t int_start = time(NULL);
1214 if (config_lines_eq(old_options->ORPort_lines,options->ORPort_lines)) {
1215 int_start += RELAY_BRIDGE_STATS_DELAY;
1216 was_relay = 1;
1218 geoip_bridge_stats_init(int_start);
1219 log_info(LD_CONFIG, "We are acting as a bridge now. Starting new "
1220 "GeoIP stats interval%s.", was_relay ? " in 6 "
1221 "hours from now" : "");
1222 } else {
1223 geoip_bridge_stats_term();
1224 log_info(LD_GENERAL, "We are no longer acting as a bridge. "
1225 "Forgetting GeoIP stats.");
1230 return 0;
1233 /** Fetch the active option list, and take relay statistics actions based on
1234 * it. All of the things we do should survive being done repeatedly. If
1235 * present, <b>old_options</b> contains the previous value of the options.
1237 * Sets <b>*print_notice_out</b> if we enabled stats, and need to print
1238 * a stats log using options_act_relay_stats_msg().
1240 * If loading the GeoIP file failed, sets DirReqStatistics and
1241 * EntryStatistics to 0. This breaks the normalization/act ordering
1242 * introduced in 29211.
1244 * Return 0 if all goes well, return -1 if it's time to die.
1246 * Note: We haven't moved all the "act on new configuration" logic
1247 * into the options_act* functions yet. Some is still in do_hup() and other
1248 * places.
1251 options_act_relay_stats(const or_options_t *old_options,
1252 bool *print_notice_out)
1254 if (BUG(!print_notice_out))
1255 return -1;
1257 or_options_t *options = get_options_mutable();
1259 if (options->CellStatistics || options->DirReqStatistics ||
1260 options->EntryStatistics || options->ExitPortStatistics ||
1261 options->ConnDirectionStatistics ||
1262 options->HiddenServiceStatistics) {
1263 time_t now = time(NULL);
1264 int print_notice = 0;
1266 if ((!old_options || !old_options->CellStatistics) &&
1267 options->CellStatistics) {
1268 rep_hist_buffer_stats_init(now);
1269 print_notice = 1;
1271 if ((!old_options || !old_options->DirReqStatistics) &&
1272 options->DirReqStatistics) {
1273 if (geoip_is_loaded(AF_INET)) {
1274 geoip_dirreq_stats_init(now);
1275 print_notice = 1;
1276 } else {
1277 /* disable statistics collection since we have no geoip file */
1278 /* 29211: refactor to avoid the normalisation/act inversion */
1279 options->DirReqStatistics = 0;
1280 if (options->ORPort_set)
1281 log_notice(LD_CONFIG, "Configured to measure directory request "
1282 "statistics, but no GeoIP database found. "
1283 "Please specify a GeoIP database using the "
1284 "GeoIPFile option.");
1287 if ((!old_options || !old_options->EntryStatistics) &&
1288 options->EntryStatistics && !should_record_bridge_info(options)) {
1289 /* If we get here, we've started recording bridge info when we didn't
1290 * do so before. Note that "should_record_bridge_info()" will
1291 * always be false at this point, because of the earlier block
1292 * that cleared EntryStatistics when public_server_mode() was false.
1293 * We're leaving it in as defensive programming. */
1294 if (geoip_is_loaded(AF_INET) || geoip_is_loaded(AF_INET6)) {
1295 geoip_entry_stats_init(now);
1296 print_notice = 1;
1297 } else {
1298 options->EntryStatistics = 0;
1299 log_notice(LD_CONFIG, "Configured to measure entry node "
1300 "statistics, but no GeoIP database found. "
1301 "Please specify a GeoIP database using the "
1302 "GeoIPFile option.");
1305 if ((!old_options || !old_options->ExitPortStatistics) &&
1306 options->ExitPortStatistics) {
1307 rep_hist_exit_stats_init(now);
1308 print_notice = 1;
1310 if ((!old_options || !old_options->ConnDirectionStatistics) &&
1311 options->ConnDirectionStatistics) {
1312 rep_hist_conn_stats_init(now);
1314 if ((!old_options || !old_options->HiddenServiceStatistics) &&
1315 options->HiddenServiceStatistics) {
1316 log_info(LD_CONFIG, "Configured to measure hidden service statistics.");
1317 rep_hist_hs_stats_init(now);
1319 if (print_notice)
1320 *print_notice_out = 1;
1323 /* If we used to have statistics enabled but we just disabled them,
1324 stop gathering them. */
1325 if (old_options && old_options->CellStatistics &&
1326 !options->CellStatistics)
1327 rep_hist_buffer_stats_term();
1328 if (old_options && old_options->DirReqStatistics &&
1329 !options->DirReqStatistics)
1330 geoip_dirreq_stats_term();
1331 if (old_options && old_options->EntryStatistics &&
1332 !options->EntryStatistics)
1333 geoip_entry_stats_term();
1334 if (old_options && old_options->HiddenServiceStatistics &&
1335 !options->HiddenServiceStatistics)
1336 rep_hist_hs_stats_term();
1337 if (old_options && old_options->ExitPortStatistics &&
1338 !options->ExitPortStatistics)
1339 rep_hist_exit_stats_term();
1340 if (old_options && old_options->ConnDirectionStatistics &&
1341 !options->ConnDirectionStatistics)
1342 rep_hist_conn_stats_term();
1344 return 0;
1347 /** Print a notice about relay/dirauth stats being enabled. */
1348 void
1349 options_act_relay_stats_msg(void)
1351 log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
1352 "the *-stats files that will first be written to the "
1353 "data directory in 24 hours from now.");
1356 /** Fetch the active option list, and take relay descriptor actions based on
1357 * it. All of the things we do should survive being done repeatedly. If
1358 * present, <b>old_options</b> contains the previous value of the options.
1360 * Return 0 if all goes well, return -1 if it's time to die.
1362 * Note: We haven't moved all the "act on new configuration" logic
1363 * into the options_act* functions yet. Some is still in do_hup() and other
1364 * places.
1367 options_act_relay_desc(const or_options_t *old_options)
1369 const or_options_t *options = get_options();
1371 /* Since our options changed, we might need to regenerate and upload our
1372 * server descriptor.
1374 if (!old_options ||
1375 options_transition_affects_descriptor(old_options, options))
1376 mark_my_descriptor_dirty("config change");
1378 return 0;
1381 /** Fetch the active option list, and take relay DoS actions based on
1382 * it. All of the things we do should survive being done repeatedly. If
1383 * present, <b>old_options</b> contains the previous value of the options.
1385 * Return 0 if all goes well, return -1 if it's time to die.
1387 * Note: We haven't moved all the "act on new configuration" logic
1388 * into the options_act* functions yet. Some is still in do_hup() and other
1389 * places.
1392 options_act_relay_dos(const or_options_t *old_options)
1394 const or_options_t *options = get_options();
1396 /* DoS mitigation subsystem only applies to public relay. */
1397 if (public_server_mode(options)) {
1398 /* If we are configured as a relay, initialize the subsystem. Even on HUP,
1399 * this is safe to call as it will load data from the current options
1400 * or/and the consensus. */
1401 dos_init();
1402 } else if (old_options && public_server_mode(old_options)) {
1403 /* Going from relay to non relay, clean it up. */
1404 dos_free_all();
1407 return 0;
1410 /** Fetch the active option list, and take dirport actions based on
1411 * it. All of the things we do should survive being done repeatedly. If
1412 * present, <b>old_options</b> contains the previous value of the options.
1414 * Return 0 if all goes well, return -1 if it's time to die.
1416 * Note: We haven't moved all the "act on new configuration" logic
1417 * into the options_act* functions yet. Some is still in do_hup() and other
1418 * places.
1421 options_act_relay_dir(const or_options_t *old_options)
1423 (void)old_options;
1425 const or_options_t *options = get_options();
1427 if (!public_server_mode(options))
1428 return 0;
1430 /* Load the webpage we're going to serve every time someone asks for '/' on
1431 our DirPort. */
1432 tor_free(global_dirfrontpagecontents);
1433 if (options->DirPortFrontPage) {
1434 global_dirfrontpagecontents =
1435 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1436 if (!global_dirfrontpagecontents) {
1437 log_warn(LD_CONFIG,
1438 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1439 options->DirPortFrontPage);
1443 return 0;