LCOV - code coverage report
Current view: top level - feature/dirauth - reachability.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 81 0.0 %
Date: 2021-11-24 03:28:48 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* Copyright (c) 2001-2004, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file reachability.c
       8             :  * \brief Router reachability testing; run by authorities to tell who is
       9             :  * running.
      10             :  */
      11             : 
      12             : #include "core/or/or.h"
      13             : #include "feature/dirauth/reachability.h"
      14             : 
      15             : #include "app/config/config.h"
      16             : #include "core/or/channel.h"
      17             : #include "core/or/channeltls.h"
      18             : #include "core/or/command.h"
      19             : #include "feature/dirauth/authmode.h"
      20             : #include "feature/dirauth/dirauth_sys.h"
      21             : #include "feature/nodelist/describe.h"
      22             : #include "feature/nodelist/nodelist.h"
      23             : #include "feature/nodelist/routerinfo.h"
      24             : #include "feature/nodelist/routerlist.h"
      25             : #include "feature/nodelist/torcert.h"
      26             : #include "feature/stats/rephist.h"
      27             : 
      28             : #include "feature/dirauth/dirauth_options_st.h"
      29             : #include "feature/nodelist/node_st.h"
      30             : #include "feature/nodelist/routerinfo_st.h"
      31             : #include "feature/nodelist/routerlist_st.h"
      32             : 
      33             : /** Called when a TLS handshake has completed successfully with a
      34             :  * router listening at <b>address</b>:<b>or_port</b>, and has yielded
      35             :  * a certificate with digest <b>digest_rcvd</b>.
      36             :  *
      37             :  * Inform the reachability checker that we could get to this relay.
      38             :  */
      39             : void
      40           0 : dirserv_orconn_tls_done(const tor_addr_t *addr,
      41             :                         uint16_t or_port,
      42             :                         const char *digest_rcvd,
      43             :                         const ed25519_public_key_t *ed_id_rcvd)
      44             : {
      45           0 :   node_t *node = NULL;
      46           0 :   tor_addr_port_t orport;
      47           0 :   routerinfo_t *ri = NULL;
      48           0 :   time_t now = time(NULL);
      49           0 :   tor_assert(addr);
      50           0 :   tor_assert(digest_rcvd);
      51             : 
      52           0 :   node = node_get_mutable_by_id(digest_rcvd);
      53           0 :   if (node == NULL || node->ri == NULL)
      54           0 :     return;
      55             : 
      56           0 :   ri = node->ri;
      57             : 
      58           0 :   if (dirauth_get_options()->AuthDirTestEd25519LinkKeys &&
      59           0 :       node_supports_ed25519_link_authentication(node, 1) &&
      60           0 :       ri->cache_info.signing_key_cert) {
      61             :     /* We allow the node to have an ed25519 key if we haven't been told one in
      62             :      * the routerinfo, but if we *HAVE* been told one in the routerinfo, it
      63             :      * needs to match. */
      64           0 :     const ed25519_public_key_t *expected_id =
      65             :       &ri->cache_info.signing_key_cert->signing_key;
      66           0 :     tor_assert(!ed25519_public_key_is_zero(expected_id));
      67           0 :     if (! ed_id_rcvd || ! ed25519_pubkey_eq(ed_id_rcvd, expected_id)) {
      68           0 :       log_info(LD_DIRSERV, "Router at %s:%d with RSA ID %s "
      69             :                "did not present expected Ed25519 ID.",
      70             :                fmt_addr(addr), or_port, hex_str(digest_rcvd, DIGEST_LEN));
      71           0 :       return; /* Don't mark it as reachable. */
      72             :     }
      73             :   }
      74             : 
      75           0 :   tor_addr_copy(&orport.addr, addr);
      76           0 :   orport.port = or_port;
      77           0 :   if (router_has_orport(ri, &orport)) {
      78             :     /* Found the right router.  */
      79           0 :     if (!authdir_mode_bridge(get_options()) ||
      80           0 :         ri->purpose == ROUTER_PURPOSE_BRIDGE) {
      81           0 :       char addrstr[TOR_ADDR_BUF_LEN];
      82             :       /* This is a bridge or we're not a bridge authority --
      83             :          mark it as reachable.  */
      84           0 :       log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.",
      85             :                router_describe(ri),
      86             :                tor_addr_to_str(addrstr, addr, sizeof(addrstr), 1),
      87             :                ri->ipv4_orport);
      88           0 :       if (tor_addr_family(addr) == AF_INET) {
      89           0 :         rep_hist_note_router_reachable(digest_rcvd, addr, or_port, now);
      90           0 :         node->last_reachable = now;
      91           0 :       } else if (tor_addr_family(addr) == AF_INET6) {
      92             :         /* No rephist for IPv6.  */
      93           0 :         node->last_reachable6 = now;
      94             :       }
      95             :     }
      96             :   }
      97             : }
      98             : 
      99             : /** Called when we, as an authority, receive a new router descriptor either as
     100             :  * an upload or a download.  Used to decide whether to relaunch reachability
     101             :  * testing for the server. */
     102             : int
     103           0 : dirserv_should_launch_reachability_test(const routerinfo_t *ri,
     104             :                                         const routerinfo_t *ri_old)
     105             : {
     106           0 :   if (!authdir_mode_handles_descs(get_options(), ri->purpose))
     107             :     return 0;
     108           0 :   if (! dirauth_get_options()->AuthDirTestReachability)
     109             :     return 0;
     110           0 :   if (!ri_old) {
     111             :     /* New router: Launch an immediate reachability test, so we will have an
     112             :      * opinion soon in case we're generating a consensus soon */
     113           0 :     log_info(LD_DIR, "descriptor for new router %s", router_describe(ri));
     114           0 :     return 1;
     115             :   }
     116           0 :   if (ri_old->is_hibernating && !ri->is_hibernating) {
     117             :     /* It just came out of hibernation; launch a reachability test */
     118           0 :     log_info(LD_DIR, "out of hibernation: router %s", router_describe(ri));
     119           0 :     return 1;
     120             :   }
     121           0 :   if (! routers_have_same_or_addrs(ri, ri_old)) {
     122             :     /* Address or port changed; launch a reachability test */
     123           0 :     log_info(LD_DIR, "address or port changed: router %s",
     124             :              router_describe(ri));
     125           0 :     return 1;
     126             :   }
     127             :   return 0;
     128             : }
     129             : 
     130             : /** Helper function for dirserv_test_reachability(). Start a TLS
     131             :  * connection to <b>router</b>, and annotate it with when we started
     132             :  * the test. */
     133             : void
     134           0 : dirserv_single_reachability_test(time_t now, routerinfo_t *router)
     135             : {
     136           0 :   const dirauth_options_t *dirauth_options = dirauth_get_options();
     137           0 :   channel_t *chan = NULL;
     138           0 :   const node_t *node = NULL;
     139           0 :   const ed25519_public_key_t *ed_id_key;
     140           0 :   (void) now;
     141             : 
     142           0 :   tor_assert(router);
     143           0 :   node = node_get_by_id(router->cache_info.identity_digest);
     144           0 :   tor_assert(node);
     145             : 
     146           0 :   if (dirauth_options->AuthDirTestEd25519LinkKeys &&
     147           0 :       node_supports_ed25519_link_authentication(node, 1) &&
     148           0 :       router->cache_info.signing_key_cert) {
     149           0 :     ed_id_key = &router->cache_info.signing_key_cert->signing_key;
     150             :   } else {
     151             :     ed_id_key = NULL;
     152             :   }
     153             : 
     154             :   /* IPv4. */
     155           0 :   log_info(LD_OR,"Testing reachability of %s at %s:%u.",
     156             :             router->nickname, fmt_addr(&router->ipv4_addr),
     157             :             router->ipv4_orport);
     158           0 :   chan = channel_tls_connect(&router->ipv4_addr, router->ipv4_orport,
     159             :                              router->cache_info.identity_digest,
     160             :                              ed_id_key);
     161           0 :   if (chan) command_setup_channel(chan);
     162             : 
     163             :   /* Possible IPv6. */
     164           0 :   if (dirauth_get_options()->AuthDirHasIPv6Connectivity == 1 &&
     165           0 :       !tor_addr_is_null(&router->ipv6_addr)) {
     166           0 :     char addrstr[TOR_ADDR_BUF_LEN];
     167           0 :     log_info(LD_OR, "Testing reachability of %s at %s:%u.",
     168             :              router->nickname,
     169             :              tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1),
     170             :              router->ipv6_orport);
     171           0 :     chan = channel_tls_connect(&router->ipv6_addr, router->ipv6_orport,
     172             :                                router->cache_info.identity_digest,
     173             :                                ed_id_key);
     174           0 :     if (chan) command_setup_channel(chan);
     175             :   }
     176           0 : }
     177             : 
     178             : /** Auth dir server only: load balance such that we only
     179             :  * try a few connections per call.
     180             :  *
     181             :  * The load balancing is such that if we get called once every ten
     182             :  * seconds, we will cycle through all the tests in
     183             :  * REACHABILITY_TEST_CYCLE_PERIOD seconds (a bit over 20 minutes).
     184             :  */
     185             : void
     186           0 : dirserv_test_reachability(time_t now)
     187             : {
     188             :   /* XXX decide what to do here; see or-talk thread "purging old router
     189             :    * information, revocation." -NM
     190             :    * We can't afford to mess with this in 0.1.2.x. The reason is that
     191             :    * if we stop doing reachability tests on some of routerlist, then
     192             :    * we'll for-sure think they're down, which may have unexpected
     193             :    * effects in other parts of the code. It doesn't hurt much to do
     194             :    * the testing, and directory authorities are easy to upgrade. Let's
     195             :    * wait til 0.2.0. -RD */
     196             : //  time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
     197           0 :   if (! dirauth_get_options()->AuthDirTestReachability)
     198             :     return;
     199             : 
     200           0 :   routerlist_t *rl = router_get_routerlist();
     201           0 :   static char ctr = 0;
     202           0 :   int bridge_auth = authdir_mode_bridge(get_options());
     203             : 
     204           0 :   SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
     205           0 :     const char *id_digest = router->cache_info.identity_digest;
     206           0 :     if (router_is_me(router))
     207           0 :       continue;
     208           0 :     if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
     209           0 :       continue; /* bridge authorities only test reachability on bridges */
     210             : //    if (router->cache_info.published_on > cutoff)
     211             : //      continue;
     212           0 :     if ((((uint8_t)id_digest[0]) % REACHABILITY_MODULO_PER_TEST) == ctr) {
     213           0 :       dirserv_single_reachability_test(now, router);
     214             :     }
     215           0 :   } SMARTLIST_FOREACH_END(router);
     216           0 :   ctr = (ctr + 1) % REACHABILITY_MODULO_PER_TEST; /* increment ctr */
     217             : }

Generated by: LCOV version 1.14