tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

selftest.c (14705B)


      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 selftest.c
      9 * \brief Relay self-testing
     10 *
     11 * Relays need to make sure that their own ports are reachable, and estimate
     12 * their own bandwidth, before publishing.
     13 */
     14 
     15 #include "core/or/or.h"
     16 
     17 #include "app/config/config.h"
     18 
     19 #include "core/mainloop/connection.h"
     20 #include "core/mainloop/mainloop.h"
     21 #include "core/mainloop/netstatus.h"
     22 
     23 #include "core/or/circuitbuild.h"
     24 #include "core/or/circuitlist.h"
     25 #include "core/or/circuituse.h"
     26 #include "core/or/crypt_path_st.h"
     27 #include "core/or/extendinfo.h"
     28 #include "core/or/extend_info_st.h"
     29 #include "core/or/origin_circuit_st.h"
     30 #include "core/or/relay.h"
     31 
     32 #include "feature/control/control_events.h"
     33 
     34 #include "feature/dirauth/authmode.h"
     35 
     36 #include "feature/dirclient/dirclient.h"
     37 #include "feature/dircommon/directory.h"
     38 
     39 #include "feature/nodelist/authority_cert_st.h"
     40 #include "feature/nodelist/routerinfo.h"
     41 #include "feature/nodelist/routerinfo_st.h"
     42 #include "feature/nodelist/routerlist.h" // but...
     43 #include "feature/nodelist/routerset.h"
     44 #include "feature/nodelist/torcert.h"
     45 
     46 #include "feature/relay/relay_periodic.h"
     47 #include "feature/relay/router.h"
     48 #include "feature/relay/selftest.h"
     49 
     50 static bool have_orport_for_family(int family);
     51 static void inform_testing_reachability(const tor_addr_t *addr,
     52                                        uint16_t port);
     53 
     54 /** Whether we can reach our IPv4 ORPort from the outside. */
     55 static bool can_reach_or_port_ipv4 = false;
     56 /** Whether we can reach our IPv6 ORPort from the outside. */
     57 static bool can_reach_or_port_ipv6 = false;
     58 
     59 /** Has informed_testing_reachable logged a message about testing our IPv4
     60 * ORPort? */
     61 static bool have_informed_testing_or_port_ipv4 = false;
     62 /** Has informed_testing_reachable logged a message about testing our IPv6
     63 * ORPort? */
     64 static bool have_informed_testing_or_port_ipv6 = false;
     65 
     66 /** Forget what we have learned about our reachability status. */
     67 void
     68 router_reset_reachability(void)
     69 {
     70  can_reach_or_port_ipv4 = can_reach_or_port_ipv6 = false;
     71  have_informed_testing_or_port_ipv4 =
     72    have_informed_testing_or_port_ipv6 = false;
     73 }
     74 
     75 /** Return 1 if we won't do reachability checks, because:
     76 *   - AssumeReachable is set, or
     77 *   - the network is disabled.
     78 * Otherwise, return 0.
     79 */
     80 static int
     81 router_reachability_checks_disabled(const or_options_t *options)
     82 {
     83  return options->AssumeReachable ||
     84         net_is_disabled();
     85 }
     86 
     87 /** Return 0 if we need to do an ORPort reachability check, because:
     88 *   - no reachability check has been done yet, or
     89 *   - we've initiated reachability checks, but none have succeeded.
     90 *  Return 1 if we don't need to do an ORPort reachability check, because:
     91 *   - we've seen a successful reachability check, or
     92 *   - AssumeReachable is set, or
     93 *   - the network is disabled.
     94 
     95 * If `family'`is AF_INET or AF_INET6, return true only when we should skip
     96 * the given family's orport check (Because it's been checked, or because we
     97 * aren't checking it.)  If `family` is 0, return true if we can skip _all_
     98 * orport checks.
     99 */
    100 int
    101 router_orport_seems_reachable(const or_options_t *options,
    102                              int family)
    103 {
    104  tor_assert_nonfatal(family == AF_INET || family == AF_INET6 || family == 0);
    105  int reach_checks_disabled = router_reachability_checks_disabled(options);
    106  if (reach_checks_disabled) {
    107    return true;
    108  }
    109 
    110  // Note that we do a == 1 here, not just a boolean check.  This value
    111  // is also an autobool, so CFG_AUTO does not mean that we should
    112  // assume IPv6 ports are reachable.
    113  const bool ipv6_assume_reachable = (options->AssumeReachableIPv6 == 1);
    114 
    115  // Which reachability flags should we look at?
    116  const bool checking_ipv4 = (family == AF_INET || family == 0);
    117  const bool checking_ipv6 = (family == AF_INET6 || family == 0);
    118 
    119  if (checking_ipv4) {
    120    if (have_orport_for_family(AF_INET) && !can_reach_or_port_ipv4) {
    121      return false;
    122    }
    123  }
    124  if (checking_ipv6 && !ipv6_assume_reachable) {
    125    if (have_orport_for_family(AF_INET6) && !can_reach_or_port_ipv6) {
    126      return false;
    127    }
    128  }
    129 
    130  return true;
    131 }
    132 
    133 /** See if we currently believe our ORPort to be unreachable. If so, return 1
    134 * else return 0. */
    135 static int
    136 router_should_check_reachability(void)
    137 {
    138  const routerinfo_t *me = router_get_my_routerinfo();
    139  const or_options_t *options = get_options();
    140 
    141  if (!me)
    142    return 0;
    143 
    144  /* Doesn't check our IPv6 address, see #34065. */
    145  if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
    146      options->StrictNodes) {
    147    /* If we've excluded ourself, and StrictNodes is set, we can't test
    148     * ourself. */
    149 #define SELF_EXCLUDED_WARN_INTERVAL 3600
    150    static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL);
    151    log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC,
    152                   "Can't perform self-tests for this relay: we have "
    153                   "listed ourself in ExcludeNodes, and StrictNodes is set. "
    154                   "We cannot learn whether we are usable, and will not "
    155                   "be able to advertise ourself.");
    156    return 0;
    157  }
    158  return 1;
    159 }
    160 
    161 /**
    162 * Return true if we have configured an ORPort for the given family that
    163 * we would like to advertise.
    164 *
    165 * Like other self-testing functions, this function looks at our most
    166 * recently built descriptor.
    167 **/
    168 static bool
    169 have_orport_for_family(int family)
    170 {
    171  const routerinfo_t *me = router_get_my_routerinfo();
    172 
    173  if (!me)
    174    return false;
    175 
    176  tor_addr_port_t ap;
    177  if (router_get_orport(me, &ap, family) < 0) {
    178    return false;
    179  }
    180  return true;
    181 }
    182 
    183 /** Allocate and return a new extend_info_t that can be used to build
    184 * a circuit to or through the router <b>r</b>, using an address from
    185 * <b>family</b> (if available).
    186 *
    187 * Clients don't have routerinfos, so this function should only be called on a
    188 * server.
    189 *
    190 * If the requested address is not available, returns NULL. */
    191 static extend_info_t *
    192 extend_info_from_router(const routerinfo_t *r, int family)
    193 {
    194  extend_info_t *info;
    195  tor_addr_port_t ap;
    196 
    197  if (BUG(!r)) {
    198    return NULL;
    199  }
    200 
    201  /* Relays always assume that the first hop is reachable. They ignore
    202   * ReachableAddresses. */
    203  tor_assert_nonfatal(router_or_conn_should_skip_reachable_address_check(
    204                                                           get_options(), 0));
    205 
    206  const ed25519_public_key_t *ed_id_key;
    207  if (r->cache_info.signing_key_cert)
    208    ed_id_key = &r->cache_info.signing_key_cert->signing_key;
    209  else
    210    ed_id_key = NULL;
    211 
    212  if (router_get_orport(r, &ap, family) < 0) {
    213    /* We don't have an ORPort for the requested family. */
    214    return NULL;
    215  }
    216  info = extend_info_new(r->nickname, r->cache_info.identity_digest,
    217                         ed_id_key,
    218                         r->onion_curve25519_pkey,
    219                         &ap.addr, ap.port,
    220                         /* TODO-324: Should self-test circuits use
    221                          * congestion control? */
    222                         NULL, false);
    223 
    224  return info;
    225 }
    226 
    227 /** Launch a self-testing circuit to one of our ORPorts, using an address from
    228 * <b>family</b> (if available). The circuit can be used to test reachability
    229 * or bandwidth. <b>me</b> is our own routerinfo.
    230 *
    231 * Logs an info-level status message. If <b>orport_reachable</b> is false,
    232 * call it a reachability circuit. Otherwise, call it a bandwidth circuit.
    233 *
    234 * See router_do_reachability_checks() for details. */
    235 static void
    236 router_do_orport_reachability_checks(const routerinfo_t *me,
    237                                     int family,
    238                                     int orport_reachable)
    239 {
    240  extend_info_t *ei = extend_info_from_router(me, family);
    241  int ipv6_flags = (family == AF_INET6 ? CIRCLAUNCH_IS_IPV6_SELFTEST : 0);
    242 
    243  /* If we're trying to test IPv6, but we don't have an IPv6 ORPort, ei will
    244   * be NULL. */
    245  if (ei) {
    246    const char *family_name = fmt_af_family(family);
    247    const tor_addr_port_t *ap = extend_info_get_orport(ei, family);
    248    if (BUG(!ap)) {
    249      /* Not much we can do here to recover apart from screaming loudly. */
    250      extend_info_free(ei);
    251      return;
    252    }
    253    log_info(LD_CIRC, "Testing %s of my %s ORPort: %s.",
    254             !orport_reachable ? "reachability" : "bandwidth",
    255             family_name, fmt_addrport_ap(ap));
    256 
    257    if (!orport_reachable) {
    258      /* Only log if we are actually doing a reachability test to learn if our
    259       * ORPort is reachable. Else, this prints a log notice if we are simply
    260       * opening a bandwidth testing circuit even though we are reachable. */
    261      inform_testing_reachability(&ap->addr, ap->port);
    262    }
    263 
    264    circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
    265                                  CIRCLAUNCH_NEED_CAPACITY|
    266                                  CIRCLAUNCH_IS_INTERNAL|
    267                                  ipv6_flags);
    268    extend_info_free(ei);
    269  }
    270 }
    271 
    272 /** Some time has passed, or we just got new directory information. See if we
    273 * currently believe our ORPort to be unreachable. If so, launch a new test
    274 * for it.
    275 *
    276 * For ORPort, we simply try making a circuit that ends at ourselves.  Success
    277 * is noticed in onionskin_answer().
    278 */
    279 void
    280 router_do_reachability_checks(void)
    281 {
    282  const routerinfo_t *me = router_get_my_routerinfo();
    283  const or_options_t *options = get_options();
    284  int orport_reachable_v4 =
    285    router_orport_seems_reachable(options, AF_INET);
    286  int orport_reachable_v6 =
    287    router_orport_seems_reachable(options, AF_INET6);
    288 
    289  if (router_should_check_reachability()) {
    290    bool need_testing = !circuit_enough_testing_circs();
    291    /* At the moment, tor relays believe that they are reachable when they
    292     * receive any create cell on an inbound connection, if the address
    293     * family is correct.
    294     */
    295    if (!orport_reachable_v4 || need_testing) {
    296      router_do_orport_reachability_checks(me, AF_INET, orport_reachable_v4);
    297    }
    298    if (!orport_reachable_v6 || need_testing) {
    299      router_do_orport_reachability_checks(me, AF_INET6, orport_reachable_v6);
    300    }
    301  }
    302 }
    303 
    304 /** Log a message informing the user that we are testing a port for
    305 * reachability, if we have not already logged such a message.
    306 *
    307 * Calls to router_reset_reachability() will reset our view of whether we have
    308 * logged this message for a given port. */
    309 static void
    310 inform_testing_reachability(const tor_addr_t *addr, uint16_t port)
    311 {
    312  if (!router_get_my_routerinfo())
    313    return;
    314 
    315  bool *have_informed_ptr;
    316  if (tor_addr_family(addr) == AF_INET) {
    317    have_informed_ptr = &have_informed_testing_or_port_ipv4;
    318  } else {
    319    have_informed_ptr = &have_informed_testing_or_port_ipv6;
    320  }
    321 
    322  if (*have_informed_ptr) {
    323    /* We already told the user that we're testing this port; no need to
    324     * do it again. */
    325    return;
    326  }
    327 
    328  char addr_buf[TOR_ADDRPORT_BUF_LEN];
    329  strlcpy(addr_buf, fmt_addrport(addr, port), sizeof(addr_buf));
    330 
    331  const char *afname = fmt_af_family(tor_addr_family(addr));
    332 
    333  control_event_server_status(LOG_NOTICE,
    334                              "CHECKING_REACHABILITY ORADDRESS=%s",
    335                              addr_buf);
    336 
    337  log_notice(LD_OR, "Now checking whether %s ORPort %s is reachable... "
    338             "(this may take up to %d minutes -- look for log "
    339             "messages indicating success)",
    340             afname, addr_buf,
    341             TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT/60);
    342 
    343  *have_informed_ptr = true;
    344 }
    345 
    346 /**
    347 * Return true if this module knows of no reason why we shouldn't publish
    348 * a server descriptor.
    349 **/
    350 static bool
    351 ready_to_publish(const or_options_t *options)
    352 {
    353  return options->PublishServerDescriptor_ != NO_DIRINFO &&
    354         router_all_orports_seem_reachable(options);
    355 }
    356 
    357 /** Annotate that we found our ORPort reachable with a given address
    358 * family. */
    359 void
    360 router_orport_found_reachable(int family)
    361 {
    362  const routerinfo_t *me = router_get_my_routerinfo();
    363  const or_options_t *options = get_options();
    364  const char *reachable_reason = "ORPort found reachable";
    365  bool *can_reach_ptr;
    366  if (family == AF_INET) {
    367    can_reach_ptr = &can_reach_or_port_ipv4;
    368  } else if (family == AF_INET6) {
    369    can_reach_ptr = &can_reach_or_port_ipv6;
    370  } else {
    371    tor_assert_nonfatal_unreached();
    372    return;
    373  }
    374  if (!*can_reach_ptr && me) {
    375    tor_addr_port_t ap;
    376    if (router_get_orport(me, &ap, family) < 0) {
    377      return;
    378    }
    379    char *address = tor_strdup(fmt_addrport_ap(&ap));
    380 
    381    *can_reach_ptr = true;
    382 
    383    log_notice(LD_OR,"Self-testing indicates your ORPort %s is reachable from "
    384               "the outside. Excellent.%s",
    385               address,
    386               ready_to_publish(options) ?
    387               " Publishing server descriptor." : "");
    388 
    389    /* Make sure our descriptor is marked to publish the IPv6 if it is now
    390     * reachable. This can change at runtime. */
    391    if (family == AF_INET6) {
    392      mark_my_descriptor_if_omit_ipv6_changes(reachable_reason, false);
    393    } else {
    394      mark_my_descriptor_dirty(reachable_reason);
    395    }
    396    /* This is a significant enough change to upload immediately,
    397     * at least in a test network */
    398    if (options->TestingTorNetwork == 1) {
    399      reschedule_descriptor_update_check();
    400    }
    401    control_event_server_status(LOG_NOTICE,
    402                                "REACHABILITY_SUCCEEDED ORADDRESS=%s",
    403                                address);
    404    tor_free(address);
    405  }
    406 }
    407 
    408 /** We have enough testing circuits open. Send a bunch of "drop"
    409 * cells down each of them, to exercise our bandwidth.
    410 *
    411 * May use IPv4 and IPv6 testing circuits (if available). */
    412 void
    413 router_perform_bandwidth_test(int num_circs, time_t now)
    414 {
    415  int num_cells = (int)(get_options()->BandwidthRate * 10 /
    416                        CELL_MAX_NETWORK_SIZE);
    417  int max_cells = num_cells < CIRCWINDOW_START ?
    418                    num_cells : CIRCWINDOW_START;
    419  int cells_per_circuit = max_cells / num_circs;
    420  origin_circuit_t *circ = NULL;
    421 
    422  log_notice(LD_OR,"Performing bandwidth self-test...done.");
    423  while ((circ = circuit_get_next_by_purpose(circ,
    424                                             CIRCUIT_PURPOSE_TESTING))) {
    425    /* dump cells_per_circuit drop cells onto this circ */
    426    int i = cells_per_circuit;
    427    if (circ->base_.state != CIRCUIT_STATE_OPEN)
    428      continue;
    429    circ->base_.timestamp_dirty = now;
    430    while (i-- > 0) {
    431      if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
    432                                       RELAY_COMMAND_DROP,
    433                                       NULL, 0, circ->cpath->prev)<0) {
    434        return; /* stop if error */
    435      }
    436    }
    437  }
    438 }