LCOV - code coverage report
Current view: top level - feature/relay - relay_config.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 487 661 73.7 %
Date: 2021-11-24 03:28:48 Functions: 28 35 80.0 %

          Line data    Source code
       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-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * @file relay_config.c
       9             :  * @brief Code to interpret the user's configuration of Tor's relay module.
      10             :  **/
      11             : 
      12             : #include "orconfig.h"
      13             : #define RELAY_CONFIG_PRIVATE
      14             : #include "feature/relay/relay_config.h"
      15             : 
      16             : #include "lib/encoding/confline.h"
      17             : #include "lib/confmgt/confmgt.h"
      18             : 
      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"
      24             : 
      25             : /* Required for dirinfo_type_t in or_options_t */
      26             : #include "core/or/or.h"
      27             : #include "app/config/config.h"
      28             : 
      29             : #include "core/mainloop/connection.h"
      30             : #include "core/mainloop/cpuworker.h"
      31             : #include "core/mainloop/mainloop.h"
      32             : #include "core/or/connection_or.h"
      33             : #include "core/or/port_cfg_st.h"
      34             : 
      35             : #include "feature/hibernate/hibernate.h"
      36             : #include "feature/nodelist/nickname.h"
      37             : #include "feature/stats/geoip_stats.h"
      38             : #include "feature/stats/predict_ports.h"
      39             : #include "feature/stats/connstats.h"
      40             : #include "feature/stats/rephist.h"
      41             : 
      42             : #include "feature/dirauth/authmode.h"
      43             : 
      44             : #include "feature/dircache/consdiffmgr.h"
      45             : #include "feature/relay/dns.h"
      46             : #include "feature/relay/routermode.h"
      47             : #include "feature/relay/selftest.h"
      48             : 
      49             : /** Contents of most recently read DirPortFrontPage file. */
      50             : static char *global_dirfrontpagecontents = NULL;
      51             : 
      52             : /* Copied from config.c, we will refactor later in 29211. */
      53             : #define REJECT(arg) \
      54             :   STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
      55             : #if defined(__GNUC__) && __GNUC__ <= 3
      56             : #define COMPLAIN(args...) \
      57             :   STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END
      58             : #else
      59             : #define COMPLAIN(args, ...)                                     \
      60             :   STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
      61             : #endif /* defined(__GNUC__) && __GNUC__ <= 3 */
      62             : 
      63             : /* Used in the various options_transition_affects* functions. */
      64             : #define YES_IF_CHANGED_BOOL(opt) \
      65             :   if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1;
      66             : #define YES_IF_CHANGED_INT(opt) \
      67             :   if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
      68             : #define YES_IF_CHANGED_STRING(opt) \
      69             :   if (!CFG_EQ_STRING(old_options, new_options, opt)) return 1;
      70             : #define YES_IF_CHANGED_LINELIST(opt) \
      71             :   if (!CFG_EQ_LINELIST(old_options, new_options, opt)) return 1;
      72             : 
      73             : /** Return the contents of our frontpage string, or NULL if not configured. */
      74           2 : MOCK_IMPL(const char*,
      75             : relay_get_dirportfrontpage, (void))
      76             : {
      77           2 :   return global_dirfrontpagecontents;
      78             : }
      79             : 
      80             : /** Release all memory and resources held by global relay configuration
      81             :  * structures.
      82             :  */
      83             : void
      84         235 : relay_config_free_all(void)
      85             : {
      86         235 :   tor_free(global_dirfrontpagecontents);
      87         235 : }
      88             : 
      89             : /** Return the bandwidthrate that we are going to report to the authorities
      90             :  * based on the config options. */
      91             : uint32_t
      92           0 : relay_get_effective_bwrate(const or_options_t *options)
      93             : {
      94           0 :   uint64_t bw = options->BandwidthRate;
      95           0 :   if (bw > options->MaxAdvertisedBandwidth)
      96             :     bw = options->MaxAdvertisedBandwidth;
      97           0 :   if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
      98             :     bw = options->RelayBandwidthRate;
      99             :   /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */
     100           0 :   return (uint32_t)bw;
     101             : }
     102             : 
     103             : /** Return the bandwidthburst that we are going to report to the authorities
     104             :  * based on the config options. */
     105             : uint32_t
     106           0 : relay_get_effective_bwburst(const or_options_t *options)
     107             : {
     108           0 :   uint64_t bw = options->BandwidthBurst;
     109           0 :   if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
     110             :     bw = options->RelayBandwidthBurst;
     111             :   /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */
     112           0 :   return (uint32_t)bw;
     113             : }
     114             : 
     115             : /** Warn for every Extended ORPort port in <b>ports</b> that is on a
     116             :  *  publicly routable address. */
     117             : void
     118          14 : port_warn_nonlocal_ext_orports(const smartlist_t *ports, const char *portname)
     119             : {
     120          42 :   SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
     121          28 :     if (port->type != CONN_TYPE_EXT_OR_LISTENER)
     122          14 :       continue;
     123          14 :     if (port->is_unix_addr)
     124           0 :       continue;
     125             :     /* XXX maybe warn even if address is RFC1918? */
     126          14 :     if (!tor_addr_is_internal(&port->addr, 1)) {
     127           3 :       log_warn(LD_CONFIG, "You specified a public address '%s' for %sPort. "
     128             :                "This is not advised; this address is supposed to only be "
     129             :                "exposed on localhost so that your pluggable transport "
     130             :                "proxies can connect to it.",
     131             :                fmt_addrport(&port->addr, port->port), portname);
     132             :     }
     133          28 :   } SMARTLIST_FOREACH_END(port);
     134          14 : }
     135             : 
     136             : /**
     137             :  * Return a static buffer describing the port number in @a port, which may
     138             :  * CFG_AUTO_PORT.
     139             :  **/
     140             : static const char *
     141          18 : describe_portnum(int port)
     142             : {
     143          18 :   static char buf[16];
     144          18 :   if (port == CFG_AUTO_PORT) {
     145             :     return "auto";
     146             :   } else {
     147          12 :     tor_snprintf(buf, sizeof(buf), "%d", port);
     148          12 :     return buf;
     149             :   }
     150             : }
     151             : 
     152             : /** Return a static buffer containing the human readable logging string that
     153             :  * describes the given port object. */
     154             : STATIC const char *
     155          18 : describe_relay_port(const port_cfg_t *port)
     156             : {
     157          18 :   IF_BUG_ONCE(!port) {
     158             :     return "<null port>";
     159             :   }
     160             : 
     161          18 :   static char buf[256];
     162          18 :   const char *type, *addr;
     163             : 
     164          18 :   switch (port->type) {
     165             :   case CONN_TYPE_OR_LISTENER:
     166             :     type = "OR";
     167             :     break;
     168           0 :   case CONN_TYPE_DIR_LISTENER:
     169           0 :     type = "Dir";
     170           0 :     break;
     171           0 :   case CONN_TYPE_EXT_OR_LISTENER:
     172           0 :     type = "ExtOR";
     173           0 :     break;
     174           0 :   default:
     175           0 :     type = "";
     176           0 :     break;
     177             :   }
     178             : 
     179          18 :   if (port->explicit_addr) {
     180           6 :     addr = fmt_and_decorate_addr(&port->addr);
     181             :   } else {
     182             :     addr = "";
     183             :   }
     184             : 
     185          54 :   tor_snprintf(buf, sizeof(buf), "%sPort %s%s%s",
     186          18 :                type, addr, (strlen(addr) > 0) ? ":" : "",
     187          18 :                describe_portnum(port->port));
     188          18 :   return buf;
     189             : }
     190             : 
     191             : /** Return true iff port p1 is equal to p2.
     192             :  *
     193             :  * This does a field by field comparaison. */
     194             : static bool
     195         566 : port_cfg_eq(const port_cfg_t *p1, const port_cfg_t *p2)
     196             : {
     197         566 :   bool ret = true;
     198             : 
     199         566 :   tor_assert(p1);
     200         566 :   tor_assert(p2);
     201             : 
     202             :   /* Address, port and type. */
     203         566 :   ret &= tor_addr_eq(&p1->addr, &p2->addr);
     204         566 :   ret &= (p1->port == p2->port);
     205         566 :   ret &= (p1->type == p2->type);
     206             : 
     207             :   /* Mode. */
     208         566 :   ret &= (p1->is_unix_addr == p2->is_unix_addr);
     209         566 :   ret &= (p1->is_group_writable == p2->is_group_writable);
     210         566 :   ret &= (p1->is_world_writable == p2->is_world_writable);
     211         566 :   ret &= (p1->relax_dirmode_check == p2->relax_dirmode_check);
     212         566 :   ret &= (p1->explicit_addr == p2->explicit_addr);
     213             : 
     214             :   /* Entry config flags. */
     215         566 :   ret &= tor_memeq(&p1->entry_cfg, &p2->entry_cfg,
     216             :                     sizeof(entry_port_cfg_t));
     217             :   /* Server config flags. */
     218         566 :   ret &= tor_memeq(&p1->server_cfg, &p2->server_cfg,
     219             :                     sizeof(server_port_cfg_t));
     220             :   /* Unix address path if any. */
     221         566 :   ret &= !strcmp(p1->unix_addr, p2->unix_addr);
     222             : 
     223         566 :   return ret;
     224             : }
     225             : 
     226             : /** Attempt to find duplicate ORPort that would be superseded by another and
     227             :  * remove them from the given ports list. This is possible if we have for
     228             :  * instance:
     229             :  *
     230             :  *    ORPort 9050
     231             :  *    ORPort [4242::1]:9050
     232             :  *
     233             :  * First one binds to both v4 and v6 address but second one is specific to an
     234             :  * address superseding the global bind one.
     235             :  *
     236             :  * Another example is this one:
     237             :  *
     238             :  *    ORPort 9001
     239             :  *    ORPort [4242::1]:9002
     240             :  *    ORPort [4242::2]:9003
     241             :  *
     242             :  * In this case, all IPv4 and IPv6 are kept since we do allow multiple ORPorts
     243             :  * but the published port will be the first explicit one if any to be
     244             :  * published or else the implicit.
     245             :  *
     246             :  * The following is O(n^2) but it is done at bootstrap or config reload and
     247             :  * the list is not very long usually. */
     248             : STATIC void
     249         583 : remove_duplicate_orports(smartlist_t *ports)
     250             : {
     251             :   /* First we'll decide what to remove, then we'll remove it. */
     252         583 :   bool *removing = tor_calloc(smartlist_len(ports), sizeof(bool));
     253             : 
     254        1174 :   for (int i = 0; i < smartlist_len(ports); ++i) {
     255         591 :     const port_cfg_t *current = smartlist_get(ports, i);
     256         591 :     if (removing[i]) {
     257          64 :       continue;
     258             :     }
     259             : 
     260             :     /* Skip non ORPorts. */
     261         527 :     if (current->type != CONN_TYPE_OR_LISTENER) {
     262          99 :       continue;
     263             :     }
     264             : 
     265        1608 :     for (int j = 0; j < smartlist_len(ports); ++j) {
     266        1180 :       const port_cfg_t *next = smartlist_get(ports, j);
     267             : 
     268             :       /* Avoid comparing the same object. */
     269        1180 :       if (current == next) {
     270         428 :         continue;
     271             :       }
     272         752 :       if (removing[j]) {
     273          22 :         continue;
     274             :       }
     275             :       /* Skip non ORPorts. */
     276         730 :       if (next->type != CONN_TYPE_OR_LISTENER) {
     277         164 :         continue;
     278             :       }
     279             :       /* Remove duplicates. */
     280         566 :       if (port_cfg_eq(current, next)) {
     281          60 :         removing[j] = true;
     282          60 :         continue;
     283             :       }
     284             :       /* Don't compare addresses of different family. */
     285         506 :       if (tor_addr_family(&current->addr) != tor_addr_family(&next->addr)) {
     286         461 :         continue;
     287             :       }
     288             :       /* At this point, we have a port of the same type and same address
     289             :        * family. Now, we want to avoid comparing addresses that are different
     290             :        * but are both explicit. As an example, these are not duplicates:
     291             :        *
     292             :        *    ORPort 127.0.0.:9001 NoAdvertise
     293             :        *    ORPort 1.2.3.4:9001 NoListen
     294             :        *
     295             :        * Any implicit address must be considered for removal since an explicit
     296             :        * one will always supersedes it. */
     297          45 :       if (!tor_addr_eq(&current->addr, &next->addr) &&
     298          14 :           current->explicit_addr && next->explicit_addr) {
     299           9 :         continue;
     300             :       }
     301             : 
     302             :       /* Port value is the same so we either have a duplicate or a port that
     303             :        * supersedes another. */
     304          36 :       if (current->port == next->port) {
     305             :         /* Do not remove the explicit address. As stated before above, we keep
     306             :          * explicit addresses which supersedes implicit ones. */
     307           4 :         if (!current->explicit_addr && next->explicit_addr) {
     308           0 :           continue;
     309             :         }
     310           4 :         removing[j] = true;
     311           4 :         char *next_str = tor_strdup(describe_relay_port(next));
     312           4 :         log_warn(LD_CONFIG, "Configuration port %s superseded by %s",
     313             :                  next_str, describe_relay_port(current));
     314           4 :         tor_free(next_str);
     315             :       }
     316             :     }
     317             :   }
     318             : 
     319             :   /* Iterate over array in reverse order to keep indices valid. */
     320        1174 :   for (int i = smartlist_len(ports)-1; i >= 0; --i) {
     321         591 :     tor_assert(i < smartlist_len(ports));
     322         591 :     if (removing[i]) {
     323          64 :       port_cfg_t *current = smartlist_get(ports, i);
     324          64 :       smartlist_del_keeporder(ports, i);
     325          64 :       port_cfg_free(current);
     326             :     }
     327             :   }
     328             : 
     329         583 :   tor_free(removing);
     330         583 : }
     331             : 
     332             : /** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal
     333             :  * consistency and warn as appropriate.  On Unix-based OSes, set
     334             :  * *<b>n_low_ports_out</b> to the number of sub-1024 ports we will be
     335             :  * binding, and warn if we may be unable to re-bind after hibernation. */
     336             : static int
     337         580 : check_and_prune_server_ports(smartlist_t *ports,
     338             :                    const or_options_t *options,
     339             :                    int *n_low_ports_out)
     340             : {
     341         580 :   if (BUG(!ports))
     342           0 :     return -1;
     343             : 
     344         580 :   if (BUG(!options))
     345           0 :     return -1;
     346             : 
     347         580 :   if (BUG(!n_low_ports_out))
     348           0 :     return -1;
     349             : 
     350         580 :   int n_orport_advertised = 0;
     351         580 :   int n_orport_advertised_ipv4 = 0;
     352         580 :   int n_orport_listeners = 0;
     353         580 :   int n_dirport_advertised = 0;
     354         580 :   int n_dirport_listeners = 0;
     355         580 :   int n_low_port = 0;
     356         580 :   int r = 0;
     357             : 
     358             :   /* Remove possible duplicate ORPorts before inspecting the list. */
     359         580 :   remove_duplicate_orports(ports);
     360             : 
     361        1097 :   SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
     362         517 :     if (port->type == CONN_TYPE_DIR_LISTENER) {
     363          86 :       if (! port->server_cfg.no_advertise)
     364          83 :         ++n_dirport_advertised;
     365          86 :       if (! port->server_cfg.no_listen)
     366          85 :         ++n_dirport_listeners;
     367         431 :     } else if (port->type == CONN_TYPE_OR_LISTENER) {
     368         418 :       if (! port->server_cfg.no_advertise) {
     369         415 :         ++n_orport_advertised;
     370         415 :         if (port_binds_ipv4(port))
     371         218 :           ++n_orport_advertised_ipv4;
     372             :       }
     373         418 :       if (! port->server_cfg.no_listen)
     374         415 :         ++n_orport_listeners;
     375             :     } else {
     376          13 :       continue;
     377             :     }
     378             : #ifndef _WIN32
     379         504 :     if (!port->server_cfg.no_listen && port->port < 1024)
     380         147 :       ++n_low_port;
     381             : #endif
     382         517 :   } SMARTLIST_FOREACH_END(port);
     383             : 
     384         580 :   if (n_orport_advertised && !n_orport_listeners) {
     385           1 :     log_warn(LD_CONFIG, "We are advertising an ORPort, but not actually "
     386             :              "listening on one.");
     387           1 :     r = -1;
     388             :   }
     389         580 :   if (n_orport_listeners && !n_orport_advertised) {
     390           1 :     log_warn(LD_CONFIG, "We are listening on an ORPort, but not advertising "
     391             :              "any ORPorts. This will keep us from building a %s "
     392             :              "descriptor, and make us impossible to use.",
     393             :              options->BridgeRelay ? "bridge" : "router");
     394           1 :     r = -1;
     395             :   }
     396         580 :   if (n_dirport_advertised && !n_dirport_listeners) {
     397           1 :     log_warn(LD_CONFIG, "We are advertising a DirPort, but not actually "
     398             :              "listening on one.");
     399           1 :     r = -1;
     400             :   }
     401         580 :   if (n_dirport_advertised > 1) {
     402           1 :     log_warn(LD_CONFIG, "Can't advertise more than one DirPort.");
     403           1 :     r = -1;
     404             :   }
     405         580 :   if (n_orport_advertised && !n_orport_advertised_ipv4 &&
     406           1 :       !options->BridgeRelay) {
     407           1 :     log_warn(LD_CONFIG, "Configured public relay to listen only on an IPv6 "
     408             :              "address. Tor needs to listen on an IPv4 address too.");
     409           1 :     r = -1;
     410             :   }
     411             : 
     412         583 :   if (n_low_port && options->AccountingMax &&
     413           6 :       (!have_capability_support() || options->KeepBindCapabilities == 0)) {
     414           3 :     const char *extra = "";
     415           3 :     if (options->KeepBindCapabilities == 0 && have_capability_support())
     416           3 :       extra = ", and you have disabled KeepBindCapabilities.";
     417           3 :     log_warn(LD_CONFIG,
     418             :           "You have set AccountingMax to use hibernation. You have also "
     419             :           "chosen a low DirPort or OrPort%s."
     420             :           "This combination can make Tor stop "
     421             :           "working when it tries to re-attach the port after a period of "
     422             :           "hibernation. Please choose a different port or turn off "
     423             :           "hibernation unless you know this combination will work on your "
     424             :           "platform.", extra);
     425             :   }
     426             : 
     427         580 :   if (n_low_ports_out)
     428         580 :     *n_low_ports_out = n_low_port;
     429             : 
     430         580 :   return r;
     431             : }
     432             : 
     433             : /** Parse all relay ports from <b>options</b>. On success, add parsed ports to
     434             :  * <b>ports</b>, and return 0.  On failure, set *<b>msg</b> to a newly
     435             :  * allocated string describing the problem, and return -1.
     436             :  **/
     437             : int
     438         588 : port_parse_ports_relay(or_options_t *options,
     439             :                   char **msg,
     440             :                   smartlist_t *ports_out,
     441             :                   int *have_low_ports_out)
     442             : {
     443         588 :   int retval = -1;
     444         588 :   smartlist_t *ports = smartlist_new();
     445         588 :   int n_low_ports = 0;
     446             : 
     447         588 :   if (BUG(!options))
     448           0 :     goto err;
     449             : 
     450         588 :   if (BUG(!msg))
     451           0 :     goto err;
     452             : 
     453         588 :   if (BUG(!ports_out))
     454           0 :     goto err;
     455             : 
     456         588 :   if (BUG(!have_low_ports_out))
     457           0 :     goto err;
     458             : 
     459         588 :   if (options->ClientOnly) {
     460           3 :     retval = 0;
     461           3 :     goto err;
     462             :   }
     463             : 
     464         585 :   if (port_parse_config(ports,
     465         585 :                         options->ORPort_lines,
     466             :                         "OR", CONN_TYPE_OR_LISTENER,
     467             :                         "0.0.0.0", 0,
     468             :                         CL_PORT_SERVER_OPTIONS) < 0) {
     469           1 :     *msg = tor_strdup("Invalid ORPort configuration");
     470           1 :     goto err;
     471             :   }
     472         584 :   if (port_parse_config(ports,
     473         584 :                         options->ORPort_lines,
     474             :                         "OR", CONN_TYPE_OR_LISTENER,
     475             :                         "[::]", 0,
     476             :                         CL_PORT_SERVER_OPTIONS) < 0) {
     477           0 :     *msg = tor_strdup("Invalid ORPort configuration");
     478           0 :     goto err;
     479             :   }
     480         584 :   if (port_parse_config(ports,
     481         584 :                         options->ExtORPort_lines,
     482             :                         "ExtOR", CONN_TYPE_EXT_OR_LISTENER,
     483             :                         "127.0.0.1", 0,
     484             :                         CL_PORT_SERVER_OPTIONS|CL_PORT_WARN_NONLOCAL) < 0) {
     485           3 :     *msg = tor_strdup("Invalid ExtORPort configuration");
     486           3 :     goto err;
     487             :   }
     488         581 :   if (port_parse_config(ports,
     489         581 :                         options->DirPort_lines,
     490             :                         "Dir", CONN_TYPE_DIR_LISTENER,
     491             :                         "0.0.0.0", 0,
     492             :                         CL_PORT_SERVER_OPTIONS) < 0) {
     493           1 :     *msg = tor_strdup("Invalid DirPort configuration");
     494           1 :     goto err;
     495             :   }
     496             : 
     497         580 :   if (check_and_prune_server_ports(ports, options, &n_low_ports) < 0) {
     498           5 :     *msg = tor_strdup("Misconfigured server ports");
     499           5 :     goto err;
     500             :   }
     501             : 
     502         575 :   smartlist_add_all(ports_out, ports);
     503         575 :   smartlist_free(ports);
     504         575 :   ports = NULL;
     505         575 :   retval = 0;
     506             : 
     507         588 :  err:
     508         588 :   if (*have_low_ports_out < 0)
     509         275 :     *have_low_ports_out = (n_low_ports > 0);
     510         588 :   if (ports) {
     511          21 :     SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p));
     512          13 :     smartlist_free(ports);
     513             :   }
     514         588 :   return retval;
     515             : }
     516             : 
     517             : /** Update the relay *Port_set values in <b>options</b> from <b>ports</b>. */
     518             : void
     519         578 : port_update_port_set_relay(or_options_t *options,
     520             :                       const smartlist_t *ports)
     521             : {
     522         578 :   if (BUG(!options))
     523           0 :     return;
     524             : 
     525         578 :   if (BUG(!ports))
     526           0 :     return;
     527             : 
     528         578 :   if (options->ClientOnly)
     529             :     return;
     530             : 
     531             :   /* Update the relay *Port_set options.  The !! here is to force a boolean
     532             :    * out of an integer. */
     533        1150 :   options->ORPort_set =
     534         575 :     !! port_count_real_listeners(ports, CONN_TYPE_OR_LISTENER, 0);
     535        1150 :   options->DirPort_set =
     536         575 :     !! port_count_real_listeners(ports, CONN_TYPE_DIR_LISTENER, 0);
     537        1150 :   options->ExtORPort_set =
     538         575 :     !! port_count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER, 0);
     539             : }
     540             : 
     541             : /**
     542             :  * Legacy validation function, which checks that the current OS is usable in
     543             :  * relay mode, if options is set to a relay mode.
     544             :  *
     545             :  * Warns about OSes with potential issues. Does not set *<b>msg</b>.
     546             :  * Always returns 0.
     547             :  */
     548             : int
     549         565 : options_validate_relay_os(const or_options_t *old_options,
     550             :                           or_options_t *options,
     551             :                           char **msg)
     552             : {
     553         565 :   (void)old_options;
     554             : 
     555         565 :   if (BUG(!options))
     556           0 :     return -1;
     557             : 
     558         565 :   if (BUG(!msg))
     559           0 :     return -1;
     560             : 
     561         565 :   if (!server_mode(options))
     562             :     return 0;
     563             : 
     564         199 :   const char *uname = get_uname();
     565             : 
     566         397 :   if (!strcmpstart(uname, "Windows 95") ||
     567         395 :       !strcmpstart(uname, "Windows 98") ||
     568         197 :       !strcmpstart(uname, "Windows Me")) {
     569           3 :     log_warn(LD_CONFIG, "Tor is running as a server, but you are "
     570             :         "running %s; this probably won't work. See "
     571             :         "https://www.torproject.org/docs/faq.html#BestOSForRelay "
     572             :         "for details.", uname);
     573             :   }
     574             : 
     575             :   return 0;
     576             : }
     577             : 
     578             : /**
     579             :  * Legacy validation/normalization function for the relay info options.
     580             :  * Uses old_options as the previous options.
     581             :  *
     582             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
     583             :  * on error.
     584             :  */
     585             : int
     586         562 : options_validate_relay_info(const or_options_t *old_options,
     587             :                             or_options_t *options,
     588             :                             char **msg)
     589             : {
     590         562 :   (void)old_options;
     591             : 
     592         562 :   if (BUG(!options))
     593           0 :     return -1;
     594             : 
     595         562 :   if (BUG(!msg))
     596           0 :     return -1;
     597             : 
     598         562 :   if (options->Nickname == NULL) {
     599         519 :     if (server_mode(options)) {
     600         165 :       options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
     601             :     }
     602             :   } else {
     603          43 :     if (!is_legal_nickname(options->Nickname)) {
     604           3 :       tor_asprintf(msg,
     605             :           "Nickname '%s', nicknames must be between 1 and 19 characters "
     606             :           "inclusive, and must contain only the characters [a-zA-Z0-9].",
     607             :           options->Nickname);
     608           3 :       return -1;
     609             :     }
     610             :   }
     611             : 
     612         559 :   if (server_mode(options) && !options->ContactInfo) {
     613         128 :     log_warn(LD_CONFIG,
     614             :              "Your ContactInfo config option is not set. Please strongly "
     615             :              "consider setting it, so we can contact you if your relay is "
     616             :              "misconfigured, end-of-life, or something else goes wrong. "
     617             :              "It is also possible that your relay might get rejected from "
     618             :              "the network due to a missing valid contact address.");
     619             :   }
     620             : 
     621         559 :   const char *ContactInfo = options->ContactInfo;
     622         559 :   if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
     623           1 :     REJECT("ContactInfo config option must be UTF-8.");
     624             : 
     625             :   return 0;
     626             : }
     627             : 
     628             : /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
     629             :  * and write it to <b>options</b>-\>PublishServerDescriptor_. Treat "1"
     630             :  * as "v3" unless BridgeRelay is 1, in which case treat it as "bridge".
     631             :  * Treat "0" as "".
     632             :  * Return 0 on success or -1 if not a recognized authority type (in which
     633             :  * case the value of PublishServerDescriptor_ is undefined). */
     634             : static int
     635         524 : compute_publishserverdescriptor(or_options_t *options)
     636             : {
     637         524 :   smartlist_t *list = options->PublishServerDescriptor;
     638         524 :   dirinfo_type_t *auth = &options->PublishServerDescriptor_;
     639         524 :   *auth = NO_DIRINFO;
     640         524 :   if (!list) /* empty list, answer is none */
     641             :     return 0;
     642        1047 :   SMARTLIST_FOREACH_BEGIN(list, const char *, string) {
     643         528 :     if (!strcasecmp(string, "v1"))
     644           3 :       log_warn(LD_CONFIG, "PublishServerDescriptor v1 has no effect, because "
     645             :                           "there are no v1 directory authorities anymore.");
     646         525 :     else if (!strcmp(string, "1"))
     647         510 :       if (options->BridgeRelay)
     648          13 :         *auth |= BRIDGE_DIRINFO;
     649             :       else
     650         497 :         *auth |= V3_DIRINFO;
     651          15 :     else if (!strcasecmp(string, "v2"))
     652           3 :       log_warn(LD_CONFIG, "PublishServerDescriptor v2 has no effect, because "
     653             :                           "there are no v2 directory authorities anymore.");
     654          12 :     else if (!strcasecmp(string, "v3"))
     655           2 :       *auth |= V3_DIRINFO;
     656          10 :     else if (!strcasecmp(string, "bridge"))
     657           2 :       *auth |= BRIDGE_DIRINFO;
     658           8 :     else if (!strcasecmp(string, "hidserv"))
     659           3 :       log_warn(LD_CONFIG,
     660             :                "PublishServerDescriptor hidserv is invalid. See "
     661             :                "PublishHidServDescriptors.");
     662           5 :     else if (!strcasecmp(string, "") || !strcmp(string, "0"))
     663             :       /* no authority */;
     664             :     else
     665             :       return -1;
     666         526 :   } SMARTLIST_FOREACH_END(string);
     667             :   return 0;
     668             : }
     669             : 
     670             : /**
     671             :  * Validate the configured bridge distribution method from a BridgeDistribution
     672             :  * config line.
     673             :  *
     674             :  * The input <b>bd</b>, is a string taken from the BridgeDistribution config
     675             :  * line (if present).  If the option wasn't set, return 0 immediately.  The
     676             :  * BridgeDistribution option is then validated.  Currently valid, recognised
     677             :  * options are:
     678             :  *
     679             :  * - "none"
     680             :  * - "any"
     681             :  * - "https"
     682             :  * - "email"
     683             :  * - "moat"
     684             :  *
     685             :  * If the option string is unrecognised, a warning will be logged and 0 is
     686             :  * returned.  If the option string contains an invalid character, -1 is
     687             :  * returned.
     688             :  **/
     689             : STATIC int
     690          17 : check_bridge_distribution_setting(const char *bd)
     691             : {
     692          17 :   if (bd == NULL)
     693             :     return 0;
     694             : 
     695          17 :   const char *RECOGNIZED[] = {
     696             :     "none", "any", "https", "email", "moat"
     697             :   };
     698          17 :   unsigned i;
     699          72 :   for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) {
     700          65 :     if (!strcasecmp(bd, RECOGNIZED[i]))
     701             :       return 0;
     702             :   }
     703             : 
     704             :   const char *cp = bd;
     705             :   //  Method = (KeywordChar | "_") +
     706          44 :   while (TOR_ISALNUM(*cp) || *cp == '-' || *cp == '_')
     707          37 :     ++cp;
     708             : 
     709           7 :   if (*cp == 0) {
     710           2 :     log_warn(LD_CONFIG, "Unrecognized BridgeDistribution value %s. I'll "
     711             :            "assume you know what you are doing...", escaped(bd));
     712           2 :     return 0; // we reached the end of the string; all is well
     713             :   } else {
     714             :     return -1; // we found a bad character in the string.
     715             :   }
     716             : }
     717             : 
     718             : /**
     719             :  * Legacy validation/normalization function for the bridge relay options.
     720             :  * Uses old_options as the previous options.
     721             :  *
     722             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
     723             :  * on error.
     724             :  */
     725             : int
     726         524 : options_validate_publish_server(const or_options_t *old_options,
     727             :                                 or_options_t *options,
     728             :                                 char **msg)
     729             : {
     730         524 :   (void)old_options;
     731             : 
     732         524 :   if (BUG(!options))
     733           0 :     return -1;
     734             : 
     735         524 :   if (BUG(!msg))
     736           0 :     return -1;
     737             : 
     738         524 :   if (compute_publishserverdescriptor(options) < 0) {
     739           2 :     tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
     740           2 :     return -1;
     741             :   }
     742             : 
     743         522 :   if ((options->BridgeRelay
     744         508 :         || options->PublishServerDescriptor_ & BRIDGE_DIRINFO)
     745          16 :       && (options->PublishServerDescriptor_ & V3_DIRINFO)) {
     746           2 :     REJECT("Bridges are not supposed to publish router descriptors to the "
     747             :            "directory authorities. Please correct your "
     748             :            "PublishServerDescriptor line.");
     749             :   }
     750             : 
     751         520 :   if (options->BridgeDistribution) {
     752           2 :     if (!options->BridgeRelay) {
     753           1 :       REJECT("You set BridgeDistribution, but you didn't set BridgeRelay!");
     754             :     }
     755           1 :     if (check_bridge_distribution_setting(options->BridgeDistribution) < 0) {
     756           1 :       REJECT("Invalid BridgeDistribution value.");
     757             :     }
     758             :   }
     759             : 
     760         518 :   if (options->PublishServerDescriptor)
     761        1036 :     SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
     762             :       if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
     763             :         if (smartlist_len(options->PublishServerDescriptor) > 1) {
     764             :           COMPLAIN("You have passed a list of multiple arguments to the "
     765             :                    "PublishServerDescriptor option that includes 0 or 1. "
     766             :                    "0 or 1 should only be used as the sole argument. "
     767             :                    "This configuration will be rejected in a future release.");
     768             :           break;
     769             :         }
     770             :     });
     771             : 
     772             :   return 0;
     773             : }
     774             : 
     775             : /**
     776             :  * Legacy validation/normalization function for the relay padding options.
     777             :  * Uses old_options as the previous options.
     778             :  *
     779             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
     780             :  * on error.
     781             :  */
     782             : int
     783         518 : options_validate_relay_padding(const or_options_t *old_options,
     784             :                                or_options_t *options,
     785             :                                char **msg)
     786             : {
     787         518 :   (void)old_options;
     788             : 
     789         518 :   if (BUG(!options))
     790           0 :     return -1;
     791             : 
     792         518 :   if (BUG(!msg))
     793           0 :     return -1;
     794             : 
     795         518 :   if (!server_mode(options))
     796             :     return 0;
     797             : 
     798         188 :   if (options->ConnectionPadding != -1) {
     799           2 :     REJECT("Relays must use 'auto' for the ConnectionPadding setting.");
     800             :   }
     801             : 
     802         186 :   if (options->ReducedConnectionPadding != 0) {
     803           1 :     REJECT("Relays cannot set ReducedConnectionPadding. ");
     804             :   }
     805             : 
     806         185 :   if (options->CircuitPadding == 0) {
     807           1 :     REJECT("Relays cannot set CircuitPadding to 0. ");
     808             :   }
     809             : 
     810         184 :   if (options->ReducedCircuitPadding == 1) {
     811           1 :     REJECT("Relays cannot set ReducedCircuitPadding. ");
     812             :   }
     813             : 
     814             :   return 0;
     815             : }
     816             : 
     817             : /**
     818             :  * Legacy validation/normalization function for the relay bandwidth options.
     819             :  * Uses old_options as the previous options.
     820             :  *
     821             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
     822             :  * on error.
     823             :  */
     824             : int
     825         496 : options_validate_relay_bandwidth(const or_options_t *old_options,
     826             :                                  or_options_t *options,
     827             :                                  char **msg)
     828             : {
     829         496 :   (void)old_options;
     830             : 
     831         496 :   if (BUG(!options))
     832           0 :     return -1;
     833             : 
     834         496 :   if (BUG(!msg))
     835           0 :     return -1;
     836             : 
     837             :   /* 31851: the tests expect us to validate bandwidths, even when we are not
     838             :   * in relay mode. */
     839         496 :   if (config_ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
     840             :                            "MaxAdvertisedBandwidth", msg) < 0)
     841             :     return -1;
     842         493 :   if (config_ensure_bandwidth_cap(&options->RelayBandwidthRate,
     843             :                            "RelayBandwidthRate", msg) < 0)
     844             :     return -1;
     845         490 :   if (config_ensure_bandwidth_cap(&options->RelayBandwidthBurst,
     846             :                            "RelayBandwidthBurst", msg) < 0)
     847             :     return -1;
     848         487 :   if (config_ensure_bandwidth_cap(&options->PerConnBWRate,
     849             :                            "PerConnBWRate", msg) < 0)
     850             :     return -1;
     851         484 :   if (config_ensure_bandwidth_cap(&options->PerConnBWBurst,
     852             :                            "PerConnBWBurst", msg) < 0)
     853             :     return -1;
     854             : 
     855         481 :   if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
     856           4 :     options->RelayBandwidthBurst = options->RelayBandwidthRate;
     857         481 :   if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
     858           1 :     options->RelayBandwidthRate = options->RelayBandwidthBurst;
     859             : 
     860         481 :   if (server_mode(options)) {
     861         338 :     const unsigned required_min_bw =
     862         169 :       public_server_mode(options) ?
     863         169 :        RELAY_REQUIRED_MIN_BANDWIDTH : BRIDGE_REQUIRED_MIN_BANDWIDTH;
     864         338 :     const char * const optbridge =
     865         169 :       public_server_mode(options) ? "" : "bridge ";
     866         169 :     if (options->BandwidthRate < required_min_bw) {
     867           1 :       tor_asprintf(msg,
     868             :                        "BandwidthRate is set to %d bytes/second. "
     869             :                        "For %sservers, it must be at least %u.",
     870             :                        (int)options->BandwidthRate, optbridge,
     871             :                        required_min_bw);
     872           1 :       return -1;
     873         168 :     } else if (options->MaxAdvertisedBandwidth <
     874         168 :                required_min_bw/2) {
     875           1 :       tor_asprintf(msg,
     876             :                        "MaxAdvertisedBandwidth is set to %d bytes/second. "
     877             :                        "For %sservers, it must be at least %u.",
     878             :                        (int)options->MaxAdvertisedBandwidth, optbridge,
     879             :                        required_min_bw/2);
     880           1 :       return -1;
     881             :     }
     882         167 :     if (options->RelayBandwidthRate &&
     883             :       options->RelayBandwidthRate < required_min_bw) {
     884           1 :       tor_asprintf(msg,
     885             :                        "RelayBandwidthRate is set to %d bytes/second. "
     886             :                        "For %sservers, it must be at least %u.",
     887             :                        (int)options->RelayBandwidthRate, optbridge,
     888             :                        required_min_bw);
     889           1 :       return -1;
     890             :     }
     891             :   }
     892             : 
     893             :   /* 31851: the tests expect us to validate bandwidths, even when we are not
     894             :    * in relay mode. */
     895         478 :   if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
     896           1 :     REJECT("RelayBandwidthBurst must be at least equal "
     897             :            "to RelayBandwidthRate.");
     898             : 
     899             :   /* if they set relaybandwidth* really high but left bandwidth*
     900             :    * at the default, raise the defaults. */
     901         477 :   if (options->RelayBandwidthRate > options->BandwidthRate)
     902           2 :     options->BandwidthRate = options->RelayBandwidthRate;
     903         477 :   if (options->RelayBandwidthBurst > options->BandwidthBurst)
     904           2 :     options->BandwidthBurst = options->RelayBandwidthBurst;
     905             : 
     906             :   return 0;
     907             : }
     908             : 
     909             : /**
     910             :  * Legacy validation/normalization function for the relay bandwidth accounting
     911             :  * options. Uses old_options as the previous options.
     912             :  *
     913             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
     914             :  * on error.
     915             :  */
     916             : int
     917         476 : options_validate_relay_accounting(const or_options_t *old_options,
     918             :                                   or_options_t *options,
     919             :                                   char **msg)
     920             : {
     921         476 :   (void)old_options;
     922             : 
     923         476 :   if (BUG(!options))
     924           0 :     return -1;
     925             : 
     926         476 :   if (BUG(!msg))
     927           0 :     return -1;
     928             : 
     929             :   /* 31851: the tests expect us to validate accounting, even when we are not
     930             :    * in relay mode. */
     931         476 :   if (accounting_parse_options(options, 1)<0)
     932           1 :     REJECT("Failed to parse accounting options. See logs for details.");
     933             : 
     934         475 :   if (options->AccountingMax) {
     935          10 :     if (options->RendConfigLines && server_mode(options)) {
     936           1 :       log_warn(LD_CONFIG, "Using accounting with a hidden service and an "
     937             :                "ORPort is risky: your hidden service(s) and your public "
     938             :                "address will all turn off at the same time, which may alert "
     939             :                "observers that they are being run by the same party.");
     940           9 :     } else if (config_count_key(options->RendConfigLines,
     941             :                                 "HiddenServiceDir") > 1) {
     942           1 :       log_warn(LD_CONFIG, "Using accounting with multiple hidden services is "
     943             :                "risky: they will all turn off at the same time, which may "
     944             :                "alert observers that they are being run by the same party.");
     945             :     }
     946             :   }
     947             : 
     948         475 :   options->AccountingRule = ACCT_MAX;
     949         475 :   if (options->AccountingRule_option) {
     950         475 :     if (!strcmp(options->AccountingRule_option, "sum"))
     951           4 :       options->AccountingRule = ACCT_SUM;
     952         471 :     else if (!strcmp(options->AccountingRule_option, "max"))
     953             :       options->AccountingRule = ACCT_MAX;
     954           3 :     else if (!strcmp(options->AccountingRule_option, "in"))
     955           1 :       options->AccountingRule = ACCT_IN;
     956           2 :     else if (!strcmp(options->AccountingRule_option, "out"))
     957           1 :       options->AccountingRule = ACCT_OUT;
     958             :     else
     959           1 :       REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
     960             :   }
     961             : 
     962             :   return 0;
     963             : }
     964             : 
     965             : /** Verify whether lst is a list of strings containing valid-looking
     966             :  * comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$'
     967             :  * to any nickname or fingerprint that needs it. Also splits comma-separated
     968             :  * list elements into multiple elements. Return 0 on success.
     969             :  * Warn and return -1 on failure.
     970             :  */
     971             : static int
     972         472 : normalize_nickname_list(config_line_t **normalized_out,
     973             :                         const config_line_t *lst, const char *name,
     974             :                         char **msg)
     975             : {
     976         472 :   if (!lst)
     977             :     return 0;
     978             : 
     979           7 :   config_line_t *new_nicknames = NULL;
     980           7 :   config_line_t **new_nicknames_next = &new_nicknames;
     981             : 
     982           7 :   const config_line_t *cl;
     983          15 :   for (cl = lst; cl; cl = cl->next) {
     984           9 :     const char *line = cl->value;
     985           9 :     if (!line)
     986           0 :       continue;
     987             : 
     988           9 :     int valid_line = 1;
     989           9 :     smartlist_t *sl = smartlist_new();
     990           9 :     smartlist_split_string(sl, line, ",",
     991             :       SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
     992          19 :     SMARTLIST_FOREACH_BEGIN(sl, char *, s)
     993             :     {
     994          11 :       char *normalized = NULL;
     995          11 :       if (!is_legal_nickname_or_hexdigest(s)) {
     996             :         // check if first char is dollar
     997           3 :         if (s[0] != '$') {
     998             :           // Try again but with a dollar symbol prepended
     999           3 :           char *prepended;
    1000           3 :           tor_asprintf(&prepended, "$%s", s);
    1001             : 
    1002           3 :           if (is_legal_nickname_or_hexdigest(prepended)) {
    1003             :             // The nickname is valid when it's prepended, set it as the
    1004             :             // normalized version
    1005           2 :             normalized = prepended;
    1006             :           } else {
    1007             :             // Still not valid, free and fallback to error message
    1008           1 :             tor_free(prepended);
    1009             :           }
    1010             :         }
    1011             : 
    1012           3 :         if (!normalized) {
    1013           1 :           tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
    1014           1 :           valid_line = 0;
    1015           1 :           break;
    1016             :         }
    1017             :       } else {
    1018           8 :         normalized = tor_strdup(s);
    1019             :       }
    1020             : 
    1021          10 :       config_line_t *next = tor_malloc_zero(sizeof(*next));
    1022          10 :       next->key = tor_strdup(cl->key);
    1023          10 :       next->value = normalized;
    1024          10 :       next->next = NULL;
    1025             : 
    1026          10 :       *new_nicknames_next = next;
    1027          10 :       new_nicknames_next = &next->next;
    1028          10 :     } SMARTLIST_FOREACH_END(s);
    1029             : 
    1030          20 :     SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
    1031           9 :     smartlist_free(sl);
    1032             : 
    1033           9 :     if (!valid_line) {
    1034           1 :       config_free_lines(new_nicknames);
    1035           1 :       return -1;
    1036             :     }
    1037             :   }
    1038             : 
    1039           6 :   *normalized_out = new_nicknames;
    1040             : 
    1041           6 :   return 0;
    1042             : }
    1043             : 
    1044             : #define ONE_MEGABYTE (UINT64_C(1) << 20)
    1045             : 
    1046             : /* If we have less than 300 MB suggest disabling dircache */
    1047             : #define DIRCACHE_MIN_MEM_MB 300
    1048             : #define DIRCACHE_MIN_MEM_BYTES (DIRCACHE_MIN_MEM_MB*ONE_MEGABYTE)
    1049             : #define STRINGIFY(val) #val
    1050             : 
    1051             : /** Create a warning message for emitting if we are a dircache but may not have
    1052             :  * enough system memory, or if we are not a dircache but probably should be.
    1053             :  * Return -1 when a message is returned in *msg*, else return 0. */
    1054             : STATIC int
    1055         172 : have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
    1056             :                              char **msg)
    1057             : {
    1058         172 :   *msg = NULL;
    1059             :   /* XXX We should possibly be looking at MaxMemInQueues here
    1060             :    * unconditionally.  Or we should believe total_mem unconditionally. */
    1061         172 :   if (total_mem == 0) {
    1062         166 :     if (get_total_system_memory(&total_mem) < 0) {
    1063           0 :       total_mem = options->MaxMemInQueues >= SIZE_MAX ?
    1064           0 :         SIZE_MAX : (size_t)options->MaxMemInQueues;
    1065             :     }
    1066             :   }
    1067         172 :   if (options->DirCache) {
    1068         167 :     if (total_mem < DIRCACHE_MIN_MEM_BYTES) {
    1069           2 :       if (options->BridgeRelay) {
    1070           1 :         tor_asprintf(msg, "Running a Bridge with less than %d MB of memory "
    1071             :                        "is not recommended.", DIRCACHE_MIN_MEM_MB);
    1072             :       } else {
    1073           1 :         tor_asprintf(msg, "Being a directory cache (default) with less than "
    1074             :                        "%d MB of memory is not recommended and may consume "
    1075             :                        "most of the available resources. Consider disabling "
    1076             :                        "this functionality by setting the DirCache option "
    1077             :                        "to 0.", DIRCACHE_MIN_MEM_MB);
    1078             :       }
    1079             :     }
    1080             :   } else {
    1081           5 :     if (total_mem >= DIRCACHE_MIN_MEM_BYTES) {
    1082           4 :       *msg = tor_strdup("DirCache is disabled and we are configured as a "
    1083             :                "relay. We will not become a Guard.");
    1084             :     }
    1085             :   }
    1086         172 :   return *msg == NULL ? 0 : -1;
    1087             : }
    1088             : #undef STRINGIFY
    1089             : 
    1090             : /**
    1091             :  * Legacy validation/normalization function for the relay mode options.
    1092             :  * Uses old_options as the previous options.
    1093             :  *
    1094             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
    1095             :  * on error.
    1096             :  */
    1097             : int
    1098         474 : options_validate_relay_mode(const or_options_t *old_options,
    1099             :                             or_options_t *options,
    1100             :                             char **msg)
    1101             : {
    1102         474 :   (void)old_options;
    1103             : 
    1104         474 :   if (BUG(!options))
    1105           0 :     return -1;
    1106             : 
    1107         474 :   if (BUG(!msg))
    1108           0 :     return -1;
    1109             : 
    1110         474 :   if (server_mode(options) && options->RendConfigLines)
    1111           2 :     log_warn(LD_CONFIG,
    1112             :         "Tor is currently configured as a relay and a hidden service. "
    1113             :         "That's not very secure: you should probably run your hidden service "
    1114             :         "in a separate Tor process, at least -- see "
    1115             :         "https://bugs.torproject.org/tpo/core/tor/8742.");
    1116             : 
    1117         474 :   if (options->BridgeRelay && options->DirPort_set) {
    1118           2 :     log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
    1119             :              "DirPort");
    1120           2 :     config_free_lines(options->DirPort_lines);
    1121           2 :     options->DirPort_lines = NULL;
    1122           2 :     options->DirPort_set = 0;
    1123             :   }
    1124             : 
    1125         474 :   if (options->DirPort_set && !options->DirCache) {
    1126           0 :     REJECT("DirPort configured but DirCache disabled. DirPort requires "
    1127             :            "DirCache.");
    1128             :   }
    1129             : 
    1130         474 :   if (options->BridgeRelay && !options->DirCache) {
    1131           1 :     REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires "
    1132             :            "DirCache.");
    1133             :   }
    1134             : 
    1135         473 :   if (options->BridgeRelay == 1 && ! options->ORPort_set)
    1136           1 :     REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid "
    1137             :            "combination.");
    1138             : 
    1139         472 :   if (server_mode(options)) {
    1140         166 :     char *dircache_msg = NULL;
    1141         166 :     if (have_enough_mem_for_dircache(options, 0, &dircache_msg)) {
    1142           3 :       log_warn(LD_CONFIG, "%s", dircache_msg);
    1143           3 :       tor_free(dircache_msg);
    1144             :     }
    1145             :   }
    1146             : 
    1147         472 :   if (options->MyFamily_lines && options->BridgeRelay) {
    1148           1 :     log_warn(LD_CONFIG, "Listing a family for a bridge relay is not "
    1149             :              "supported: it can reveal bridge fingerprints to censors. "
    1150             :              "You should also make sure you aren't listing this bridge's "
    1151             :              "fingerprint in any other MyFamily.");
    1152             :   }
    1153         472 :   if (options->MyFamily_lines && !options->ContactInfo) {
    1154           4 :     log_warn(LD_CONFIG, "MyFamily is set but ContactInfo is not configured. "
    1155             :              "ContactInfo should always be set when MyFamily option is too.");
    1156             :   }
    1157         472 :   if (normalize_nickname_list(&options->MyFamily,
    1158         472 :                               options->MyFamily_lines, "MyFamily", msg))
    1159             :     return -1;
    1160             : 
    1161         471 :   if (options->ConstrainedSockets) {
    1162           6 :     if (options->DirPort_set) {
    1163             :       /* Providing cached directory entries while system TCP buffers are scarce
    1164             :        * will exacerbate the socket errors.  Suggest that this be disabled. */
    1165           0 :       COMPLAIN("You have requested constrained socket buffers while also "
    1166             :                "serving directory entries via DirPort.  It is strongly "
    1167             :                "suggested that you disable serving directory requests when "
    1168             :                "system TCP buffer resources are scarce.");
    1169             :     }
    1170             :   }
    1171             : 
    1172             :   return 0;
    1173             : }
    1174             : 
    1175             : /**
    1176             :  * Legacy validation/normalization function for the relay testing options
    1177             :  * in options. Uses old_options as the previous options.
    1178             :  *
    1179             :  * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
    1180             :  * on error.
    1181             :  */
    1182             : int
    1183         406 : options_validate_relay_testing(const or_options_t *old_options,
    1184             :                                or_options_t *options,
    1185             :                                char **msg)
    1186             : {
    1187         406 :   (void)old_options;
    1188             : 
    1189         406 :   if (BUG(!options))
    1190           0 :     return -1;
    1191             : 
    1192         406 :   if (BUG(!msg))
    1193           0 :     return -1;
    1194             : 
    1195         406 :   if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
    1196           1 :     REJECT("SigningKeyLifetime is too short.");
    1197         405 :   if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2)
    1198           2 :     REJECT("LinkCertLifetime is too short.");
    1199         403 :   if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
    1200           2 :     REJECT("TestingAuthKeyLifetime is too short.");
    1201             : 
    1202             :   return 0;
    1203             : }
    1204             : 
    1205             : /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
    1206             :  * will require us to rotate the CPU and DNS workers; else return 0. */
    1207             : static int
    1208           0 : options_transition_affects_workers(const or_options_t *old_options,
    1209             :                                    const or_options_t *new_options)
    1210             : {
    1211           0 :   YES_IF_CHANGED_STRING(DataDirectory);
    1212           0 :   YES_IF_CHANGED_INT(NumCPUs);
    1213           0 :   YES_IF_CHANGED_LINELIST(ORPort_lines);
    1214           0 :   YES_IF_CHANGED_BOOL(ServerDNSSearchDomains);
    1215           0 :   YES_IF_CHANGED_BOOL(SafeLogging_);
    1216           0 :   YES_IF_CHANGED_BOOL(ClientOnly);
    1217           0 :   YES_IF_CHANGED_BOOL(LogMessageDomains);
    1218           0 :   YES_IF_CHANGED_LINELIST(Logs);
    1219             : 
    1220           0 :   if (server_mode(old_options) != server_mode(new_options) ||
    1221           0 :       public_server_mode(old_options) != public_server_mode(new_options) ||
    1222           0 :       dir_server_mode(old_options) != dir_server_mode(new_options))
    1223           0 :     return 1;
    1224             : 
    1225             :   /* Nothing that changed matters. */
    1226             :   return 0;
    1227             : }
    1228             : 
    1229             : /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
    1230             :  * will require us to generate a new descriptor; else return 0. */
    1231             : static int
    1232           0 : options_transition_affects_descriptor(const or_options_t *old_options,
    1233             :                                       const or_options_t *new_options)
    1234             : {
    1235             :   /* XXX We can be smarter here. If your DirPort isn't being
    1236             :    * published and you just turned it off, no need to republish. Etc. */
    1237             : 
    1238           0 :   YES_IF_CHANGED_STRING(DataDirectory);
    1239           0 :   YES_IF_CHANGED_STRING(Nickname);
    1240           0 :   YES_IF_CHANGED_LINELIST(Address);
    1241           0 :   YES_IF_CHANGED_LINELIST(ExitPolicy);
    1242           0 :   YES_IF_CHANGED_BOOL(ExitRelay);
    1243           0 :   YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate);
    1244           0 :   YES_IF_CHANGED_BOOL(ExitPolicyRejectLocalInterfaces);
    1245           0 :   YES_IF_CHANGED_BOOL(IPv6Exit);
    1246           0 :   YES_IF_CHANGED_LINELIST(ORPort_lines);
    1247           0 :   YES_IF_CHANGED_LINELIST(DirPort_lines);
    1248           0 :   YES_IF_CHANGED_LINELIST(DirPort_lines);
    1249           0 :   YES_IF_CHANGED_BOOL(ClientOnly);
    1250           0 :   YES_IF_CHANGED_BOOL(DisableNetwork);
    1251           0 :   YES_IF_CHANGED_BOOL(PublishServerDescriptor_);
    1252           0 :   YES_IF_CHANGED_STRING(ContactInfo);
    1253           0 :   YES_IF_CHANGED_STRING(BridgeDistribution);
    1254           0 :   YES_IF_CHANGED_LINELIST(MyFamily);
    1255           0 :   YES_IF_CHANGED_STRING(AccountingStart);
    1256           0 :   YES_IF_CHANGED_INT(AccountingMax);
    1257           0 :   YES_IF_CHANGED_INT(AccountingRule);
    1258           0 :   YES_IF_CHANGED_BOOL(DirCache);
    1259           0 :   YES_IF_CHANGED_BOOL(AssumeReachable);
    1260             : 
    1261           0 :   if (relay_get_effective_bwrate(old_options) !=
    1262           0 :         relay_get_effective_bwrate(new_options) ||
    1263           0 :       relay_get_effective_bwburst(old_options) !=
    1264           0 :         relay_get_effective_bwburst(new_options) ||
    1265           0 :       public_server_mode(old_options) != public_server_mode(new_options))
    1266           0 :     return 1;
    1267             : 
    1268             :   return 0;
    1269             : }
    1270             : 
    1271             : /** Fetch the active option list, and take relay actions based on it. All of
    1272             :  * the things we do should survive being done repeatedly.  If present,
    1273             :  * <b>old_options</b> contains the previous value of the options.
    1274             :  *
    1275             :  * Return 0 if all goes well, return -1 if it's time to die.
    1276             :  *
    1277             :  * Note: We haven't moved all the "act on new configuration" logic
    1278             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1279             :  * places.
    1280             :  */
    1281             : int
    1282           4 : options_act_relay(const or_options_t *old_options)
    1283             : {
    1284           4 :   const or_options_t *options = get_options();
    1285             : 
    1286           8 :   const int transition_affects_workers =
    1287           4 :     old_options && options_transition_affects_workers(old_options, options);
    1288             : 
    1289             :   /* We want to reinit keys as needed before we do much of anything else:
    1290             :      keys are important, and other things can depend on them. */
    1291           4 :   if (transition_affects_workers ||
    1292           4 :       (authdir_mode_v3(options) && (!old_options ||
    1293           0 :                                     !authdir_mode_v3(old_options)))) {
    1294           0 :     if (init_keys() < 0) {
    1295           0 :       log_warn(LD_BUG,"Error initializing keys; exiting");
    1296           0 :       return -1;
    1297             :     }
    1298             :   }
    1299             : 
    1300           4 :   if (server_mode(options)) {
    1301           4 :     static int cdm_initialized = 0;
    1302           4 :     if (cdm_initialized == 0) {
    1303           4 :       cdm_initialized = 1;
    1304           4 :       consdiffmgr_configure(NULL);
    1305           4 :       consdiffmgr_validate();
    1306             :     }
    1307             :   }
    1308             : 
    1309             :   /* Check for transitions that need action. */
    1310           4 :   if (old_options) {
    1311           0 :     if (transition_affects_workers) {
    1312           0 :       log_info(LD_GENERAL,
    1313             :                "Worker-related options changed. Rotating workers.");
    1314           0 :       const int server_mode_turned_on =
    1315           0 :         server_mode(options) && !server_mode(old_options);
    1316           0 :       const int dir_server_mode_turned_on =
    1317           0 :         dir_server_mode(options) && !dir_server_mode(old_options);
    1318             : 
    1319           0 :       if (server_mode_turned_on || dir_server_mode_turned_on) {
    1320           0 :         cpu_init();
    1321             :       }
    1322             : 
    1323           0 :       if (server_mode_turned_on) {
    1324           0 :         ip_address_changed(0);
    1325             :       }
    1326           0 :       cpuworkers_rotate_keyinfo();
    1327             :     }
    1328             :   }
    1329             : 
    1330             :   return 0;
    1331             : }
    1332             : 
    1333             : /** Fetch the active option list, and take relay accounting actions based on
    1334             :  * it. All of the things we do should survive being done repeatedly. If
    1335             :  * present, <b>old_options</b> contains the previous value of the options.
    1336             :  *
    1337             :  * Return 0 if all goes well, return -1 if it's time to die.
    1338             :  *
    1339             :  * Note: We haven't moved all the "act on new configuration" logic
    1340             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1341             :  * places.
    1342             :  */
    1343             : int
    1344           4 : options_act_relay_accounting(const or_options_t *old_options)
    1345             : {
    1346           4 :   (void)old_options;
    1347             : 
    1348           4 :   const or_options_t *options = get_options();
    1349             : 
    1350             :   /* Set up accounting */
    1351           4 :   if (accounting_parse_options(options, 0)<0) {
    1352             :     // LCOV_EXCL_START
    1353             :     log_warn(LD_BUG,"Error in previously validated accounting options");
    1354             :     return -1;
    1355             :     // LCOV_EXCL_STOP
    1356             :   }
    1357           4 :   if (accounting_is_enabled(options))
    1358           0 :     configure_accounting(time(NULL));
    1359             : 
    1360             :   return 0;
    1361             : }
    1362             : 
    1363             : /** Fetch the active option list, and take relay bandwidth actions based on
    1364             :  * it. All of the things we do should survive being done repeatedly. If
    1365             :  * present, <b>old_options</b> contains the previous value of the options.
    1366             :  *
    1367             :  * Return 0 if all goes well, return -1 if it's time to die.
    1368             :  *
    1369             :  * Note: We haven't moved all the "act on new configuration" logic
    1370             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1371             :  * places.
    1372             :  */
    1373             : int
    1374           0 : options_act_relay_bandwidth(const or_options_t *old_options)
    1375             : {
    1376           0 :   const or_options_t *options = get_options();
    1377             : 
    1378             :   /* Check for transitions that need action. */
    1379           0 :   if (old_options) {
    1380           0 :     if (options->PerConnBWRate != old_options->PerConnBWRate ||
    1381           0 :         options->PerConnBWBurst != old_options->PerConnBWBurst)
    1382           0 :       connection_or_update_token_buckets(get_connection_array(), options);
    1383             : 
    1384           0 :     if (options->RelayBandwidthRate != old_options->RelayBandwidthRate ||
    1385           0 :         options->RelayBandwidthBurst != old_options->RelayBandwidthBurst)
    1386           0 :       connection_bucket_adjust(options);
    1387             :   }
    1388             : 
    1389           0 :   return 0;
    1390             : }
    1391             : 
    1392             : /** Fetch the active option list, and take bridge statistics actions based on
    1393             :  * it. All of the things we do should survive being done repeatedly. If
    1394             :  * present, <b>old_options</b> contains the previous value of the options.
    1395             :  *
    1396             :  * Return 0 if all goes well, return -1 if it's time to die.
    1397             :  *
    1398             :  * Note: We haven't moved all the "act on new configuration" logic
    1399             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1400             :  * places.
    1401             :  */
    1402             : int
    1403           0 : options_act_bridge_stats(const or_options_t *old_options)
    1404             : {
    1405           0 :   const or_options_t *options = get_options();
    1406             : 
    1407             : /* How long should we delay counting bridge stats after becoming a bridge?
    1408             :  * We use this so we don't count clients who used our bridge thinking it is
    1409             :  * a relay. If you change this, don't forget to change the log message
    1410             :  * below. It's 4 hours (the time it takes to stop being used by clients)
    1411             :  * plus some extra time for clock skew. */
    1412             : #define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
    1413             : 
    1414             :   /* Check for transitions that need action. */
    1415           0 :   if (old_options) {
    1416           0 :     if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
    1417           0 :       int was_relay = 0;
    1418           0 :       if (options->BridgeRelay) {
    1419           0 :         time_t int_start = time(NULL);
    1420           0 :         if (config_lines_eq(old_options->ORPort_lines,options->ORPort_lines)) {
    1421           0 :           int_start += RELAY_BRIDGE_STATS_DELAY;
    1422           0 :           was_relay = 1;
    1423             :         }
    1424           0 :         geoip_bridge_stats_init(int_start);
    1425           0 :         log_info(LD_CONFIG, "We are acting as a bridge now.  Starting new "
    1426             :                  "GeoIP stats interval%s.", was_relay ? " in 6 "
    1427             :                  "hours from now" : "");
    1428             :       } else {
    1429           0 :         geoip_bridge_stats_term();
    1430           0 :         log_info(LD_GENERAL, "We are no longer acting as a bridge.  "
    1431             :                  "Forgetting GeoIP stats.");
    1432             :       }
    1433             :     }
    1434             :   }
    1435             : 
    1436           0 :   return 0;
    1437             : }
    1438             : 
    1439             : /** Fetch the active option list, and take relay statistics actions based on
    1440             :  * it. All of the things we do should survive being done repeatedly. If
    1441             :  * present, <b>old_options</b> contains the previous value of the options.
    1442             :  *
    1443             :  * Sets <b>*print_notice_out</b> if we enabled stats, and need to print
    1444             :  * a stats log using options_act_relay_stats_msg().
    1445             :  *
    1446             :  * If loading the GeoIP file failed, sets DirReqStatistics and
    1447             :  * EntryStatistics to 0. This breaks the normalization/act ordering
    1448             :  * introduced in 29211.
    1449             :  *
    1450             :  * Return 0 if all goes well, return -1 if it's time to die.
    1451             :  *
    1452             :  * Note: We haven't moved all the "act on new configuration" logic
    1453             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1454             :  * places.
    1455             :  */
    1456             : int
    1457           4 : options_act_relay_stats(const or_options_t *old_options,
    1458             :                         bool *print_notice_out)
    1459             : {
    1460           4 :   if (BUG(!print_notice_out))
    1461           0 :     return -1;
    1462             : 
    1463           4 :   or_options_t *options = get_options_mutable();
    1464             : 
    1465           4 :   if (options->CellStatistics || options->DirReqStatistics ||
    1466           0 :       options->EntryStatistics || options->ExitPortStatistics ||
    1467           0 :       options->ConnDirectionStatistics ||
    1468           0 :       options->HiddenServiceStatistics) {
    1469           4 :     time_t now = time(NULL);
    1470           4 :     int print_notice = 0;
    1471             : 
    1472           4 :     if ((!old_options || !old_options->CellStatistics) &&
    1473           4 :         options->CellStatistics) {
    1474           0 :       rep_hist_buffer_stats_init(now);
    1475           0 :       print_notice = 1;
    1476             :     }
    1477           4 :     if ((!old_options || !old_options->DirReqStatistics) &&
    1478           4 :         options->DirReqStatistics) {
    1479           4 :       if (geoip_is_loaded(AF_INET)) {
    1480           0 :         geoip_dirreq_stats_init(now);
    1481           0 :         print_notice = 1;
    1482             :       } else {
    1483             :         /* disable statistics collection since we have no geoip file */
    1484             :         /* 29211: refactor to avoid the normalisation/act inversion */
    1485           4 :         options->DirReqStatistics = 0;
    1486           4 :         if (options->ORPort_set)
    1487           4 :           log_notice(LD_CONFIG, "Configured to measure directory request "
    1488             :                                 "statistics, but no GeoIP database found. "
    1489             :                                 "Please specify a GeoIP database using the "
    1490             :                                 "GeoIPFile option.");
    1491             :       }
    1492             :     }
    1493           4 :     if ((!old_options || !old_options->EntryStatistics) &&
    1494           4 :         options->EntryStatistics && !should_record_bridge_info(options)) {
    1495             :       /* If we get here, we've started recording bridge info when we didn't
    1496             :        * do so before.  Note that "should_record_bridge_info()" will
    1497             :        * always be false at this point, because of the earlier block
    1498             :        * that cleared EntryStatistics when public_server_mode() was false.
    1499             :        * We're leaving it in as defensive programming. */
    1500           0 :       if (geoip_is_loaded(AF_INET) || geoip_is_loaded(AF_INET6)) {
    1501           0 :         geoip_entry_stats_init(now);
    1502           0 :         print_notice = 1;
    1503             :       } else {
    1504           0 :         options->EntryStatistics = 0;
    1505           0 :         log_notice(LD_CONFIG, "Configured to measure entry node "
    1506             :                               "statistics, but no GeoIP database found. "
    1507             :                               "Please specify a GeoIP database using the "
    1508             :                               "GeoIPFile option.");
    1509             :       }
    1510             :     }
    1511           4 :     if ((!old_options || !old_options->ExitPortStatistics) &&
    1512           4 :         options->ExitPortStatistics) {
    1513           0 :       rep_hist_exit_stats_init(now);
    1514           0 :       print_notice = 1;
    1515             :     }
    1516           4 :     if ((!old_options || !old_options->ConnDirectionStatistics) &&
    1517           4 :         options->ConnDirectionStatistics) {
    1518           0 :       conn_stats_init(now);
    1519             :     }
    1520           4 :     if ((!old_options || !old_options->HiddenServiceStatistics) &&
    1521           4 :         options->HiddenServiceStatistics) {
    1522           4 :       log_info(LD_CONFIG, "Configured to measure hidden service statistics.");
    1523           4 :       rep_hist_hs_stats_init(now);
    1524             :     }
    1525           4 :     if (print_notice)
    1526           0 :       *print_notice_out = 1;
    1527             :   }
    1528             : 
    1529             :   /* If we used to have statistics enabled but we just disabled them,
    1530             :      stop gathering them.  */
    1531           4 :   if (old_options && old_options->CellStatistics &&
    1532           0 :       !options->CellStatistics)
    1533           0 :     rep_hist_buffer_stats_term();
    1534           4 :   if (old_options && old_options->DirReqStatistics &&
    1535           0 :       !options->DirReqStatistics)
    1536           0 :     geoip_dirreq_stats_term();
    1537           4 :   if (old_options && old_options->EntryStatistics &&
    1538           0 :       !options->EntryStatistics)
    1539           0 :     geoip_entry_stats_term();
    1540           4 :   if (old_options && old_options->HiddenServiceStatistics &&
    1541           0 :       !options->HiddenServiceStatistics)
    1542           0 :     rep_hist_hs_stats_term();
    1543           4 :   if (old_options && old_options->ExitPortStatistics &&
    1544           0 :       !options->ExitPortStatistics)
    1545           0 :     rep_hist_exit_stats_term();
    1546           4 :   if (old_options && old_options->ConnDirectionStatistics &&
    1547           0 :       !options->ConnDirectionStatistics)
    1548           0 :     conn_stats_terminate();
    1549             : 
    1550             :   return 0;
    1551             : }
    1552             : 
    1553             : /** Print a notice about relay/dirauth stats being enabled. */
    1554             : void
    1555           0 : options_act_relay_stats_msg(void)
    1556             : {
    1557           0 :   log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
    1558             :              "the *-stats files that will first be written to the "
    1559             :              "data directory in 24 hours from now.");
    1560           0 : }
    1561             : 
    1562             : /** Fetch the active option list, and take relay descriptor actions based on
    1563             :  * it. All of the things we do should survive being done repeatedly. If
    1564             :  * present, <b>old_options</b> contains the previous value of the options.
    1565             :  *
    1566             :  * Return 0 if all goes well, return -1 if it's time to die.
    1567             :  *
    1568             :  * Note: We haven't moved all the "act on new configuration" logic
    1569             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1570             :  * places.
    1571             :  */
    1572             : int
    1573           4 : options_act_relay_desc(const or_options_t *old_options)
    1574             : {
    1575           4 :   const or_options_t *options = get_options();
    1576             : 
    1577             :   /* Since our options changed, we might need to regenerate and upload our
    1578             :    * server descriptor.
    1579             :    */
    1580           4 :   if (!old_options ||
    1581           0 :       options_transition_affects_descriptor(old_options, options))
    1582           4 :     mark_my_descriptor_dirty("config change");
    1583             : 
    1584           4 :   return 0;
    1585             : }
    1586             : 
    1587             : /** Fetch the active option list, and take relay DoS actions based on
    1588             :  * it. All of the things we do should survive being done repeatedly. If
    1589             :  * present, <b>old_options</b> contains the previous value of the options.
    1590             :  *
    1591             :  * Return 0 if all goes well, return -1 if it's time to die.
    1592             :  *
    1593             :  * Note: We haven't moved all the "act on new configuration" logic
    1594             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1595             :  * places.
    1596             :  */
    1597             : int
    1598           4 : options_act_relay_dos(const or_options_t *old_options)
    1599             : {
    1600           4 :   const or_options_t *options = get_options();
    1601             : 
    1602             :   /* DoS mitigation subsystem only applies to public relay. */
    1603           4 :   if (public_server_mode(options)) {
    1604             :     /* If we are configured as a relay, initialize the subsystem. Even on HUP,
    1605             :      * this is safe to call as it will load data from the current options
    1606             :      * or/and the consensus. */
    1607           4 :     dos_init();
    1608           0 :   } else if (old_options && public_server_mode(old_options)) {
    1609             :     /* Going from relay to non relay, clean it up. */
    1610           0 :     dos_free_all();
    1611             :   }
    1612             : 
    1613           4 :   return 0;
    1614             : }
    1615             : 
    1616             : /** Fetch the active option list, and take dirport actions based on
    1617             :  * it. All of the things we do should survive being done repeatedly. If
    1618             :  * present, <b>old_options</b> contains the previous value of the options.
    1619             :  *
    1620             :  * Return 0 if all goes well, return -1 if it's time to die.
    1621             :  *
    1622             :  * Note: We haven't moved all the "act on new configuration" logic
    1623             :  * into the options_act* functions yet.  Some is still in do_hup() and other
    1624             :  * places.
    1625             :  */
    1626             : int
    1627           4 : options_act_relay_dir(const or_options_t *old_options)
    1628             : {
    1629           4 :   (void)old_options;
    1630             : 
    1631           4 :   const or_options_t *options = get_options();
    1632             : 
    1633           4 :   if (!public_server_mode(options))
    1634             :     return 0;
    1635             : 
    1636             :   /* Load the webpage we're going to serve every time someone asks for '/' on
    1637             :      our DirPort. */
    1638           4 :   tor_free(global_dirfrontpagecontents);
    1639           4 :   if (options->DirPortFrontPage) {
    1640           0 :     global_dirfrontpagecontents =
    1641           0 :       read_file_to_str(options->DirPortFrontPage, 0, NULL);
    1642           0 :     if (!global_dirfrontpagecontents) {
    1643           0 :       log_warn(LD_CONFIG,
    1644             :                "DirPortFrontPage file '%s' not found. Continuing anyway.",
    1645             :                options->DirPortFrontPage);
    1646             :     }
    1647             :   }
    1648             : 
    1649             :   return 0;
    1650             : }

Generated by: LCOV version 1.14