LCOV - code coverage report
Current view: top level - feature/nodelist - networkstatus.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 644 1104 58.3 %
Date: 2021-11-24 03:28:48 Functions: 64 85 75.3 %

          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 networkstatus.c
       9             :  * \brief Functions and structures for handling networkstatus documents as a
      10             :  * client or as a directory cache.
      11             :  *
      12             :  * A consensus networkstatus object is created by the directory
      13             :  * authorities.  It authenticates a set of network parameters--most
      14             :  * importantly, the list of all the relays in the network.  This list
      15             :  * of relays is represented as an array of routerstatus_t objects.
      16             :  *
      17             :  * There are currently two flavors of consensus.  With the older "NS"
      18             :  * flavor, each relay is associated with a digest of its router
      19             :  * descriptor. Tor instances that use this consensus keep the list of
      20             :  * router descriptors as routerinfo_t objects stored and managed in
      21             :  * routerlist.c.  With the newer "microdesc" flavor, each relay is
      22             :  * associated with a digest of the microdescriptor that the authorities
      23             :  * made for it.  These are stored and managed in microdesc.c. Information
      24             :  * about the router is divided between the the networkstatus and the
      25             :  * microdescriptor according to the general rule that microdescriptors
      26             :  * should hold information that changes much less frequently than the
      27             :  * information in the networkstatus.
      28             :  *
      29             :  * Modern clients use microdescriptor networkstatuses.  Directory caches
      30             :  * need to keep both kinds of networkstatus document, so they can serve them.
      31             :  *
      32             :  * This module manages fetching, holding, storing, updating, and
      33             :  * validating networkstatus objects.  The download-and-validate process
      34             :  * is slightly complicated by the fact that the keys you need to
      35             :  * validate a consensus are stored in the authority certificates, which
      36             :  * you might not have yet when you download the consensus.
      37             :  */
      38             : 
      39             : #define NETWORKSTATUS_PRIVATE
      40             : #include "core/or/or.h"
      41             : #include "app/config/config.h"
      42             : #include "core/mainloop/connection.h"
      43             : #include "core/mainloop/mainloop.h"
      44             : #include "core/mainloop/netstatus.h"
      45             : #include "core/or/channel.h"
      46             : #include "core/or/channelpadding.h"
      47             : #include "core/or/circuitpadding.h"
      48             : #include "core/or/circuitmux.h"
      49             : #include "core/or/circuitmux_ewma.h"
      50             : #include "core/or/circuitstats.h"
      51             : #include "core/or/connection_edge.h"
      52             : #include "core/or/connection_or.h"
      53             : #include "core/or/dos.h"
      54             : #include "core/or/protover.h"
      55             : #include "core/or/relay.h"
      56             : #include "core/or/scheduler.h"
      57             : #include "core/or/versions.h"
      58             : #include "feature/client/bridges.h"
      59             : #include "feature/client/entrynodes.h"
      60             : #include "feature/client/transports.h"
      61             : #include "feature/control/control_events.h"
      62             : #include "feature/dirauth/reachability.h"
      63             : #include "feature/dircache/consdiffmgr.h"
      64             : #include "feature/dircache/dirserv.h"
      65             : #include "feature/dirclient/dirclient.h"
      66             : #include "feature/dirclient/dirclient_modes.h"
      67             : #include "feature/dirclient/dlstatus.h"
      68             : #include "feature/dircommon/directory.h"
      69             : #include "feature/dirauth/voting_schedule.h"
      70             : #include "feature/dirparse/ns_parse.h"
      71             : #include "feature/hibernate/hibernate.h"
      72             : #include "feature/hs/hs_dos.h"
      73             : #include "feature/nodelist/authcert.h"
      74             : #include "feature/nodelist/dirlist.h"
      75             : #include "feature/nodelist/fmt_routerstatus.h"
      76             : #include "feature/nodelist/microdesc.h"
      77             : #include "feature/nodelist/networkstatus.h"
      78             : #include "feature/nodelist/node_select.h"
      79             : #include "feature/nodelist/nodelist.h"
      80             : #include "feature/nodelist/routerinfo.h"
      81             : #include "feature/nodelist/routerlist.h"
      82             : #include "feature/nodelist/torcert.h"
      83             : #include "feature/relay/routermode.h"
      84             : #include "lib/crypt_ops/crypto_rand.h"
      85             : #include "lib/crypt_ops/crypto_util.h"
      86             : 
      87             : #include "feature/dirauth/dirauth_periodic.h"
      88             : #include "feature/dirauth/dirvote.h"
      89             : #include "feature/dirauth/authmode.h"
      90             : #include "feature/dirauth/shared_random.h"
      91             : #include "feature/dirauth/voteflags.h"
      92             : 
      93             : #include "feature/nodelist/authority_cert_st.h"
      94             : #include "feature/dircommon/dir_connection_st.h"
      95             : #include "feature/dirclient/dir_server_st.h"
      96             : #include "feature/nodelist/document_signature_st.h"
      97             : #include "feature/nodelist/networkstatus_st.h"
      98             : #include "feature/nodelist/networkstatus_voter_info_st.h"
      99             : #include "feature/dirauth/ns_detached_signatures_st.h"
     100             : #include "feature/nodelist/node_st.h"
     101             : #include "feature/nodelist/routerinfo_st.h"
     102             : #include "feature/nodelist/routerlist_st.h"
     103             : #include "feature/dirauth/vote_microdesc_hash_st.h"
     104             : #include "feature/nodelist/vote_routerstatus_st.h"
     105             : #include "feature/nodelist/routerstatus_st.h"
     106             : 
     107             : #ifdef HAVE_UNISTD_H
     108             : #include <unistd.h>
     109             : #endif
     110             : 
     111             : /** Most recently received and validated v3 "ns"-flavored consensus network
     112             :  * status. */
     113             : STATIC networkstatus_t *current_ns_consensus = NULL;
     114             : 
     115             : /** Most recently received and validated v3 "microdesc"-flavored consensus
     116             :  * network status. */
     117             : STATIC networkstatus_t *current_md_consensus = NULL;
     118             : 
     119             : /** A v3 consensus networkstatus that we've received, but which we don't
     120             :  * have enough certificates to be happy about. */
     121             : typedef struct consensus_waiting_for_certs_t {
     122             :   /** The consensus itself. */
     123             :   networkstatus_t *consensus;
     124             :   /** When did we set the current value of consensus_waiting_for_certs?  If
     125             :    * this is too recent, we shouldn't try to fetch a new consensus for a
     126             :    * little while, to give ourselves time to get certificates for this one. */
     127             :   time_t set_at;
     128             :   /** Set to 1 if we've been holding on to it for so long we should maybe
     129             :    * treat it as being bad. */
     130             :   int dl_failed;
     131             : } consensus_waiting_for_certs_t;
     132             : 
     133             : /** An array, for each flavor of consensus we might want, of consensuses that
     134             :  * we have downloaded, but which we cannot verify due to having insufficient
     135             :  * authority certificates. */
     136             : static consensus_waiting_for_certs_t
     137             :        consensus_waiting_for_certs[N_CONSENSUS_FLAVORS];
     138             : 
     139             : /** A time before which we shouldn't try to replace the current consensus:
     140             :  * this will be at some point after the next consensus becomes valid, but
     141             :  * before the current consensus becomes invalid. */
     142             : static time_t time_to_download_next_consensus[N_CONSENSUS_FLAVORS];
     143             : /** Download status for the current consensus networkstatus. */
     144             : static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS] =
     145             :   {
     146             :     { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
     147             :       DL_SCHED_INCREMENT_FAILURE, 0, 0 },
     148             :     { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
     149             :       DL_SCHED_INCREMENT_FAILURE, 0, 0 },
     150             :   };
     151             : 
     152             : #define N_CONSENSUS_BOOTSTRAP_SCHEDULES 2
     153             : #define CONSENSUS_BOOTSTRAP_SOURCE_AUTHORITY 0
     154             : #define CONSENSUS_BOOTSTRAP_SOURCE_ANY_DIRSERVER  1
     155             : 
     156             : /* Using DL_SCHED_INCREMENT_ATTEMPT on these schedules means that
     157             :  * download_status_increment_failure won't increment these entries.
     158             :  * However, any bootstrap connection failures that occur after we have
     159             :  * a valid consensus will count against the failure counts on the non-bootstrap
     160             :  * schedules. There should only be one of these, as all the others will have
     161             :  * been cancelled. (This doesn't seem to be a significant issue.) */
     162             : static download_status_t
     163             :               consensus_bootstrap_dl_status[N_CONSENSUS_BOOTSTRAP_SCHEDULES] =
     164             :   {
     165             :     { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
     166             :       DL_SCHED_INCREMENT_ATTEMPT, 0, 0 },
     167             :     /* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
     168             :     { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
     169             :       DL_SCHED_INCREMENT_ATTEMPT, 0, 0 },
     170             :   };
     171             : 
     172             : /** True iff we have logged a warning about this OR's version being older than
     173             :  * listed by the authorities. */
     174             : static int have_warned_about_old_version = 0;
     175             : /** True iff we have logged a warning about this OR's version being newer than
     176             :  * listed by the authorities. */
     177             : static int have_warned_about_new_version = 0;
     178             : 
     179             : static void update_consensus_bootstrap_multiple_downloads(
     180             :                                                   time_t now,
     181             :                                                   const or_options_t *options);
     182             : static int networkstatus_check_required_protocols(const networkstatus_t *ns,
     183             :                                                   int client_mode,
     184             :                                                   char **warning_out);
     185             : static int reload_consensus_from_file(const char *fname,
     186             :                                       const char *flavor,
     187             :                                       unsigned flags,
     188             :                                       const char *source_dir);
     189             : 
     190             : /** Forget that we've warned about anything networkstatus-related, so we will
     191             :  * give fresh warnings if the same behavior happens again. */
     192             : void
     193           0 : networkstatus_reset_warnings(void)
     194             : {
     195           0 :   SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node,
     196             :                     node->name_lookup_warned = 0);
     197             : 
     198           0 :   have_warned_about_old_version = 0;
     199           0 :   have_warned_about_new_version = 0;
     200           0 : }
     201             : 
     202             : /** Reset the descriptor download failure count on all networkstatus docs, so
     203             :  * that we can retry any long-failed documents immediately.
     204             :  */
     205             : void
     206           0 : networkstatus_reset_download_failures(void)
     207             : {
     208           0 :   int i;
     209             : 
     210           0 :   log_debug(LD_GENERAL,
     211             :             "In networkstatus_reset_download_failures()");
     212             : 
     213           0 :   for (i=0; i < N_CONSENSUS_FLAVORS; ++i)
     214           0 :     download_status_reset(&consensus_dl_status[i]);
     215             : 
     216           0 :   for (i=0; i < N_CONSENSUS_BOOTSTRAP_SCHEDULES; ++i)
     217           0 :     download_status_reset(&consensus_bootstrap_dl_status[i]);
     218           0 : }
     219             : 
     220             : /** Return the filename used to cache the consensus of a given flavor */
     221           2 : MOCK_IMPL(char *,
     222             : networkstatus_get_cache_fname,(int flav,
     223             :                                const char *flavorname,
     224             :                                int unverified_consensus))
     225             : {
     226           2 :   char buf[128];
     227           2 :   const char *prefix;
     228           2 :   if (unverified_consensus) {
     229             :     prefix = "unverified";
     230             :   } else {
     231           2 :     prefix = "cached";
     232             :   }
     233           2 :   if (flav == FLAV_NS) {
     234           1 :     tor_snprintf(buf, sizeof(buf), "%s-consensus", prefix);
     235             :   } else {
     236           1 :     tor_snprintf(buf, sizeof(buf), "%s-%s-consensus", prefix, flavorname);
     237             :   }
     238             : 
     239           2 :   return get_cachedir_fname(buf);
     240             : }
     241             : 
     242             : /**
     243             :  * Read and return the cached consensus of type <b>flavorname</b>.  If
     244             :  * <b>unverified</b> is false, get the one we haven't verified. Return NULL if
     245             :  * the file isn't there. */
     246             : static tor_mmap_t *
     247           2 : networkstatus_map_cached_consensus_impl(int flav,
     248             :                                         const char *flavorname,
     249             :                                         int unverified_consensus)
     250             : {
     251           2 :   char *filename = networkstatus_get_cache_fname(flav,
     252             :                                                  flavorname,
     253             :                                                  unverified_consensus);
     254           2 :   tor_mmap_t *result = tor_mmap_file(filename);
     255           2 :   tor_free(filename);
     256           2 :   return result;
     257             : }
     258             : 
     259             : /** Map the file containing the current cached consensus of flavor
     260             :  * <b>flavorname</b> */
     261             : tor_mmap_t *
     262           2 : networkstatus_map_cached_consensus(const char *flavorname)
     263             : {
     264           2 :   int flav = networkstatus_parse_flavor_name(flavorname);
     265           2 :   if (flav < 0)
     266             :     return NULL;
     267           2 :   return networkstatus_map_cached_consensus_impl(flav, flavorname, 0);
     268             : }
     269             : 
     270             : /** Read every cached v3 consensus networkstatus from the disk. */
     271             : int
     272           0 : router_reload_consensus_networkstatus(void)
     273             : {
     274           0 :   const unsigned int flags = NSSET_FROM_CACHE | NSSET_DONT_DOWNLOAD_CERTS;
     275           0 :   int flav;
     276             : 
     277             :   /* FFFF Suppress warnings if cached consensus is bad? */
     278           0 :   for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
     279           0 :     const char *flavor = networkstatus_get_flavor_name(flav);
     280           0 :     char *fname = networkstatus_get_cache_fname(flav, flavor, 0);
     281           0 :     reload_consensus_from_file(fname, flavor, flags, NULL);
     282           0 :     tor_free(fname);
     283             : 
     284           0 :     fname = networkstatus_get_cache_fname(flav, flavor, 1);
     285           0 :     reload_consensus_from_file(fname, flavor,
     286             :                                flags | NSSET_WAS_WAITING_FOR_CERTS,
     287             :                                NULL);
     288           0 :     tor_free(fname);
     289             :   }
     290             : 
     291           0 :   update_certificate_downloads(time(NULL));
     292             : 
     293           0 :   routers_update_all_from_networkstatus(time(NULL), 3);
     294           0 :   update_microdescs_from_networkstatus(time(NULL));
     295             : 
     296           0 :   return 0;
     297             : }
     298             : 
     299             : /** Free all storage held by the vote_routerstatus object <b>rs</b>. */
     300             : void
     301         612 : vote_routerstatus_free_(vote_routerstatus_t *rs)
     302             : {
     303         612 :   vote_microdesc_hash_t *h, *next;
     304         612 :   if (!rs)
     305         612 :     return;
     306         612 :   tor_free(rs->version);
     307         612 :   tor_free(rs->protocols);
     308         612 :   tor_free(rs->status.exitsummary);
     309        1044 :   for (h = rs->microdesc; h; h = next) {
     310         432 :     tor_free(h->microdesc_hash_line);
     311         432 :     next = h->next;
     312         432 :     tor_free(h);
     313             :   }
     314         612 :   tor_free(rs);
     315             : }
     316             : 
     317             : /** Free all storage held by the routerstatus object <b>rs</b>. */
     318             : void
     319        6740 : routerstatus_free_(routerstatus_t *rs)
     320             : {
     321        6740 :   if (!rs)
     322             :     return;
     323        6739 :   tor_free(rs->exitsummary);
     324        6739 :   tor_free(rs);
     325             : }
     326             : 
     327             : /** Free all storage held in <b>sig</b> */
     328             : void
     329         236 : document_signature_free_(document_signature_t *sig)
     330             : {
     331         236 :   tor_free(sig->signature);
     332         236 :   tor_free(sig);
     333         236 : }
     334             : 
     335             : /** Return a newly allocated copy of <b>sig</b> */
     336             : document_signature_t *
     337          12 : document_signature_dup(const document_signature_t *sig)
     338             : {
     339          12 :   document_signature_t *r = tor_memdup(sig, sizeof(document_signature_t));
     340          12 :   if (r->signature)
     341          12 :     r->signature = tor_memdup(sig->signature, sig->signature_len);
     342          12 :   return r;
     343             : }
     344             : 
     345             : /** Free all storage held in <b>ns</b>. */
     346             : void
     347        4096 : networkstatus_vote_free_(networkstatus_t *ns)
     348             : {
     349        4096 :   if (!ns)
     350             :     return;
     351             : 
     352        2351 :   tor_free(ns->client_versions);
     353        2351 :   tor_free(ns->server_versions);
     354        2351 :   tor_free(ns->recommended_client_protocols);
     355        2351 :   tor_free(ns->recommended_relay_protocols);
     356        2351 :   tor_free(ns->required_client_protocols);
     357        2351 :   tor_free(ns->required_relay_protocols);
     358             : 
     359        2351 :   if (ns->known_flags) {
     360        5428 :     SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
     361        1820 :     smartlist_free(ns->known_flags);
     362             :   }
     363        2351 :   if (ns->weight_params) {
     364        1035 :     SMARTLIST_FOREACH(ns->weight_params, char *, c, tor_free(c));
     365          51 :     smartlist_free(ns->weight_params);
     366             :   }
     367        2351 :   if (ns->net_params) {
     368        3078 :     SMARTLIST_FOREACH(ns->net_params, char *, c, tor_free(c));
     369         383 :     smartlist_free(ns->net_params);
     370             :   }
     371        2351 :   if (ns->supported_methods) {
     372        3333 :     SMARTLIST_FOREACH(ns->supported_methods, char *, c, tor_free(c));
     373         398 :     smartlist_free(ns->supported_methods);
     374             :   }
     375        2351 :   if (ns->package_lines) {
     376        1989 :     SMARTLIST_FOREACH(ns->package_lines, char *, c, tor_free(c));
     377        1793 :     smartlist_free(ns->package_lines);
     378             :   }
     379        2351 :   if (ns->voters) {
     380        5294 :     SMARTLIST_FOREACH_BEGIN(ns->voters, networkstatus_voter_info_t *, voter) {
     381        3507 :       tor_free(voter->nickname);
     382        3507 :       tor_free(voter->address);
     383        3507 :       tor_free(voter->contact);
     384        3507 :       if (voter->sigs) {
     385        3698 :         SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
     386             :                           document_signature_free(sig));
     387        3480 :         smartlist_free(voter->sigs);
     388             :       }
     389        3507 :       tor_free(voter);
     390        3507 :     } SMARTLIST_FOREACH_END(voter);
     391        1787 :     smartlist_free(ns->voters);
     392             :   }
     393        2351 :   authority_cert_free(ns->cert);
     394             : 
     395        2351 :   if (ns->routerstatus_list) {
     396        1754 :     if (ns->type == NS_TYPE_VOTE || ns->type == NS_TYPE_OPINION) {
     397         782 :       SMARTLIST_FOREACH(ns->routerstatus_list, vote_routerstatus_t *, rs,
     398             :                         vote_routerstatus_free(rs));
     399             :     } else {
     400        1961 :       SMARTLIST_FOREACH(ns->routerstatus_list, routerstatus_t *, rs,
     401             :                         routerstatus_free(rs));
     402             :     }
     403             : 
     404        1754 :     smartlist_free(ns->routerstatus_list);
     405             :   }
     406             : 
     407        2351 :   if (ns->bw_file_headers) {
     408           0 :     SMARTLIST_FOREACH(ns->bw_file_headers, char *, c, tor_free(c));
     409           0 :     smartlist_free(ns->bw_file_headers);
     410             :   }
     411             : 
     412        2351 :   digestmap_free(ns->desc_digest_map, NULL);
     413             : 
     414        2351 :   if (ns->sr_info.commits) {
     415         158 :     dirvote_clear_commits(ns);
     416             :   }
     417        2351 :   tor_free(ns->sr_info.previous_srv);
     418        2351 :   tor_free(ns->sr_info.current_srv);
     419             : 
     420        2351 :   memwipe(ns, 11, sizeof(*ns));
     421        2351 :   tor_free(ns);
     422             : }
     423             : 
     424             : /** Return the voter info from <b>vote</b> for the voter whose identity digest
     425             :  * is <b>identity</b>, or NULL if no such voter is associated with
     426             :  * <b>vote</b>. */
     427             : networkstatus_voter_info_t *
     428         376 : networkstatus_get_voter_by_id(networkstatus_t *vote,
     429             :                               const char *identity)
     430             : {
     431         376 :   if (!vote || !vote->voters)
     432             :     return NULL;
     433        1001 :   SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter,
     434             :     if (fast_memeq(voter->identity_digest, identity, DIGEST_LEN))
     435             :       return voter);
     436             :   return NULL;
     437             : }
     438             : 
     439             : /** Return the signature made by <b>voter</b> using the algorithm
     440             :  * <b>alg</b>, or NULL if none is found. */
     441             : document_signature_t *
     442         367 : networkstatus_get_voter_sig_by_alg(const networkstatus_voter_info_t *voter,
     443             :                                    digest_algorithm_t alg)
     444             : {
     445         367 :   if (!voter->sigs)
     446             :     return NULL;
     447         709 :   SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
     448             :                     if (sig->alg == alg)
     449             :                     return sig);
     450             :   return NULL;
     451             : }
     452             : 
     453             : /** Check whether the signature <b>sig</b> is correctly signed with the
     454             :  * signing key in <b>cert</b>.  Return -1 if <b>cert</b> doesn't match the
     455             :  * signing key; otherwise set the good_signature or bad_signature flag on
     456             :  * <b>voter</b>, and return 0. */
     457             : int
     458           9 : networkstatus_check_document_signature(const networkstatus_t *consensus,
     459             :                                        document_signature_t *sig,
     460             :                                        const authority_cert_t *cert)
     461             : {
     462           9 :   char key_digest[DIGEST_LEN];
     463           9 :   const int dlen = sig->alg == DIGEST_SHA1 ? DIGEST_LEN : DIGEST256_LEN;
     464           9 :   char *signed_digest;
     465           9 :   size_t signed_digest_len;
     466             : 
     467           9 :   if (crypto_pk_get_digest(cert->signing_key, key_digest)<0)
     468             :     return -1;
     469          18 :   if (tor_memneq(sig->signing_key_digest, key_digest, DIGEST_LEN) ||
     470           9 :       tor_memneq(sig->identity_digest, cert->cache_info.identity_digest,
     471             :                  DIGEST_LEN))
     472           0 :     return -1;
     473             : 
     474           9 :   if (authority_cert_is_denylisted(cert)) {
     475             :     /* We implement denylisting for authority signing keys by treating
     476             :      * all their signatures as always bad. That way we don't get into
     477             :      * crazy loops of dropping and re-fetching signatures. */
     478           0 :     log_warn(LD_DIR, "Ignoring a consensus signature made with deprecated"
     479             :              " signing key %s",
     480             :              hex_str(cert->signing_key_digest, DIGEST_LEN));
     481           0 :     sig->bad_signature = 1;
     482           0 :     return 0;
     483             :   }
     484             : 
     485           9 :   signed_digest_len = crypto_pk_keysize(cert->signing_key);
     486           9 :   signed_digest = tor_malloc(signed_digest_len);
     487           9 :   if (crypto_pk_public_checksig(cert->signing_key,
     488             :                                 signed_digest,
     489             :                                 signed_digest_len,
     490           9 :                                 sig->signature,
     491          18 :                                 sig->signature_len) < dlen ||
     492           9 :       tor_memneq(signed_digest, consensus->digests.d[sig->alg], dlen)) {
     493           0 :     log_warn(LD_DIR, "Got a bad signature on a networkstatus vote");
     494           0 :     sig->bad_signature = 1;
     495             :   } else {
     496           9 :     sig->good_signature = 1;
     497             :   }
     498           9 :   tor_free(signed_digest);
     499           9 :   return 0;
     500             : }
     501             : 
     502             : /** Given a v3 networkstatus consensus in <b>consensus</b>, check every
     503             :  * as-yet-unchecked signature on <b>consensus</b>.  Return 1 if there is a
     504             :  * signature from every recognized authority on it, 0 if there are
     505             :  * enough good signatures from recognized authorities on it, -1 if we might
     506             :  * get enough good signatures by fetching missing certificates, and -2
     507             :  * otherwise.  Log messages at INFO or WARN: if <b>warn</b> is over 1, warn
     508             :  * about every problem; if warn is at least 1, warn only if we can't get
     509             :  * enough signatures; if warn is negative, log nothing at all. */
     510             : int
     511           5 : networkstatus_check_consensus_signature(networkstatus_t *consensus,
     512             :                                         int warn)
     513             : {
     514           5 :   int n_good = 0;
     515           5 :   int n_missing_key = 0, n_dl_failed_key = 0;
     516           5 :   int n_bad = 0;
     517           5 :   int n_unknown = 0;
     518           5 :   int n_no_signature = 0;
     519           5 :   int n_v3_authorities = get_n_authorities(V3_DIRINFO);
     520           5 :   int n_required = n_v3_authorities/2 + 1;
     521           5 :   smartlist_t *list_good = smartlist_new();
     522           5 :   smartlist_t *list_no_signature = smartlist_new();
     523           5 :   smartlist_t *need_certs_from = smartlist_new();
     524           5 :   smartlist_t *unrecognized = smartlist_new();
     525           5 :   smartlist_t *missing_authorities = smartlist_new();
     526           5 :   int severity;
     527           5 :   time_t now = time(NULL);
     528             : 
     529           5 :   tor_assert(consensus->type == NS_TYPE_CONSENSUS);
     530             : 
     531          25 :   SMARTLIST_FOREACH_BEGIN(consensus->voters, networkstatus_voter_info_t *,
     532             :                           voter) {
     533          20 :     int good_here = 0;
     534          20 :     int bad_here = 0;
     535          20 :     int unknown_here = 0;
     536          20 :     int missing_key_here = 0, dl_failed_key_here = 0;
     537          30 :     SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
     538          10 :       if (!sig->good_signature && !sig->bad_signature &&
     539          10 :           sig->signature) {
     540             :         /* we can try to check the signature. */
     541          20 :         int is_v3_auth = trusteddirserver_get_by_v3_auth_digest(
     542          10 :                                               sig->identity_digest) != NULL;
     543          10 :         authority_cert_t *cert =
     544          20 :           authority_cert_get_by_digests(sig->identity_digest,
     545          10 :                                         sig->signing_key_digest);
     546          10 :         tor_assert(tor_memeq(sig->identity_digest, voter->identity_digest,
     547             :                            DIGEST_LEN));
     548             : 
     549          10 :         if (!is_v3_auth) {
     550          10 :           smartlist_add(unrecognized, voter);
     551          10 :           ++unknown_here;
     552          10 :           continue;
     553           0 :         } else if (!cert || cert->expires < now) {
     554           0 :           smartlist_add(need_certs_from, voter);
     555           0 :           ++missing_key_here;
     556           0 :           if (authority_cert_dl_looks_uncertain(sig->identity_digest))
     557           0 :             ++dl_failed_key_here;
     558           0 :           continue;
     559             :         }
     560           0 :         if (networkstatus_check_document_signature(consensus, sig, cert) < 0) {
     561           0 :           smartlist_add(need_certs_from, voter);
     562           0 :           ++missing_key_here;
     563           0 :           if (authority_cert_dl_looks_uncertain(sig->identity_digest))
     564           0 :             ++dl_failed_key_here;
     565           0 :           continue;
     566             :         }
     567             :       }
     568           0 :       if (sig->good_signature)
     569           0 :         ++good_here;
     570           0 :       else if (sig->bad_signature)
     571           0 :         ++bad_here;
     572          10 :     } SMARTLIST_FOREACH_END(sig);
     573             : 
     574          20 :     if (good_here) {
     575           0 :       ++n_good;
     576           0 :       smartlist_add(list_good, voter->nickname);
     577          20 :     } else if (bad_here) {
     578           0 :       ++n_bad;
     579          20 :     } else if (missing_key_here) {
     580           0 :       ++n_missing_key;
     581           0 :       if (dl_failed_key_here)
     582           0 :         ++n_dl_failed_key;
     583          20 :     } else if (unknown_here) {
     584          10 :       ++n_unknown;
     585             :     } else {
     586          10 :       ++n_no_signature;
     587          10 :       smartlist_add(list_no_signature, voter->nickname);
     588             :     }
     589          20 :   } SMARTLIST_FOREACH_END(voter);
     590             : 
     591             :   /* Now see whether we're missing any voters entirely. */
     592           5 :   SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
     593             :                     dir_server_t *, ds,
     594             :     {
     595             :       if ((ds->type & V3_DIRINFO) &&
     596             :           !networkstatus_get_voter_by_id(consensus, ds->v3_identity_digest))
     597             :         smartlist_add(missing_authorities, ds);
     598             :     });
     599             : 
     600           5 :   if (warn > 1 || (warn >= 0 &&
     601           5 :                    (n_good + n_missing_key - n_dl_failed_key < n_required))) {
     602             :     severity = LOG_WARN;
     603             :   } else {
     604           0 :     severity = LOG_INFO;
     605             :   }
     606             : 
     607           5 :   if (warn >= 0) {
     608          15 :     SMARTLIST_FOREACH(unrecognized, networkstatus_voter_info_t *, voter,
     609             :       {
     610             :         tor_log(severity, LD_DIR, "Consensus includes unrecognized authority "
     611             :                  "'%s' at %s:%" PRIu16 " (contact %s; identity %s)",
     612             :                  voter->nickname, voter->address, voter->ipv4_dirport,
     613             :                  voter->contact?voter->contact:"n/a",
     614             :                  hex_str(voter->identity_digest, DIGEST_LEN));
     615             :       });
     616           5 :     SMARTLIST_FOREACH(need_certs_from, networkstatus_voter_info_t *, voter,
     617             :       {
     618             :         tor_log(severity, LD_DIR, "Looks like we need to download a new "
     619             :                  "certificate from authority '%s' at %s:%" PRIu16
     620             :                  " (contact %s; identity %s)",
     621             :                  voter->nickname, voter->address, voter->ipv4_dirport,
     622             :                  voter->contact?voter->contact:"n/a",
     623             :                  hex_str(voter->identity_digest, DIGEST_LEN));
     624             :       });
     625           5 :     SMARTLIST_FOREACH(missing_authorities, dir_server_t *, ds,
     626             :       {
     627             :         tor_log(severity, LD_DIR, "Consensus does not include configured "
     628             :                  "authority '%s' at %s:%" PRIu16 " (identity %s)",
     629             :                  ds->nickname, ds->address, ds->ipv4_dirport,
     630             :                  hex_str(ds->v3_identity_digest, DIGEST_LEN));
     631             :       });
     632             :     {
     633           5 :       char *joined;
     634           5 :       smartlist_t *sl = smartlist_new();
     635           5 :       char *tmp = smartlist_join_strings(list_good, " ", 0, NULL);
     636           5 :       smartlist_add_asprintf(sl,
     637             :                    "A consensus needs %d good signatures from recognized "
     638             :                    "authorities for us to accept it. "
     639             :                    "This %s one has %d (%s).",
     640             :                    n_required,
     641             :                    networkstatus_get_flavor_name(consensus->flavor),
     642             :                    n_good, tmp);
     643           5 :       tor_free(tmp);
     644           5 :       if (n_no_signature) {
     645           5 :         tmp = smartlist_join_strings(list_no_signature, " ", 0, NULL);
     646           5 :         smartlist_add_asprintf(sl,
     647             :                      "%d (%s) of the authorities we know didn't sign it.",
     648             :                      n_no_signature, tmp);
     649           5 :         tor_free(tmp);
     650             :       }
     651           5 :       if (n_unknown) {
     652           5 :         smartlist_add_asprintf(sl,
     653             :                       "It has %d signatures from authorities we don't "
     654             :                       "recognize.", n_unknown);
     655             :       }
     656           5 :       if (n_bad) {
     657           0 :         smartlist_add_asprintf(sl, "%d of the signatures on it didn't verify "
     658             :                       "correctly.", n_bad);
     659             :       }
     660           5 :       if (n_missing_key) {
     661           0 :         smartlist_add_asprintf(sl,
     662             :                       "We were unable to check %d of the signatures, "
     663             :                       "because we were missing the keys.", n_missing_key);
     664             :       }
     665           5 :       joined = smartlist_join_strings(sl, " ", 0, NULL);
     666           5 :       tor_log(severity, LD_DIR, "%s", joined);
     667           5 :       tor_free(joined);
     668          20 :       SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
     669           5 :       smartlist_free(sl);
     670             :     }
     671             :   }
     672             : 
     673           5 :   smartlist_free(list_good);
     674           5 :   smartlist_free(list_no_signature);
     675           5 :   smartlist_free(unrecognized);
     676           5 :   smartlist_free(need_certs_from);
     677           5 :   smartlist_free(missing_authorities);
     678             : 
     679           5 :   if (n_good == n_v3_authorities)
     680             :     return 1;
     681           0 :   else if (n_good >= n_required)
     682             :     return 0;
     683           0 :   else if (n_good + n_missing_key >= n_required)
     684             :     return -1;
     685             :   else
     686           0 :     return -2;
     687             : }
     688             : 
     689             : /** How far in the future do we allow a network-status to get before removing
     690             :  * it? (seconds) */
     691             : #define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
     692             : 
     693             : /** Helper for bsearching a list of routerstatus_t pointers: compare a
     694             :  * digest in the key to the identity digest of a routerstatus_t. */
     695             : int
     696           9 : compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
     697             : {
     698           9 :   const char *key = _key;
     699           9 :   const routerstatus_t *rs = *_member;
     700           9 :   return tor_memcmp(key, rs->identity_digest, DIGEST_LEN);
     701             : }
     702             : 
     703             : /** Helper for bsearching a list of routerstatus_t pointers: compare a
     704             :  * digest in the key to the identity digest of a routerstatus_t. */
     705             : int
     706           4 : compare_digest_to_vote_routerstatus_entry(const void *_key,
     707             :                                           const void **_member)
     708             : {
     709           4 :   const char *key = _key;
     710           4 :   const vote_routerstatus_t *vrs = *_member;
     711           4 :   return tor_memcmp(key, vrs->status.identity_digest, DIGEST_LEN);
     712             : }
     713             : 
     714             : /** As networkstatus_find_entry, but do not return a const pointer */
     715             : routerstatus_t *
     716           0 : networkstatus_vote_find_mutable_entry(networkstatus_t *ns, const char *digest)
     717             : {
     718           0 :   return smartlist_bsearch(ns->routerstatus_list, digest,
     719             :                            compare_digest_to_routerstatus_entry);
     720             : }
     721             : 
     722             : /** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
     723             :  * NULL if none was found. */
     724           0 : MOCK_IMPL(const routerstatus_t *,
     725             : networkstatus_vote_find_entry,(networkstatus_t *ns, const char *digest))
     726             : {
     727           0 :   return networkstatus_vote_find_mutable_entry(ns, digest);
     728             : }
     729             : 
     730             : /*XXXX MOVE make this static once functions are moved into this file. */
     731             : /** Search the routerstatuses in <b>ns</b> for one whose identity digest is
     732             :  * <b>digest</b>.  Return value and set *<b>found_out</b> as for
     733             :  * smartlist_bsearch_idx(). */
     734             : int
     735           0 : networkstatus_vote_find_entry_idx(networkstatus_t *ns,
     736             :                                   const char *digest, int *found_out)
     737             : {
     738           0 :   return smartlist_bsearch_idx(ns->routerstatus_list, digest,
     739             :                                compare_digest_to_routerstatus_entry,
     740             :                                found_out);
     741             : }
     742             : 
     743             : /** As router_get_consensus_status_by_descriptor_digest, but does not return
     744             :  * a const pointer. */
     745           2 : MOCK_IMPL(routerstatus_t *,
     746             : router_get_mutable_consensus_status_by_descriptor_digest,(
     747             :                                                  networkstatus_t *consensus,
     748             :                                                  const char *digest))
     749             : {
     750           2 :   if (!consensus)
     751           0 :     consensus = networkstatus_get_latest_consensus();
     752           2 :   if (!consensus)
     753             :     return NULL;
     754           2 :   if (!consensus->desc_digest_map) {
     755           1 :     digestmap_t *m = consensus->desc_digest_map = digestmap_new();
     756           4 :     SMARTLIST_FOREACH(consensus->routerstatus_list,
     757             :                       routerstatus_t *, rs,
     758             :      {
     759             :        digestmap_set(m, rs->descriptor_digest, rs);
     760             :      });
     761             :   }
     762           2 :   return digestmap_get(consensus->desc_digest_map, digest);
     763             : }
     764             : 
     765             : /** Return the consensus view of the status of the router whose current
     766             :  * <i>descriptor</i> digest in <b>consensus</b> is <b>digest</b>, or NULL if
     767             :  * no such router is known. */
     768             : const routerstatus_t *
     769           2 : router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
     770             :                                                  const char *digest)
     771             : {
     772           2 :   return router_get_mutable_consensus_status_by_descriptor_digest(
     773             :                                                           consensus, digest);
     774             : }
     775             : 
     776             : /** Return a smartlist of all router descriptor digests in a consensus */
     777             : static smartlist_t *
     778           0 : router_get_descriptor_digests_in_consensus(networkstatus_t *consensus)
     779             : {
     780           0 :   smartlist_t *result = smartlist_new();
     781           0 :   digestmap_iter_t *i;
     782           0 :   const char *digest;
     783           0 :   void *rs;
     784           0 :   char *digest_tmp;
     785             : 
     786           0 :   for (i = digestmap_iter_init(consensus->desc_digest_map);
     787           0 :        !(digestmap_iter_done(i));
     788           0 :        i = digestmap_iter_next(consensus->desc_digest_map, i)) {
     789           0 :     digestmap_iter_get(i, &digest, &rs);
     790           0 :     digest_tmp = tor_malloc(DIGEST_LEN);
     791           0 :     memcpy(digest_tmp, digest, DIGEST_LEN);
     792           0 :     smartlist_add(result, digest_tmp);
     793             :   }
     794             : 
     795           0 :   return result;
     796             : }
     797             : 
     798             : /** Return a smartlist of all router descriptor digests in the current
     799             :  * consensus */
     800           0 : MOCK_IMPL(smartlist_t *,
     801             : router_get_descriptor_digests,(void))
     802             : {
     803           0 :   smartlist_t *result = NULL;
     804             : 
     805           0 :   if (current_ns_consensus) {
     806           0 :     result =
     807           0 :       router_get_descriptor_digests_in_consensus(current_ns_consensus);
     808             :   }
     809             : 
     810           0 :   return result;
     811             : }
     812             : 
     813             : /** Given the digest of a router descriptor, return its current download
     814             :  * status, or NULL if the digest is unrecognized. */
     815           0 : MOCK_IMPL(download_status_t *,
     816             : router_get_dl_status_by_descriptor_digest,(const char *d))
     817             : {
     818           0 :   routerstatus_t *rs;
     819           0 :   if (!current_ns_consensus)
     820             :     return NULL;
     821           0 :   if ((rs = router_get_mutable_consensus_status_by_descriptor_digest(
     822             :                                               current_ns_consensus, d)))
     823           0 :     return &rs->dl_status;
     824             : 
     825             :   return NULL;
     826             : }
     827             : 
     828             : /** As router_get_consensus_status_by_id, but do not return a const pointer */
     829             : routerstatus_t *
     830          16 : router_get_mutable_consensus_status_by_id(const char *digest)
     831             : {
     832          16 :   const networkstatus_t *ns = networkstatus_get_latest_consensus();
     833          16 :   if (!ns)
     834             :     return NULL;
     835          14 :   smartlist_t *rslist = ns->routerstatus_list;
     836          14 :   return smartlist_bsearch(rslist, digest,
     837             :                            compare_digest_to_routerstatus_entry);
     838             : }
     839             : 
     840             : /** Return the consensus view of the status of the router whose identity
     841             :  * digest is <b>digest</b>, or NULL if we don't know about any such router. */
     842             : const routerstatus_t *
     843          16 : router_get_consensus_status_by_id(const char *digest)
     844             : {
     845          16 :   return router_get_mutable_consensus_status_by_id(digest);
     846             : }
     847             : 
     848             : /** How frequently do directory authorities re-download fresh networkstatus
     849             :  * documents? */
     850             : #define AUTHORITY_NS_CACHE_INTERVAL (10*60)
     851             : 
     852             : /** How frequently do non-authority directory caches re-download fresh
     853             :  * networkstatus documents? */
     854             : #define NONAUTHORITY_NS_CACHE_INTERVAL (60*60)
     855             : 
     856             : /** Return true iff, given the options listed in <b>options</b>, <b>flavor</b>
     857             :  *  is the flavor of a consensus networkstatus that we would like to fetch.
     858             :  *
     859             :  * For certificate fetches, use we_want_to_fetch_unknown_auth_certs, and
     860             :  * for serving fetched documents, use directory_caches_dir_info. */
     861             : int
     862         100 : we_want_to_fetch_flavor(const or_options_t *options, int flavor)
     863             : {
     864         100 :   if (flavor < 0 || flavor > N_CONSENSUS_FLAVORS) {
     865             :     /* This flavor is crazy; we don't want it */
     866             :     /*XXXX handle unrecognized flavors later */
     867             :     return 0;
     868             :   }
     869         100 :   if (authdir_mode_v3(options) || directory_caches_dir_info(options)) {
     870             :     /* We want to serve all flavors to others, regardless if we would use
     871             :      * it ourselves. */
     872           0 :     return 1;
     873             :   }
     874         100 :   if (options->FetchUselessDescriptors) {
     875             :     /* In order to get all descriptors, we need to fetch all consensuses. */
     876             :     return 1;
     877             :   }
     878             :   /* Otherwise, we want the flavor only if we want to use it to build
     879             :    * circuits. */
     880          98 :   return flavor == usable_consensus_flavor();
     881             : }
     882             : 
     883             : /** Return true iff, given the options listed in <b>options</b>, we would like
     884             :  * to fetch and store unknown authority certificates.
     885             :  *
     886             :  * For consensus and descriptor fetches, use we_want_to_fetch_flavor, and
     887             :  * for serving fetched certificates, use directory_caches_unknown_auth_certs.
     888             :  */
     889             : int
     890           1 : we_want_to_fetch_unknown_auth_certs(const or_options_t *options)
     891             : {
     892           2 :   if (authdir_mode_v3(options) ||
     893           1 :       directory_caches_unknown_auth_certs((options))) {
     894             :     /* We want to serve all certs to others, regardless if we would use
     895             :      * them ourselves. */
     896           0 :     return 1;
     897             :   }
     898           1 :   if (options->FetchUselessDescriptors) {
     899             :     /* Unknown certificates are definitely useless. */
     900           0 :     return 1;
     901             :   }
     902             :   /* Otherwise, don't fetch unknown certificates. */
     903             :   return 0;
     904             : }
     905             : 
     906             : /** How long will we hang onto a possibly live consensus for which we're
     907             :  * fetching certs before we check whether there is a better one? */
     908             : #define DELAY_WHILE_FETCHING_CERTS (20*60)
     909             : 
     910             : /** What is the minimum time we need to have waited fetching certs, before we
     911             :  * increment the consensus download schedule on failure? */
     912             : #define MIN_DELAY_FOR_FETCH_CERT_STATUS_FAILURE (1*60)
     913             : 
     914             : /* Check if a downloaded consensus flavor should still wait for certificates
     915             :  * to download now. If we decide not to wait, check if enough time has passed
     916             :  * to consider the certificate download failure a separate failure. If so,
     917             :  * fail dls.
     918             :  * If waiting for certificates to download, return 1. If not, return 0. */
     919             : static int
     920           0 : check_consensus_waiting_for_certs(int flavor, time_t now,
     921             :                                   download_status_t *dls)
     922             : {
     923           0 :   consensus_waiting_for_certs_t *waiting;
     924             : 
     925             :   /* We should always have a known flavor, because we_want_to_fetch_flavor()
     926             :    * filters out unknown flavors. */
     927           0 :   tor_assert(flavor >= 0 && flavor < N_CONSENSUS_FLAVORS);
     928             : 
     929           0 :   waiting = &consensus_waiting_for_certs[flavor];
     930           0 :   if (waiting->consensus) {
     931             :     /* XXXX make sure this doesn't delay sane downloads. */
     932           0 :     if (waiting->set_at + DELAY_WHILE_FETCHING_CERTS > now &&
     933           0 :         waiting->consensus->valid_until > now) {
     934             :       return 1;
     935             :     } else {
     936           0 :       if (!waiting->dl_failed) {
     937           0 :         if (waiting->set_at + MIN_DELAY_FOR_FETCH_CERT_STATUS_FAILURE > now) {
     938           0 :           download_status_failed(dls, 0);
     939             :         }
     940           0 :         waiting->dl_failed=1;
     941             :       }
     942             :     }
     943             :   }
     944             : 
     945             :   return 0;
     946             : }
     947             : 
     948             : /** If we want to download a fresh consensus, launch a new download as
     949             :  * appropriate. */
     950             : static void
     951           2 : update_consensus_networkstatus_downloads(time_t now)
     952             : {
     953           2 :   int i;
     954           2 :   const or_options_t *options = get_options();
     955           2 :   const int we_are_bootstrapping = networkstatus_consensus_is_bootstrapping(
     956             :                                                                         now);
     957           2 :   const int use_multi_conn =
     958           2 :     networkstatus_consensus_can_use_multiple_directories(options);
     959             : 
     960           2 :   if (should_delay_dir_fetches(options, NULL))
     961             :     return;
     962             : 
     963           0 :   for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
     964             :     /* XXXX need some way to download unknown flavors if we are caching. */
     965           0 :     const char *resource;
     966           0 :     networkstatus_t *c;
     967           0 :     int max_in_progress_conns = 1;
     968             : 
     969           0 :     if (! we_want_to_fetch_flavor(options, i))
     970           0 :       continue;
     971             : 
     972           0 :     c = networkstatus_get_latest_consensus_by_flavor(i);
     973           0 :     if (! (c && c->valid_after <= now && now <= c->valid_until)) {
     974             :       /* No live consensus? Get one now!*/
     975           0 :       time_to_download_next_consensus[i] = now;
     976             :     }
     977             : 
     978           0 :     if (time_to_download_next_consensus[i] > now)
     979           0 :       continue; /* Wait until the current consensus is older. */
     980             : 
     981           0 :     resource = networkstatus_get_flavor_name(i);
     982             : 
     983             :     /* Check if we already have enough connections in progress */
     984           0 :     if (we_are_bootstrapping && use_multi_conn) {
     985           0 :       max_in_progress_conns =
     986             :         options->ClientBootstrapConsensusMaxInProgressTries;
     987             :     }
     988           0 :     if (connection_dir_count_by_purpose_and_resource(
     989             :                                                   DIR_PURPOSE_FETCH_CONSENSUS,
     990             :                                                   resource)
     991             :         >= max_in_progress_conns) {
     992           0 :       continue;
     993             :     }
     994             : 
     995             :     /* Check if we want to launch another download for a usable consensus.
     996             :      * Only used during bootstrap. */
     997           0 :     if (we_are_bootstrapping && use_multi_conn
     998           0 :         && i == usable_consensus_flavor()) {
     999             : 
    1000             :       /* Check if we're already downloading a usable consensus */
    1001           0 :       if (networkstatus_consensus_is_already_downloading(resource))
    1002           0 :         continue;
    1003             : 
    1004             :       /* Make multiple connections for a bootstrap consensus download. */
    1005           0 :       update_consensus_bootstrap_multiple_downloads(now, options);
    1006             :     } else {
    1007             :       /* Check if we failed downloading a consensus too recently */
    1008             : 
    1009             :       /* Let's make sure we remembered to update consensus_dl_status */
    1010           0 :       tor_assert(consensus_dl_status[i].schedule == DL_SCHED_CONSENSUS);
    1011             : 
    1012           0 :       if (!download_status_is_ready(&consensus_dl_status[i], now)) {
    1013           0 :         continue;
    1014             :       }
    1015             : 
    1016             :       /** Check if we're waiting for certificates to download. If we are,
    1017             :        * launch download for missing directory authority certificates. */
    1018           0 :       if (check_consensus_waiting_for_certs(i, now, &consensus_dl_status[i])) {
    1019           0 :         update_certificate_downloads(now);
    1020           0 :         continue;
    1021             :       }
    1022             : 
    1023             :       /* Try the requested attempt */
    1024           0 :       log_info(LD_DIR, "Launching %s standard networkstatus consensus "
    1025             :                "download.", networkstatus_get_flavor_name(i));
    1026           0 :       directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
    1027             :                                    ROUTER_PURPOSE_GENERAL, resource,
    1028             :                                    PDS_RETRY_IF_NO_SERVERS,
    1029           0 :                                    consensus_dl_status[i].want_authority);
    1030             :     }
    1031             :   }
    1032             : }
    1033             : 
    1034             : /** When we're bootstrapping, launch one or more consensus download
    1035             :  * connections, if schedule indicates connection(s) should be made after now.
    1036             :  * If is_authority, connect to an authority, otherwise, use a fallback
    1037             :  * directory mirror.
    1038             :  */
    1039             : static void
    1040           0 : update_consensus_bootstrap_attempt_downloads(
    1041             :                                       time_t now,
    1042             :                                       download_status_t *dls,
    1043             :                                       download_want_authority_t want_authority)
    1044             : {
    1045           0 :   const char *resource = networkstatus_get_flavor_name(
    1046           0 :                                                   usable_consensus_flavor());
    1047             : 
    1048             :   /* Let's make sure we remembered to update schedule */
    1049           0 :   tor_assert(dls->schedule == DL_SCHED_CONSENSUS);
    1050             : 
    1051             :   /* Allow for multiple connections in the same second, if the schedule value
    1052             :    * is 0. */
    1053           0 :   while (download_status_is_ready(dls, now)) {
    1054           0 :     log_info(LD_DIR, "Launching %s bootstrap %s networkstatus consensus "
    1055             :              "download.", resource, (want_authority == DL_WANT_AUTHORITY
    1056             :                                      ? "authority"
    1057             :                                      : "mirror"));
    1058             : 
    1059           0 :     directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
    1060             :                                  ROUTER_PURPOSE_GENERAL, resource,
    1061             :                                  PDS_RETRY_IF_NO_SERVERS, want_authority);
    1062             :     /* schedule the next attempt */
    1063           0 :     download_status_increment_attempt(dls, resource, now);
    1064             :   }
    1065           0 : }
    1066             : 
    1067             : /** If we're bootstrapping, check the connection schedules and see if we want
    1068             :  * to make additional, potentially concurrent, consensus download
    1069             :  * connections.
    1070             :  * Only call when bootstrapping, and when we want to make additional
    1071             :  * connections. Only nodes that satisfy
    1072             :  * networkstatus_consensus_can_use_multiple_directories make additional
    1073             :  * connections.
    1074             :  */
    1075             : static void
    1076           0 : update_consensus_bootstrap_multiple_downloads(time_t now,
    1077             :                                               const or_options_t *options)
    1078             : {
    1079           0 :   const int usable_flavor = usable_consensus_flavor();
    1080             : 
    1081             :   /* make sure we can use multiple connections */
    1082           0 :   if (!networkstatus_consensus_can_use_multiple_directories(options)) {
    1083             :     return;
    1084             :   }
    1085             : 
    1086             :   /* Launch concurrent consensus download attempt(s) based on the mirror and
    1087             :    * authority schedules. Try the mirror first - this makes it slightly more
    1088             :    * likely that we'll connect to the fallback first, and then end the
    1089             :    * authority connection attempt. */
    1090             : 
    1091             :   /* If a consensus download fails because it's waiting for certificates,
    1092             :    * we'll fail both the authority and fallback schedules. This is better than
    1093             :    * failing only one of the schedules, and having the other continue
    1094             :    * unchecked.
    1095             :    */
    1096             : 
    1097             :   /* If we don't have or can't use extra fallbacks, don't try them. */
    1098           0 :   if (networkstatus_consensus_can_use_extra_fallbacks(options)) {
    1099           0 :     download_status_t *dls_f =
    1100             :       &consensus_bootstrap_dl_status[CONSENSUS_BOOTSTRAP_SOURCE_ANY_DIRSERVER];
    1101             : 
    1102           0 :     if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_f)) {
    1103             :       /* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
    1104           0 :       update_consensus_bootstrap_attempt_downloads(now, dls_f,
    1105             :                                                    DL_WANT_ANY_DIRSERVER);
    1106             :     }
    1107             :   }
    1108             : 
    1109             :   /* Now try an authority. */
    1110           0 :   download_status_t *dls_a =
    1111             :     &consensus_bootstrap_dl_status[CONSENSUS_BOOTSTRAP_SOURCE_AUTHORITY];
    1112             : 
    1113           0 :   if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_a)) {
    1114           0 :     update_consensus_bootstrap_attempt_downloads(now, dls_a,
    1115             :                                                  DL_WANT_AUTHORITY);
    1116             :   }
    1117             : }
    1118             : 
    1119             : /** Called when an attempt to download a consensus fails: note that the
    1120             :  * failure occurred, and possibly retry. */
    1121             : void
    1122           2 : networkstatus_consensus_download_failed(int status_code, const char *flavname)
    1123             : {
    1124           2 :   int flav = networkstatus_parse_flavor_name(flavname);
    1125           2 :   if (flav >= 0) {
    1126           2 :     tor_assert(flav < N_CONSENSUS_FLAVORS);
    1127             :     /* XXXX handle unrecognized flavors */
    1128           2 :     download_status_failed(&consensus_dl_status[flav], status_code);
    1129             :     /* Retry immediately, if appropriate. */
    1130           2 :     update_consensus_networkstatus_downloads(time(NULL));
    1131             :   }
    1132           2 : }
    1133             : 
    1134             : /** How long do we (as a cache) wait after a consensus becomes non-fresh
    1135             :  * before trying to fetch another? */
    1136             : #define CONSENSUS_MIN_SECONDS_BEFORE_CACHING 120
    1137             : 
    1138             : /** Update the time at which we'll consider replacing the current
    1139             :  * consensus of flavor <b>flav</b> */
    1140             : static void
    1141           5 : update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
    1142             : {
    1143           5 :   const or_options_t *options = get_options();
    1144           5 :   networkstatus_t *c = networkstatus_get_latest_consensus_by_flavor(flav);
    1145           5 :   const char *flavor = networkstatus_get_flavor_name(flav);
    1146           5 :   if (! we_want_to_fetch_flavor(get_options(), flav))
    1147             :     return;
    1148             : 
    1149           8 :   if (c && c->valid_after <= now && now <= c->valid_until) {
    1150           3 :     long dl_interval;
    1151           3 :     long interval = c->fresh_until - c->valid_after;
    1152           3 :     long min_sec_before_caching = CONSENSUS_MIN_SECONDS_BEFORE_CACHING;
    1153           3 :     time_t start;
    1154             : 
    1155           3 :     if (min_sec_before_caching > interval/16) {
    1156             :       /* Usually we allow 2-minutes slop factor in case clocks get
    1157             :          desynchronized a little.  If we're on a private network with
    1158             :          a crazy-fast voting interval, though, 2 minutes may be too
    1159             :          much. */
    1160           3 :       min_sec_before_caching = interval/16;
    1161             :       /* make sure we always delay by at least a second before caching */
    1162           3 :       if (min_sec_before_caching == 0) {
    1163           0 :         min_sec_before_caching = 1;
    1164             :       }
    1165             :     }
    1166             : 
    1167           3 :     if (dirclient_fetches_dir_info_early(options)) {
    1168             :       /* We want to cache the next one at some point after this one
    1169             :        * is no longer fresh... */
    1170           0 :       start = (time_t)(c->fresh_until + min_sec_before_caching);
    1171             :       /* Some clients may need the consensus sooner than others. */
    1172           0 :       if (options->FetchDirInfoExtraEarly || authdir_mode_v3(options)) {
    1173           0 :         dl_interval = 60;
    1174           0 :         if (min_sec_before_caching + dl_interval > interval)
    1175           0 :           dl_interval = interval/2;
    1176             :       } else {
    1177             :         /* But only in the first half-interval after that. */
    1178           0 :         dl_interval = interval/2;
    1179             :       }
    1180             :     } else {
    1181             :       /* We're an ordinary client, a bridge, or a hidden service.
    1182             :        * Give all the caches enough time to download the consensus. */
    1183           3 :       start = (time_t)(c->fresh_until + (interval*3)/4);
    1184             :       /* But download the next one well before this one is expired. */
    1185           3 :       dl_interval = ((c->valid_until - start) * 7 )/ 8;
    1186             : 
    1187             :       /* If we're a bridge user, make use of the numbers we just computed
    1188             :        * to choose the rest of the interval *after* them. */
    1189           3 :       if (dirclient_fetches_dir_info_later(options)) {
    1190             :         /* Give all the *clients* enough time to download the consensus. */
    1191           0 :         start = (time_t)(start + dl_interval + min_sec_before_caching);
    1192             :         /* But try to get it before ours actually expires. */
    1193           0 :         dl_interval = (c->valid_until - start) - min_sec_before_caching;
    1194             :       }
    1195             :     }
    1196             :     /* catch low dl_interval in crazy-fast networks */
    1197           3 :     if (dl_interval < 1)
    1198             :       dl_interval = 1;
    1199             :     /* catch late start in crazy-fast networks */
    1200           3 :     if (start+dl_interval >= c->valid_until)
    1201           0 :       start = c->valid_until - dl_interval - 1;
    1202           3 :     log_debug(LD_DIR,
    1203             :               "fresh_until: %ld start: %ld "
    1204             :               "dl_interval: %ld valid_until: %ld ",
    1205             :               (long)c->fresh_until, (long)start, dl_interval,
    1206             :               (long)c->valid_until);
    1207             :     /* We must not try to replace c while it's still fresh: */
    1208           3 :     tor_assert(c->fresh_until < start);
    1209             :     /* We must download the next one before c is invalid: */
    1210           3 :     tor_assert(start+dl_interval < c->valid_until);
    1211           6 :     time_to_download_next_consensus[flav] =
    1212           3 :       start + crypto_rand_int((int)dl_interval);
    1213             :     {
    1214           3 :       char tbuf1[ISO_TIME_LEN+1];
    1215           3 :       char tbuf2[ISO_TIME_LEN+1];
    1216           3 :       char tbuf3[ISO_TIME_LEN+1];
    1217           3 :       format_local_iso_time(tbuf1, c->fresh_until);
    1218           3 :       format_local_iso_time(tbuf2, c->valid_until);
    1219           3 :       format_local_iso_time(tbuf3, time_to_download_next_consensus[flav]);
    1220           3 :       log_info(LD_DIR, "Live %s consensus %s the most recent until %s and "
    1221             :                "will expire at %s; fetching the next one at %s.",
    1222             :                flavor, (c->fresh_until > now) ? "will be" : "was",
    1223             :                tbuf1, tbuf2, tbuf3);
    1224             :     }
    1225             :   } else {
    1226           2 :     time_to_download_next_consensus[flav] = now;
    1227           2 :     log_info(LD_DIR, "No live %s consensus; we should fetch one immediately.",
    1228             :              flavor);
    1229             :   }
    1230             : }
    1231             : 
    1232             : /** Update the time at which we'll consider replacing the current
    1233             :  * consensus of flavor 'flavor' */
    1234             : void
    1235           5 : update_consensus_networkstatus_fetch_time(time_t now)
    1236             : {
    1237           5 :   int i;
    1238          15 :   for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
    1239          10 :     if (we_want_to_fetch_flavor(get_options(), i))
    1240           5 :       update_consensus_networkstatus_fetch_time_impl(now, i);
    1241             :   }
    1242           5 : }
    1243             : 
    1244             : /** Return 1 if there's a reason we shouldn't try any directory
    1245             :  * fetches yet (e.g. we demand bridges and none are yet known).
    1246             :  * Else return 0.
    1247             : 
    1248             :  * If we return 1 and <b>msg_out</b> is provided, set <b>msg_out</b>
    1249             :  * to an explanation of why directory fetches are delayed. (If we
    1250             :  * return 0, we set msg_out to NULL.)
    1251             :  */
    1252             : int
    1253          17 : should_delay_dir_fetches(const or_options_t *options, const char **msg_out)
    1254             : {
    1255          17 :   if (msg_out) {
    1256          12 :     *msg_out = NULL;
    1257             :   }
    1258             : 
    1259          17 :   if (options->DisableNetwork) {
    1260           0 :     if (msg_out) {
    1261           0 :       *msg_out = "DisableNetwork is set.";
    1262             :     }
    1263           0 :     log_info(LD_DIR, "Delaying dir fetches (DisableNetwork is set)");
    1264           0 :     return 1;
    1265             :   }
    1266             : 
    1267          17 :   if (we_are_hibernating()) {
    1268          12 :     if (msg_out) {
    1269          10 :       *msg_out = "We are hibernating or shutting down.";
    1270             :     }
    1271          12 :     log_info(LD_DIR, "Delaying dir fetches (Hibernating or shutting down)");
    1272          12 :     return 1;
    1273             :   }
    1274             : 
    1275           5 :   if (options->UseBridges) {
    1276             :     /* If we know that none of our bridges can possibly work, avoid fetching
    1277             :      * directory documents. But if some of them might work, try again. */
    1278           0 :     if (num_bridges_usable(1) == 0) {
    1279           0 :       if (msg_out) {
    1280           0 :         *msg_out = "No running bridges";
    1281             :       }
    1282           0 :       log_info(LD_DIR, "Delaying dir fetches (no running bridges known)");
    1283           0 :       return 1;
    1284             :     }
    1285             : 
    1286           0 :     if (pt_proxies_configuration_pending()) {
    1287           0 :       if (msg_out) {
    1288           0 :         *msg_out = "Pluggable transport proxies still configuring";
    1289             :       }
    1290           0 :       log_info(LD_DIR, "Delaying dir fetches (pt proxies still configuring)");
    1291           0 :       return 1;
    1292             :     }
    1293             :   }
    1294             : 
    1295             :   return 0;
    1296             : }
    1297             : 
    1298             : /** Launch requests for networkstatus documents as appropriate. This is called
    1299             :  * when we retry all the connections on a SIGHUP and periodically by a Periodic
    1300             :  * event which checks whether we want to download any networkstatus documents.
    1301             :  */
    1302             : void
    1303           0 : update_networkstatus_downloads(time_t now)
    1304             : {
    1305           0 :   const or_options_t *options = get_options();
    1306           0 :   if (should_delay_dir_fetches(options, NULL))
    1307             :     return;
    1308             :   /** Launch a consensus download request, we will wait for the consensus to
    1309             :    * download and when it completes we will launch a certificate download
    1310             :    * request. */
    1311           0 :   update_consensus_networkstatus_downloads(now);
    1312             : }
    1313             : 
    1314             : /** Launch requests as appropriate for missing directory authority
    1315             :  * certificates. */
    1316             : void
    1317           0 : update_certificate_downloads(time_t now)
    1318             : {
    1319           0 :   int i;
    1320           0 :   for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
    1321           0 :     if (consensus_waiting_for_certs[i].consensus)
    1322           0 :       authority_certs_fetch_missing(consensus_waiting_for_certs[i].consensus,
    1323             :                                     now, NULL);
    1324             :   }
    1325             : 
    1326           0 :   if (current_ns_consensus)
    1327           0 :     authority_certs_fetch_missing(current_ns_consensus, now, NULL);
    1328           0 :   if (current_md_consensus)
    1329           0 :     authority_certs_fetch_missing(current_md_consensus, now, NULL);
    1330           0 : }
    1331             : 
    1332             : /** Return 1 if we have a consensus but we don't have enough certificates
    1333             :  * to start using it yet. */
    1334             : int
    1335          32 : consensus_is_waiting_for_certs(void)
    1336             : {
    1337          32 :   return consensus_waiting_for_certs[usable_consensus_flavor()].consensus
    1338          32 :     ? 1 : 0;
    1339             : }
    1340             : 
    1341             : /** Look up the currently active (depending on bootstrap status) download
    1342             :  * status for this consensus flavor and return a pointer to it.
    1343             :  */
    1344           0 : MOCK_IMPL(download_status_t *,
    1345             : networkstatus_get_dl_status_by_flavor,(consensus_flavor_t flavor))
    1346             : {
    1347           0 :   download_status_t *dl = NULL;
    1348           0 :   const int we_are_bootstrapping =
    1349           0 :     networkstatus_consensus_is_bootstrapping(time(NULL));
    1350             : 
    1351           0 :   if ((int)flavor <= N_CONSENSUS_FLAVORS) {
    1352           0 :     dl = &((we_are_bootstrapping ?
    1353           0 :            consensus_bootstrap_dl_status : consensus_dl_status)[flavor]);
    1354             :   }
    1355             : 
    1356           0 :   return dl;
    1357             : }
    1358             : 
    1359             : /** Look up the bootstrap download status for this consensus flavor
    1360             :  * and return a pointer to it. */
    1361           0 : MOCK_IMPL(download_status_t *,
    1362             : networkstatus_get_dl_status_by_flavor_bootstrap,(consensus_flavor_t flavor))
    1363             : {
    1364           0 :   download_status_t *dl = NULL;
    1365             : 
    1366           0 :   if ((int)flavor <= N_CONSENSUS_FLAVORS) {
    1367           0 :     dl = &(consensus_bootstrap_dl_status[flavor]);
    1368             :   }
    1369             : 
    1370           0 :   return dl;
    1371             : }
    1372             : 
    1373             : /** Look up the running (non-bootstrap) download status for this consensus
    1374             :  * flavor and return a pointer to it. */
    1375           0 : MOCK_IMPL(download_status_t *,
    1376             : networkstatus_get_dl_status_by_flavor_running,(consensus_flavor_t flavor))
    1377             : {
    1378           0 :   download_status_t *dl = NULL;
    1379             : 
    1380           0 :   if ((int)flavor <= N_CONSENSUS_FLAVORS) {
    1381           0 :     dl = &(consensus_dl_status[flavor]);
    1382             :   }
    1383             : 
    1384           0 :   return dl;
    1385             : }
    1386             : 
    1387             : /** Return the most recent consensus that we have downloaded, or NULL if we
    1388             :  * don't have one. May return future or expired consensuses. */
    1389       26315 : MOCK_IMPL(networkstatus_t *,
    1390             : networkstatus_get_latest_consensus,(void))
    1391             : {
    1392       26315 :   if (we_use_microdescriptors_for_circuits(get_options()))
    1393       26210 :     return current_md_consensus;
    1394             :   else
    1395         105 :     return current_ns_consensus;
    1396             : }
    1397             : 
    1398             : /** Return the latest consensus we have whose flavor matches <b>f</b>, or NULL
    1399             :  * if we don't have one. May return future or expired consensuses. */
    1400         533 : MOCK_IMPL(networkstatus_t *,
    1401             : networkstatus_get_latest_consensus_by_flavor,(consensus_flavor_t f))
    1402             : {
    1403         533 :   if (f == FLAV_NS)
    1404         160 :     return current_ns_consensus;
    1405         373 :   else if (f == FLAV_MICRODESC)
    1406         373 :     return current_md_consensus;
    1407             :   else {
    1408           0 :     tor_assert(0);
    1409             :     return NULL;
    1410             :   }
    1411             : }
    1412             : 
    1413             : /** Return the most recent consensus that we have downloaded, or NULL if it is
    1414             :  * no longer live. */
    1415         157 : MOCK_IMPL(networkstatus_t *,
    1416             : networkstatus_get_live_consensus,(time_t now))
    1417             : {
    1418         157 :   networkstatus_t *ns = networkstatus_get_latest_consensus();
    1419         157 :   if (ns && networkstatus_is_live(ns, now))
    1420             :     return ns;
    1421             :   else
    1422         142 :     return NULL;
    1423             : }
    1424             : 
    1425             : /** Given a consensus in <b>ns</b>, return true iff currently live and
    1426             :  *  unexpired. */
    1427             : int
    1428          58 : networkstatus_is_live(const networkstatus_t *ns, time_t now)
    1429             : {
    1430          58 :   return (ns->valid_after <= now && now <= ns->valid_until);
    1431             : }
    1432             : 
    1433             : /** Determine if <b>consensus</b> is valid, or expired recently enough, or not
    1434             :  * too far in the future, so that we can still use it.
    1435             :  *
    1436             :  * Return 1 if the consensus is reasonably live, or 0 if it is too old or
    1437             :  * too new.
    1438             :  */
    1439             : int
    1440       12098 : networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
    1441             :                                         time_t now)
    1442             : {
    1443       12098 :   if (BUG(!consensus))
    1444           0 :     return 0;
    1445             : 
    1446       12098 :   return networkstatus_valid_after_is_reasonably_live(consensus->valid_after,
    1447       12098 :                                                       now) &&
    1448       12097 :          networkstatus_valid_until_is_reasonably_live(consensus->valid_until,
    1449             :                                                       now);
    1450             : }
    1451             : 
    1452             : #define REASONABLY_LIVE_TIME (24*60*60)
    1453             : 
    1454             : /** As networkstatus_consensus_reasonably_live, but takes a valid_after
    1455             :  * time, and checks to see if it is in the past, or not too far in the future.
    1456             :  */
    1457             : int
    1458       12103 : networkstatus_valid_after_is_reasonably_live(time_t valid_after,
    1459             :                                              time_t now)
    1460             : {
    1461       12103 :   return (now >= valid_after - REASONABLY_LIVE_TIME);
    1462             : }
    1463             : 
    1464             : /** As networkstatus_consensus_reasonably_live, but takes a valid_until
    1465             :  * time, and checks to see if it is in the future, or not too far in the past.
    1466             :  */
    1467             : int
    1468       12102 : networkstatus_valid_until_is_reasonably_live(time_t valid_until,
    1469             :                                              time_t now)
    1470             : {
    1471       12102 :   return (now <= valid_until + REASONABLY_LIVE_TIME);
    1472             : }
    1473             : 
    1474             : /** As networkstatus_get_live_consensus(), but is way more tolerant of expired
    1475             :  *  and future consensuses. */
    1476         378 : MOCK_IMPL(networkstatus_t *,
    1477             : networkstatus_get_reasonably_live_consensus,(time_t now, int flavor))
    1478             : {
    1479         378 :   networkstatus_t *consensus =
    1480         378 :     networkstatus_get_latest_consensus_by_flavor(flavor);
    1481         422 :   if (consensus &&
    1482          44 :       networkstatus_consensus_reasonably_live(consensus, now))
    1483             :     return consensus;
    1484             :   else
    1485         344 :     return NULL;
    1486             : }
    1487             : 
    1488             : /** Check if we need to download a consensus during tor's bootstrap phase.
    1489             :  * If we have no consensus, or our consensus is unusably old, return 1.
    1490             :  * As soon as we have received a consensus, return 0, even if we don't have
    1491             :  * enough certificates to validate it.
    1492             :  * If a fallback directory gives us a consensus we can never get certs for,
    1493             :  * check_consensus_waiting_for_certs() will wait 20 minutes before failing
    1494             :  * the cert downloads. After that, a new consensus will be fetched from a
    1495             :  * randomly chosen fallback. */
    1496          43 : MOCK_IMPL(int,
    1497             : networkstatus_consensus_is_bootstrapping,(time_t now))
    1498             : {
    1499             :   /* If we have a validated, reasonably live consensus, we're not
    1500             :    * bootstrapping a consensus at all. */
    1501          43 :   if (networkstatus_get_reasonably_live_consensus(
    1502             :                                                 now,
    1503             :                                                 usable_consensus_flavor())) {
    1504             :     return 0;
    1505             :   }
    1506             : 
    1507             :   /* If we have a consensus, but we're waiting for certificates,
    1508             :    * we're not waiting for a consensus download while bootstrapping. */
    1509          32 :   if (consensus_is_waiting_for_certs()) {
    1510           0 :     return 0;
    1511             :   }
    1512             : 
    1513             :   /* If we have no consensus, or our consensus is very old, we are
    1514             :    * bootstrapping, and we need to download a consensus. */
    1515             :   return 1;
    1516             : }
    1517             : 
    1518             : /** Check if we can use multiple directories for a consensus download.
    1519             :  * Only clients (including bridge relays, which act like clients) benefit
    1520             :  * from multiple simultaneous consensus downloads. */
    1521             : int
    1522          64 : networkstatus_consensus_can_use_multiple_directories(
    1523             :                                                   const or_options_t *options)
    1524             : {
    1525             :   /* If we are a client, bridge, bridge client, or hidden service */
    1526          64 :   return !public_server_mode(options);
    1527             : }
    1528             : 
    1529             : /** Check if we can use fallback directory mirrors for a consensus download.
    1530             :  * If we have fallbacks and don't want to fetch from the authorities,
    1531             :  * we can use them. */
    1532          27 : MOCK_IMPL(int,
    1533             : networkstatus_consensus_can_use_extra_fallbacks,(const or_options_t *options))
    1534             : {
    1535             :   /* The list length comparisons are a quick way to check if we have any
    1536             :    * non-authority fallback directories. If we ever have any authorities that
    1537             :    * aren't fallback directories, we will need to change this code. */
    1538          27 :   tor_assert(smartlist_len(router_get_fallback_dir_servers())
    1539             :              >= smartlist_len(router_get_trusted_dir_servers()));
    1540             :   /* If we don't fetch from the authorities, and we have additional mirrors,
    1541             :    * we can use them. */
    1542          27 :   return (!dirclient_fetches_from_authorities(options)
    1543          27 :           && (smartlist_len(router_get_fallback_dir_servers())
    1544          27 :               > smartlist_len(router_get_trusted_dir_servers())));
    1545             : }
    1546             : 
    1547             : /* Is there a consensus fetch for flavor <b>resource</b> that's far
    1548             :  * enough along to be attached to a circuit? */
    1549             : int
    1550          56 : networkstatus_consensus_is_already_downloading(const char *resource)
    1551             : {
    1552          56 :   int answer = 0;
    1553             : 
    1554             :   /* First, get a list of all the dir conns that are fetching a consensus,
    1555             :    * fetching *this* consensus, and are in state "reading" (meaning they
    1556             :    * have already flushed their request onto the socks connection). */
    1557         112 :   smartlist_t *fetching_conns =
    1558          56 :     connection_dir_list_by_purpose_resource_and_state(
    1559             :       DIR_PURPOSE_FETCH_CONSENSUS, resource, DIR_CONN_STATE_CLIENT_READING);
    1560             : 
    1561             :   /* Then, walk through each conn, to see if its linked socks connection
    1562             :    * is in an attached state. We have to check this separately, since with
    1563             :    * the optimistic data feature, fetches can send their request to the
    1564             :    * socks connection and go into state 'reading', even before they're
    1565             :    * attached to any circuit. */
    1566          60 :   SMARTLIST_FOREACH_BEGIN(fetching_conns, dir_connection_t *, dirconn) {
    1567             :     /* Do any of these other dir conns have a linked socks conn that is
    1568             :      * attached to a circuit already? */
    1569          20 :     connection_t *base = TO_CONN(dirconn);
    1570          20 :     if (base->linked_conn &&
    1571          18 :         base->linked_conn->type == CONN_TYPE_AP &&
    1572          18 :         !AP_CONN_STATE_IS_UNATTACHED(base->linked_conn->state)) {
    1573             :       answer = 1;
    1574             :       break; /* stop looping, because we know the answer will be yes */
    1575             :     }
    1576           4 :   } SMARTLIST_FOREACH_END(dirconn);
    1577          56 :   smartlist_free(fetching_conns);
    1578             : 
    1579          56 :   return answer;
    1580             : }
    1581             : 
    1582             : /** Given two router status entries for the same router identity, return 1
    1583             :  * if the contents have changed between them. Otherwise, return 0.
    1584             :  * It only checks for fields that are output by control port.
    1585             :  * This should be kept in sync with the struct routerstatus_t
    1586             :  * and the printing function routerstatus_format_entry in
    1587             :  * NS_CONTROL_PORT mode.
    1588             :  **/
    1589             : STATIC int
    1590          29 : routerstatus_has_visibly_changed(const routerstatus_t *a,
    1591             :                                  const routerstatus_t *b)
    1592             : {
    1593          29 :   tor_assert(tor_memeq(a->identity_digest, b->identity_digest, DIGEST_LEN));
    1594             : 
    1595          57 :   return strcmp(a->nickname, b->nickname) ||
    1596          55 :          fast_memneq(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
    1597          27 :          !tor_addr_eq(&a->ipv4_addr, &b->ipv4_addr) ||
    1598          26 :          a->ipv4_orport != b->ipv4_orport ||
    1599             :          a->ipv4_dirport != b->ipv4_dirport ||
    1600          24 :          a->is_authority != b->is_authority ||
    1601             :          a->is_exit != b->is_exit ||
    1602             :          a->is_stable != b->is_stable ||
    1603             :          a->is_fast != b->is_fast ||
    1604             :          a->is_flagged_running != b->is_flagged_running ||
    1605          24 :          a->is_named != b->is_named ||
    1606          17 :          a->is_unnamed != b->is_unnamed ||
    1607          17 :          a->is_valid != b->is_valid ||
    1608          16 :          a->is_possible_guard != b->is_possible_guard ||
    1609             :          a->is_bad_exit != b->is_bad_exit ||
    1610             :          a->is_hs_dir != b->is_hs_dir ||
    1611          16 :          a->is_staledesc != b->is_staledesc ||
    1612          11 :          a->has_bandwidth != b->has_bandwidth ||
    1613          11 :          a->published_on != b->published_on ||
    1614          10 :          a->ipv6_orport != b->ipv6_orport ||
    1615           9 :          a->is_v2_dir != b->is_v2_dir ||
    1616          44 :          a->bandwidth_kb != b->bandwidth_kb ||
    1617           7 :          tor_addr_compare(&a->ipv6_addr, &b->ipv6_addr, CMP_EXACT);
    1618             : }
    1619             : 
    1620             : /** Notify controllers of any router status entries that changed between
    1621             :  * <b>old_c</b> and <b>new_c</b>. */
    1622             : static void
    1623           5 : notify_control_networkstatus_changed(const networkstatus_t *old_c,
    1624             :                                      const networkstatus_t *new_c)
    1625             : {
    1626           5 :   smartlist_t *changed;
    1627           5 :   if (old_c == new_c)
    1628           5 :     return;
    1629             : 
    1630             :   /* tell the controller exactly which relays are still listed, as well
    1631             :    * as what they're listed as */
    1632           5 :   control_event_newconsensus(new_c);
    1633             : 
    1634           5 :   if (!control_event_is_interesting(EVENT_NS))
    1635             :     return;
    1636             : 
    1637           0 :   if (!old_c) {
    1638           0 :     control_event_networkstatus_changed(new_c->routerstatus_list);
    1639           0 :     return;
    1640             :   }
    1641           0 :   changed = smartlist_new();
    1642             : 
    1643           0 :   SMARTLIST_FOREACH_JOIN(
    1644             :                      old_c->routerstatus_list, const routerstatus_t *, rs_old,
    1645             :                      new_c->routerstatus_list, const routerstatus_t *, rs_new,
    1646             :                      tor_memcmp(rs_old->identity_digest,
    1647             :                             rs_new->identity_digest, DIGEST_LEN),
    1648             :                      smartlist_add(changed, (void*) rs_new)) {
    1649           0 :     if (routerstatus_has_visibly_changed(rs_old, rs_new))
    1650           0 :       smartlist_add(changed, (void*)rs_new);
    1651             :   } SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
    1652             : 
    1653           0 :   control_event_networkstatus_changed(changed);
    1654           0 :   smartlist_free(changed);
    1655             : }
    1656             : 
    1657             : /* Called before the consensus changes from old_c to new_c. */
    1658             : static void
    1659           5 : notify_before_networkstatus_changes(const networkstatus_t *old_c,
    1660             :                                     const networkstatus_t *new_c)
    1661             : {
    1662           5 :   notify_control_networkstatus_changed(old_c, new_c);
    1663           5 :   dos_consensus_has_changed(new_c);
    1664           5 :   relay_consensus_has_changed(new_c);
    1665           5 :   hs_dos_consensus_has_changed(new_c);
    1666           5 : }
    1667             : 
    1668             : /* Called after a new consensus has been put in the global state. It is safe
    1669             :  * to use the consensus getters in this function. */
    1670             : static void
    1671           5 : notify_after_networkstatus_changes(void)
    1672             : {
    1673           5 :   const networkstatus_t *c = networkstatus_get_latest_consensus();
    1674           5 :   const or_options_t *options = get_options();
    1675           5 :   const time_t now = approx_time();
    1676             : 
    1677           5 :   scheduler_notify_networkstatus_changed();
    1678             : 
    1679             :   /* The "current" consensus has just been set and it is a usable flavor so
    1680             :    * the first thing we need to do is recalculate the voting schedule static
    1681             :    * object so we can use the timings in there needed by some subsystems
    1682             :    * such as hidden service and shared random. */
    1683           5 :   dirauth_sched_recalculate_timing(options, now);
    1684           5 :   reschedule_dirvote(options);
    1685             : 
    1686           5 :   nodelist_set_consensus(c);
    1687             : 
    1688           5 :   update_consensus_networkstatus_fetch_time(now);
    1689             : 
    1690             :   /* Change the cell EWMA settings */
    1691           5 :   cmux_ewma_set_options(options, c);
    1692             : 
    1693             :   /* XXXX this call might be unnecessary here: can changing the
    1694             :    * current consensus really alter our view of any OR's rate limits? */
    1695           5 :   connection_or_update_token_buckets(get_connection_array(), options);
    1696             : 
    1697           5 :   circuit_build_times_new_consensus_params(
    1698             :                                  get_circuit_build_times_mutable(), c);
    1699           5 :   channelpadding_new_consensus_params(c);
    1700           5 :   circpad_new_consensus_params(c);
    1701           5 :   router_new_consensus_params(c);
    1702           5 : }
    1703             : 
    1704             : /** Copy all the ancillary information (like router download status and so on)
    1705             :  * from <b>old_c</b> to <b>new_c</b>. */
    1706             : static void
    1707           0 : networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
    1708             :                                       const networkstatus_t *old_c)
    1709             : {
    1710           0 :   if (old_c == new_c)
    1711             :     return;
    1712           0 :   if (!old_c || !smartlist_len(old_c->routerstatus_list))
    1713             :     return;
    1714             : 
    1715           0 :   SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
    1716             :                          new_c->routerstatus_list, routerstatus_t *, rs_new,
    1717             :                          tor_memcmp(rs_old->identity_digest,
    1718             :                                 rs_new->identity_digest, DIGEST_LEN),
    1719             :                          STMT_NIL) {
    1720             :     /* Okay, so we're looking at the same identity. */
    1721           0 :     rs_new->last_dir_503_at = rs_old->last_dir_503_at;
    1722             : 
    1723           0 :     if (tor_memeq(rs_old->descriptor_digest, rs_new->descriptor_digest,
    1724             :                   DIGEST256_LEN)) {
    1725             :       /* And the same descriptor too! */
    1726           0 :       memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t));
    1727             :     }
    1728             :   } SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
    1729             : }
    1730             : 
    1731             : #ifdef TOR_UNIT_TESTS
    1732             : /**Accept a <b>flavor</b> consensus <b>c</b> without any additional
    1733             :  * validation. This is exclusively for unit tests.
    1734             :  * We copy any ancillary information from a pre-existing consensus
    1735             :  * and then free the current one and replace it with the newly
    1736             :  * provided instance. Returns -1 on unrecognized flavor, 0 otherwise.
    1737             :  */
    1738             : int
    1739           1 : networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
    1740             :                                             const char *flavor)
    1741             : {
    1742           1 :   int flav = networkstatus_parse_flavor_name(flavor);
    1743           1 :   switch (flav) {
    1744           0 :     case FLAV_NS:
    1745           0 :       if (current_ns_consensus) {
    1746           0 :         networkstatus_copy_old_consensus_info(c, current_ns_consensus);
    1747           0 :         networkstatus_vote_free(current_ns_consensus);
    1748             :       }
    1749           0 :       current_ns_consensus = c;
    1750           0 :       break;
    1751           1 :     case FLAV_MICRODESC:
    1752           1 :       if (current_md_consensus) {
    1753           0 :         networkstatus_copy_old_consensus_info(c, current_md_consensus);
    1754           0 :         networkstatus_vote_free(current_md_consensus);
    1755             :       }
    1756           1 :       current_md_consensus = c;
    1757           1 :       break;
    1758             :   }
    1759           1 :   return current_md_consensus ? 0 : -1;
    1760             : }
    1761             : #endif /* defined(TOR_UNIT_TESTS) */
    1762             : 
    1763             : /**
    1764             :  * Helper: Read the current consensus of type <b>flavor</b> from
    1765             :  * <b>fname</b>.  Flags and return values are as for
    1766             :  * networkstatus_set_current_consensus().
    1767             :  **/
    1768             : static int
    1769           0 : reload_consensus_from_file(const char *fname,
    1770             :                            const char *flavor,
    1771             :                            unsigned flags,
    1772             :                            const char *source_dir)
    1773             : {
    1774           0 :   tor_mmap_t *map = tor_mmap_file(fname);
    1775           0 :   if (!map)
    1776             :     return 0;
    1777             : 
    1778           0 :   int rv = networkstatus_set_current_consensus(map->data, map->size,
    1779             :                                                flavor, flags, source_dir);
    1780             : #ifdef _WIN32
    1781             :   if (rv < 0 && tor_memstr(map->data, map->size, "\r\n")) {
    1782             :     log_notice(LD_GENERAL, "Looks like the above failures are probably "
    1783             :                "because of a CRLF in consensus file %s; falling back to "
    1784             :                "read_file_to_string. Nothing to worry about: this file "
    1785             :                "was probably saved by an earlier version of Tor.",
    1786             :                escaped(fname));
    1787             :     char *content = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
    1788             :     rv = networkstatus_set_current_consensus(content, strlen(content),
    1789             :                                              flavor, flags, source_dir);
    1790             :     tor_free(content);
    1791             :   }
    1792             : #endif /* defined(_WIN32) */
    1793           0 :   if (rv < -1) {
    1794           0 :     log_warn(LD_GENERAL, "Couldn't set consensus from cache file %s",
    1795             :              escaped(fname));
    1796             :   }
    1797           0 :   tor_munmap_file(map);
    1798           0 :   return rv;
    1799             : }
    1800             : 
    1801             : /**
    1802             :  * Helper for handle_missing_protocol_warning: handles either the
    1803             :  * client case (if <b>is_client</b> is set) or the server case otherwise.
    1804             :  */
    1805             : static void
    1806           5 : handle_missing_protocol_warning_impl(const networkstatus_t *c,
    1807             :                                      int is_client)
    1808             : {
    1809           5 :   char *protocol_warning = NULL;
    1810             : 
    1811           5 :   int should_exit = networkstatus_check_required_protocols(c,
    1812             :                                                    is_client,
    1813             :                                                    &protocol_warning);
    1814           5 :   if (protocol_warning) {
    1815           0 :     tor_log(should_exit ? LOG_ERR : LOG_WARN,
    1816             :             LD_GENERAL,
    1817             :             "%s", protocol_warning);
    1818             :   }
    1819           5 :   if (should_exit) {
    1820           0 :     tor_assert_nonfatal(protocol_warning);
    1821             :   }
    1822           5 :   tor_free(protocol_warning);
    1823           5 :   if (should_exit)
    1824           0 :     exit(1); // XXXX bad exit: should return from main.
    1825           5 : }
    1826             : 
    1827             : /** Called when we have received a networkstatus <b>c</b>. If there are
    1828             :  * any _required_ protocols we are missing, log an error and exit
    1829             :  * immediately. If there are any _recommended_ protocols we are missing,
    1830             :  * warn. */
    1831             : static void
    1832           5 : handle_missing_protocol_warning(const networkstatus_t *c,
    1833             :                                 const or_options_t *options)
    1834             : {
    1835           5 :   const int is_server = server_mode(options);
    1836           5 :   const int is_client = options_any_client_port_set(options) || !is_server;
    1837             : 
    1838           5 :   if (is_server)
    1839           0 :     handle_missing_protocol_warning_impl(c, 0);
    1840           5 :   if (is_client)
    1841           5 :     handle_missing_protocol_warning_impl(c, 1);
    1842           5 : }
    1843             : 
    1844             : /**
    1845             :  * Check whether we received a consensus that appears to be coming
    1846             :  * from the future.  Because we implicitly trust the directory
    1847             :  * authorities' idea of the current time, we produce a warning if we
    1848             :  * get an early consensus.
    1849             :  *
    1850             :  * If we got a consensus that is time stamped far in the past, that
    1851             :  * could simply have come from a stale cache.  Possible ways to get a
    1852             :  * consensus from the future can include:
    1853             :  *
    1854             :  * - enough directory authorities have wrong clocks
    1855             :  * - directory authorities collude to produce misleading time stamps
    1856             :  * - our own clock is wrong (this is by far the most likely)
    1857             :  *
    1858             :  * We neglect highly improbable scenarios that involve actual time
    1859             :  * travel.
    1860             :  */
    1861             : STATIC void
    1862          11 : warn_early_consensus(const networkstatus_t *c, const char *flavor,
    1863             :                      time_t now)
    1864             : {
    1865          11 :   char tbuf[ISO_TIME_LEN+1];
    1866          11 :   char dbuf[64];
    1867          11 :   long delta = now - c->valid_after;
    1868          11 :   char *flavormsg = NULL;
    1869             : 
    1870             : /** If a consensus appears more than this many seconds before it could
    1871             :  * possibly be a sufficiently-signed consensus, declare that our clock
    1872             :  * is skewed. */
    1873             : #define EARLY_CONSENSUS_NOTICE_SKEW 60
    1874             : 
    1875             :   /* We assume that if a majority of dirauths have accurate clocks,
    1876             :    * the earliest that a dirauth with a skewed clock could possibly
    1877             :    * publish a sufficiently-signed consensus is (valid_after -
    1878             :    * dist_seconds).  Before that time, the skewed dirauth would be
    1879             :    * unable to obtain enough authority signatures for the consensus to
    1880             :    * be valid. */
    1881          11 :   if (now >= c->valid_after - c->dist_seconds - EARLY_CONSENSUS_NOTICE_SKEW)
    1882           8 :     return;
    1883             : 
    1884           3 :   format_iso_time(tbuf, c->valid_after);
    1885           3 :   format_time_interval(dbuf, sizeof(dbuf), delta);
    1886           3 :   log_warn(LD_GENERAL, "Our clock is %s behind the time published in the "
    1887             :            "consensus network status document (%s UTC).  Tor needs an "
    1888             :            "accurate clock to work correctly. Please check your time and "
    1889             :            "date settings!", dbuf, tbuf);
    1890           3 :   tor_asprintf(&flavormsg, "%s flavor consensus", flavor);
    1891           3 :   clock_skew_warning(NULL, delta, 1, LD_GENERAL, flavormsg, "CONSENSUS");
    1892           3 :   tor_free(flavormsg);
    1893             : }
    1894             : 
    1895             : /** Try to replace the current cached v3 networkstatus with the one in
    1896             :  * <b>consensus</b>.  If we don't have enough certificates to validate it,
    1897             :  * store it in consensus_waiting_for_certs and launch a certificate fetch.
    1898             :  *
    1899             :  * If flags & NSSET_FROM_CACHE, this networkstatus has come from the disk
    1900             :  * cache.  If flags & NSSET_WAS_WAITING_FOR_CERTS, this networkstatus was
    1901             :  * already received, but we were waiting for certificates on it.  If flags &
    1902             :  * NSSET_DONT_DOWNLOAD_CERTS, do not launch certificate downloads as needed.
    1903             :  * If flags & NSSET_ACCEPT_OBSOLETE, then we should be willing to take this
    1904             :  * consensus, even if it comes from many days in the past.
    1905             :  *
    1906             :  * If source_dir is non-NULL, it's the identity digest for a directory that
    1907             :  * we've just successfully retrieved a consensus or certificates from, so try
    1908             :  * it first to fetch any missing certificates.
    1909             :  *
    1910             :  * Return 0 on success, <0 on failure.  On failure, caller should increment
    1911             :  * the failure count as appropriate.
    1912             :  *
    1913             :  * We return -1 for mild failures that don't need to be reported to the
    1914             :  * user, and -2 for more serious problems.
    1915             :  */
    1916             : int
    1917           5 : networkstatus_set_current_consensus(const char *consensus,
    1918             :                                     size_t consensus_len,
    1919             :                                     const char *flavor,
    1920             :                                     unsigned flags,
    1921             :                                     const char *source_dir)
    1922             : {
    1923           5 :   networkstatus_t *c=NULL;
    1924           5 :   int r, result = -1;
    1925           5 :   time_t now = approx_time();
    1926           5 :   const or_options_t *options = get_options();
    1927           5 :   char *unverified_fname = NULL, *consensus_fname = NULL;
    1928           5 :   int flav = networkstatus_parse_flavor_name(flavor);
    1929           5 :   const unsigned from_cache = flags & NSSET_FROM_CACHE;
    1930           5 :   const unsigned was_waiting_for_certs = flags & NSSET_WAS_WAITING_FOR_CERTS;
    1931           5 :   const unsigned dl_certs = !(flags & NSSET_DONT_DOWNLOAD_CERTS);
    1932           5 :   const unsigned accept_obsolete = flags & NSSET_ACCEPT_OBSOLETE;
    1933           5 :   const unsigned require_flavor = flags & NSSET_REQUIRE_FLAVOR;
    1934           5 :   const common_digests_t *current_digests = NULL;
    1935           5 :   consensus_waiting_for_certs_t *waiting = NULL;
    1936           5 :   time_t current_valid_after = 0;
    1937           5 :   int free_consensus = 1; /* Free 'c' at the end of the function */
    1938           5 :   int checked_protocols_already = 0;
    1939             : 
    1940           5 :   if (flav < 0) {
    1941             :     /* XXXX we don't handle unrecognized flavors yet. */
    1942           0 :     log_warn(LD_BUG, "Unrecognized consensus flavor %s", flavor);
    1943           0 :     return -2;
    1944             :   }
    1945             : 
    1946             :   /* Make sure it's parseable. */
    1947           5 :   c = networkstatus_parse_vote_from_string(consensus,
    1948             :                                            consensus_len,
    1949             :                                            NULL, NS_TYPE_CONSENSUS);
    1950           5 :   if (!c) {
    1951           0 :     log_warn(LD_DIR, "Unable to parse networkstatus consensus");
    1952           0 :     result = -2;
    1953           0 :     goto done;
    1954             :   }
    1955             : 
    1956           5 :   if (from_cache && !was_waiting_for_certs) {
    1957             :     /* We previously stored this; check _now_ to make sure that version-kills
    1958             :      * really work. This happens even before we check signatures: we did so
    1959             :      * before when we stored this to disk. This does mean an attacker who can
    1960             :      * write to the datadir can make us not start: such an attacker could
    1961             :      * already harm us by replacing our guards, which would be worse. */
    1962           0 :     checked_protocols_already = 1;
    1963           0 :     handle_missing_protocol_warning(c, options);
    1964             :   }
    1965             : 
    1966           5 :   if ((int)c->flavor != flav) {
    1967             :     /* This wasn't the flavor we thought we were getting. */
    1968           1 :     if (require_flavor) {
    1969           0 :       log_warn(LD_DIR, "Got consensus with unexpected flavor %s (wanted %s)",
    1970             :                networkstatus_get_flavor_name(c->flavor), flavor);
    1971           0 :       goto done;
    1972             :     }
    1973           1 :     flav = c->flavor;
    1974           1 :     flavor = networkstatus_get_flavor_name(flav);
    1975             :   }
    1976             : 
    1977           5 :   if (flav != usable_consensus_flavor() &&
    1978           0 :       !we_want_to_fetch_flavor(options, flav)) {
    1979             :     /* This consensus is totally boring to us: we won't use it, we didn't want
    1980             :      * it, and we won't serve it.  Drop it. */
    1981           0 :     goto done;
    1982             :   }
    1983             : 
    1984           5 :   if (from_cache && !accept_obsolete &&
    1985           0 :       c->valid_until < now-OLD_ROUTER_DESC_MAX_AGE) {
    1986           0 :     log_info(LD_DIR, "Loaded an expired consensus. Discarding.");
    1987           0 :     goto done;
    1988             :   }
    1989             : 
    1990           5 :   if (!strcmp(flavor, "ns")) {
    1991           0 :     consensus_fname = get_cachedir_fname("cached-consensus");
    1992           0 :     unverified_fname = get_cachedir_fname("unverified-consensus");
    1993           0 :     if (current_ns_consensus) {
    1994           0 :       current_digests = &current_ns_consensus->digests;
    1995           0 :       current_valid_after = current_ns_consensus->valid_after;
    1996             :     }
    1997           5 :   } else if (!strcmp(flavor, "microdesc")) {
    1998           5 :     consensus_fname = get_cachedir_fname("cached-microdesc-consensus");
    1999           5 :     unverified_fname = get_cachedir_fname("unverified-microdesc-consensus");
    2000           5 :     if (current_md_consensus) {
    2001           0 :       current_digests = &current_md_consensus->digests;
    2002           0 :       current_valid_after = current_md_consensus->valid_after;
    2003             :     }
    2004             :   } else {
    2005           0 :     tor_assert_nonfatal_unreached();
    2006           0 :     result = -2;
    2007           0 :     goto done;
    2008             :   }
    2009             : 
    2010           5 :   if (current_digests &&
    2011           0 :       tor_memeq(&c->digests, current_digests, sizeof(c->digests))) {
    2012             :     /* We already have this one. That's a failure. */
    2013           0 :     log_info(LD_DIR, "Got a %s consensus we already have", flavor);
    2014           0 :     goto done;
    2015             :   }
    2016             : 
    2017           5 :   if (current_valid_after && c->valid_after <= current_valid_after) {
    2018             :     /* We have a newer one.  There's no point in accepting this one,
    2019             :      * even if it's great. */
    2020           0 :     log_info(LD_DIR, "Got a %s consensus at least as old as the one we have",
    2021             :              flavor);
    2022           0 :     goto done;
    2023             :   }
    2024             : 
    2025             :   /* Make sure it's signed enough. */
    2026           5 :   if ((r=networkstatus_check_consensus_signature(c, 1))<0) {
    2027           0 :     if (r == -1) {
    2028             :       /* Okay, so it _might_ be signed enough if we get more certificates. */
    2029           0 :       if (!was_waiting_for_certs) {
    2030           0 :         log_info(LD_DIR,
    2031             :                  "Not enough certificates to check networkstatus consensus");
    2032             :       }
    2033           0 :       if (!current_valid_after ||
    2034           0 :           c->valid_after > current_valid_after) {
    2035           0 :         waiting = &consensus_waiting_for_certs[flav];
    2036           0 :         networkstatus_vote_free(waiting->consensus);
    2037           0 :         waiting->consensus = c;
    2038           0 :         free_consensus = 0;
    2039           0 :         waiting->set_at = now;
    2040           0 :         waiting->dl_failed = 0;
    2041           0 :         if (!from_cache) {
    2042           0 :           write_bytes_to_file(unverified_fname, consensus, consensus_len, 1);
    2043             :         }
    2044           0 :         if (dl_certs)
    2045           0 :           authority_certs_fetch_missing(c, now, source_dir);
    2046             :         /* This case is not a success or a failure until we get the certs
    2047             :          * or fail to get the certs. */
    2048             :         result = 0;
    2049             :       } else {
    2050             :         /* Even if we had enough signatures, we'd never use this as the
    2051             :          * latest consensus. */
    2052           0 :         if (was_waiting_for_certs && from_cache)
    2053           0 :           if (unlink(unverified_fname) != 0) {
    2054           0 :             log_debug(LD_FS,
    2055             :                       "Failed to unlink %s: %s",
    2056             :                       unverified_fname, strerror(errno));
    2057             :           }
    2058             :       }
    2059           0 :       goto done;
    2060             :     } else {
    2061             :       /* This can never be signed enough:  Kill it. */
    2062           0 :       if (!was_waiting_for_certs) {
    2063           0 :         log_warn(LD_DIR, "Not enough good signatures on networkstatus "
    2064             :                  "consensus");
    2065           0 :         result = -2;
    2066             :       }
    2067           0 :       if (was_waiting_for_certs && (r < -1) && from_cache) {
    2068           0 :         if (unlink(unverified_fname) != 0) {
    2069           0 :             log_debug(LD_FS,
    2070             :                       "Failed to unlink %s: %s",
    2071             :                       unverified_fname, strerror(errno));
    2072             :         }
    2073             :       }
    2074           0 :       goto done;
    2075             :     }
    2076             :   }
    2077             : 
    2078             :   /* Signatures from the consensus are verified */
    2079           5 :   if (from_cache && was_waiting_for_certs) {
    2080             :     /* We check if the consensus is loaded from disk cache and that it
    2081             :      * it is an unverified consensus. If it is unverified, rename it to
    2082             :      * cached-*-consensus since it has been verified. */
    2083           0 :     log_info(LD_DIR, "Unverified consensus signatures verified.");
    2084           0 :     tor_rename(unverified_fname, consensus_fname);
    2085             :   }
    2086             : 
    2087           5 :   if (!from_cache && flav == usable_consensus_flavor())
    2088           5 :     control_event_client_status(LOG_NOTICE, "CONSENSUS_ARRIVED");
    2089             : 
    2090           5 :   if (!checked_protocols_already) {
    2091           5 :     handle_missing_protocol_warning(c, options);
    2092             :   }
    2093             : 
    2094             :   /* Are we missing any certificates at all? */
    2095           5 :   if (r != 1 && dl_certs)
    2096           0 :     authority_certs_fetch_missing(c, now, source_dir);
    2097             : 
    2098           5 :   const int is_usable_flavor = flav == usable_consensus_flavor();
    2099             : 
    2100             :   /* Before we switch to the new consensus, notify that we are about to change
    2101             :    * it using the old consensus and the new one. */
    2102           5 :   if (is_usable_flavor) {
    2103           5 :     notify_before_networkstatus_changes(networkstatus_get_latest_consensus(),
    2104             :                                         c);
    2105             :   }
    2106           5 :   if (flav == FLAV_NS) {
    2107           0 :     if (current_ns_consensus) {
    2108           0 :       networkstatus_copy_old_consensus_info(c, current_ns_consensus);
    2109           0 :       networkstatus_vote_free(current_ns_consensus);
    2110             :       /* Defensive programming : we should set current_ns_consensus very soon
    2111             :        * but we're about to call some stuff in the meantime, and leaving this
    2112             :        * dangling pointer around has proven to be trouble. */
    2113           0 :       current_ns_consensus = NULL;
    2114             :     }
    2115           0 :     current_ns_consensus = c;
    2116           0 :     free_consensus = 0; /* avoid free */
    2117           5 :   } else if (flav == FLAV_MICRODESC) {
    2118           5 :     if (current_md_consensus) {
    2119           0 :       networkstatus_copy_old_consensus_info(c, current_md_consensus);
    2120           0 :       networkstatus_vote_free(current_md_consensus);
    2121             :       /* more defensive programming */
    2122           0 :       current_md_consensus = NULL;
    2123             :     }
    2124           5 :     current_md_consensus = c;
    2125           5 :     free_consensus = 0; /* avoid free */
    2126             :   }
    2127             : 
    2128           5 :   waiting = &consensus_waiting_for_certs[flav];
    2129           5 :   if (waiting->consensus &&
    2130           0 :       waiting->consensus->valid_after <= c->valid_after) {
    2131           0 :     networkstatus_vote_free(waiting->consensus);
    2132           0 :     waiting->consensus = NULL;
    2133           0 :     waiting->set_at = 0;
    2134           0 :     waiting->dl_failed = 0;
    2135           0 :     if (unlink(unverified_fname) != 0) {
    2136           0 :       log_debug(LD_FS,
    2137             :                 "Failed to unlink %s: %s",
    2138             :                 unverified_fname, strerror(errno));
    2139             :     }
    2140             :   }
    2141             : 
    2142           5 :   if (is_usable_flavor) {
    2143             :     /* Notify that we just changed the consensus so the current global value
    2144             :      * can be looked at. */
    2145           5 :     notify_after_networkstatus_changes();
    2146             :   }
    2147             : 
    2148             :   /* Reset the failure count only if this consensus is actually valid. */
    2149           5 :   if (c->valid_after <= now && now <= c->valid_until) {
    2150           3 :     download_status_reset(&consensus_dl_status[flav]);
    2151             :   } else {
    2152           2 :     if (!from_cache)
    2153           2 :       download_status_failed(&consensus_dl_status[flav], 0);
    2154             :   }
    2155             : 
    2156           5 :   if (we_want_to_fetch_flavor(options, flav)) {
    2157           5 :     if (dir_server_mode(get_options())) {
    2158           0 :       dirserv_set_cached_consensus_networkstatus(consensus,
    2159             :                                                  consensus_len,
    2160             :                                                  flavor,
    2161           0 :                                                  &c->digests,
    2162           0 :                                                  c->digest_sha3_as_signed,
    2163             :                                                  c->valid_after);
    2164             : 
    2165           0 :       consdiffmgr_add_consensus(consensus, consensus_len, c);
    2166             :     }
    2167             :   }
    2168             : 
    2169           5 :   if (!from_cache) {
    2170           5 :     write_bytes_to_file(consensus_fname, consensus, consensus_len, 1);
    2171             :   }
    2172             : 
    2173           5 :   warn_early_consensus(c, flavor, now);
    2174             : 
    2175             :   /* We got a new consensus. Reset our md fetch fail cache */
    2176           5 :   microdesc_reset_outdated_dirservers_list();
    2177             : 
    2178           5 :   router_dir_info_changed();
    2179             : 
    2180           5 :   result = 0;
    2181           5 :  done:
    2182           5 :   if (free_consensus)
    2183           0 :     networkstatus_vote_free(c);
    2184           5 :   tor_free(consensus_fname);
    2185           5 :   tor_free(unverified_fname);
    2186           5 :   return result;
    2187             : }
    2188             : 
    2189             : /** Called when we have gotten more certificates: see whether we can
    2190             :  * now verify a pending consensus.
    2191             :  *
    2192             :  * If source_dir is non-NULL, it's the identity digest for a directory that
    2193             :  * we've just successfully retrieved certificates from, so try it first to
    2194             :  * fetch any missing certificates.
    2195             :  */
    2196             : void
    2197          12 : networkstatus_note_certs_arrived(const char *source_dir)
    2198             : {
    2199          12 :   int i;
    2200          36 :   for (i=0; i<N_CONSENSUS_FLAVORS; ++i) {
    2201          24 :     const char *flavor_name = networkstatus_get_flavor_name(i);
    2202          24 :     consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
    2203          24 :     if (!waiting->consensus)
    2204          24 :       continue;
    2205           0 :     if (networkstatus_check_consensus_signature(waiting->consensus, 0)>=0) {
    2206           0 :       char *fname = networkstatus_get_cache_fname(i, flavor_name, 1);
    2207           0 :       reload_consensus_from_file(fname, flavor_name,
    2208             :                                  NSSET_WAS_WAITING_FOR_CERTS, source_dir);
    2209           0 :       tor_free(fname);
    2210             :     }
    2211             :   }
    2212          12 : }
    2213             : 
    2214             : /** If the network-status list has changed since the last time we called this
    2215             :  * function, update the status of every routerinfo from the network-status
    2216             :  * list. If <b>dir_version</b> is 2, it's a v2 networkstatus that changed.
    2217             :  * If <b>dir_version</b> is 3, it's a v3 consensus that changed.
    2218             :  */
    2219             : void
    2220           1 : routers_update_all_from_networkstatus(time_t now, int dir_version)
    2221             : {
    2222           1 :   routerlist_t *rl = router_get_routerlist();
    2223           1 :   networkstatus_t *consensus = networkstatus_get_reasonably_live_consensus(now,
    2224             :                                                                      FLAV_NS);
    2225             : 
    2226           1 :   if (!consensus || dir_version < 3) /* nothing more we should do */
    2227             :     return;
    2228             : 
    2229             :   /* calls router_dir_info_changed() when it's done -- more routers
    2230             :    * might be up or down now, which might affect whether there's enough
    2231             :    * directory info. */
    2232           0 :   routers_update_status_from_consensus_networkstatus(rl->routers, 0);
    2233             : 
    2234           0 :   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
    2235             :                     ri->cache_info.routerlist_index = ri_sl_idx);
    2236           0 :   if (rl->old_routers)
    2237           0 :     signed_descs_update_status_from_consensus_networkstatus(rl->old_routers);
    2238             : 
    2239           0 :   if (!have_warned_about_old_version) {
    2240           0 :     int is_server = server_mode(get_options());
    2241           0 :     version_status_t status;
    2242           0 :     const char *recommended = is_server ?
    2243             :       consensus->server_versions : consensus->client_versions;
    2244           0 :     status = tor_version_is_obsolete(VERSION, recommended);
    2245             : 
    2246           0 :     if (status == VS_RECOMMENDED) {
    2247           0 :       log_info(LD_GENERAL, "The directory authorities say my version is ok.");
    2248           0 :     } else if (status == VS_EMPTY) {
    2249           0 :       log_info(LD_GENERAL,
    2250             :                "The directory authorities don't recommend any versions.");
    2251           0 :     } else if (status == VS_NEW || status == VS_NEW_IN_SERIES) {
    2252           0 :       if (!have_warned_about_new_version) {
    2253           0 :         log_notice(LD_GENERAL, "This version of Tor (%s) is newer than any "
    2254             :                    "recommended version%s, according to the directory "
    2255             :                    "authorities. Recommended versions are: %s",
    2256             :                    VERSION,
    2257             :                    status == VS_NEW_IN_SERIES ? " in its series" : "",
    2258             :                    recommended);
    2259           0 :         have_warned_about_new_version = 1;
    2260           0 :         control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
    2261             :                                      "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
    2262             :                                      VERSION, "NEW", recommended);
    2263             :       }
    2264             :     } else {
    2265           0 :       log_warn(LD_GENERAL, "Please upgrade! "
    2266             :                "This version of Tor (%s) is %s, according to the directory "
    2267             :                "authorities. Recommended versions are: %s",
    2268             :                VERSION,
    2269             :                status == VS_OLD ? "obsolete" : "not recommended",
    2270             :                recommended);
    2271           0 :       have_warned_about_old_version = 1;
    2272           0 :       control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
    2273             :            "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
    2274             :            VERSION, status == VS_OLD ? "OBSOLETE" : "UNRECOMMENDED",
    2275             :            recommended);
    2276             :     }
    2277             :   }
    2278             : }
    2279             : 
    2280             : /** Given a list <b>routers</b> of routerinfo_t *, update each status field
    2281             :  * according to our current consensus networkstatus.  May re-order
    2282             :  * <b>routers</b>. */
    2283             : void
    2284           4 : routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
    2285             :                                                    int reset_failures)
    2286             : {
    2287           4 :   const or_options_t *options = get_options();
    2288           4 :   int authdir = authdir_mode_v3(options);
    2289           4 :   networkstatus_t *ns = networkstatus_get_latest_consensus();
    2290           4 :   if (!ns || !smartlist_len(ns->routerstatus_list))
    2291             :     return;
    2292             : 
    2293           0 :   routers_sort_by_identity(routers);
    2294             : 
    2295           0 :   SMARTLIST_FOREACH_JOIN(ns->routerstatus_list, routerstatus_t *, rs,
    2296             :                          routers, routerinfo_t *, router,
    2297             :                          tor_memcmp(rs->identity_digest,
    2298             :                                router->cache_info.identity_digest, DIGEST_LEN),
    2299             :   {
    2300             :   }) {
    2301             :     /* Is it the same descriptor, or only the same identity? */
    2302           0 :     if (tor_memeq(router->cache_info.signed_descriptor_digest,
    2303           0 :                 rs->descriptor_digest, DIGEST_LEN)) {
    2304           0 :       if (ns->valid_until > router->cache_info.last_listed_as_valid_until)
    2305           0 :         router->cache_info.last_listed_as_valid_until = ns->valid_until;
    2306             :     }
    2307             : 
    2308           0 :     if (authdir) {
    2309             :       /* If we _are_ an authority, we should check whether this router
    2310             :        * is one that will cause us to need a reachability test. */
    2311           0 :       routerinfo_t *old_router =
    2312           0 :         router_get_mutable_by_digest(router->cache_info.identity_digest);
    2313           0 :       if (old_router != router) {
    2314           0 :         router->needs_retest_if_added =
    2315           0 :           dirserv_should_launch_reachability_test(router, old_router);
    2316             :       }
    2317             :     }
    2318           0 :     if (reset_failures) {
    2319           0 :       download_status_reset(&rs->dl_status);
    2320             :     }
    2321             :   } SMARTLIST_FOREACH_JOIN_END(rs, router);
    2322             : 
    2323           0 :   router_dir_info_changed();
    2324             : }
    2325             : 
    2326             : /** Given a list of signed_descriptor_t, update their fields (mainly, when
    2327             :  * they were last listed) from the most recent consensus. */
    2328             : void
    2329           0 : signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs)
    2330             : {
    2331           0 :   networkstatus_t *ns = current_ns_consensus;
    2332           0 :   if (!ns)
    2333             :     return;
    2334             : 
    2335           0 :   if (!ns->desc_digest_map) {
    2336           0 :     char dummy[DIGEST_LEN];
    2337             :     /* instantiates the digest map. */
    2338           0 :     memset(dummy, 0, sizeof(dummy));
    2339           0 :     router_get_consensus_status_by_descriptor_digest(ns, dummy);
    2340             :   }
    2341           0 :   SMARTLIST_FOREACH(descs, signed_descriptor_t *, d,
    2342             :   {
    2343             :     const routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
    2344             :                                        d->signed_descriptor_digest);
    2345             :     if (rs) {
    2346             :       if (ns->valid_until > d->last_listed_as_valid_until)
    2347             :         d->last_listed_as_valid_until = ns->valid_until;
    2348             :     }
    2349             :   });
    2350             : }
    2351             : 
    2352             : /** Generate networkstatus lines for a single routerstatus_t object, and
    2353             :  * return the result in a newly allocated string.  Used only by controller
    2354             :  * interface (for now.) */
    2355             : char *
    2356           1 : networkstatus_getinfo_helper_single(const routerstatus_t *rs)
    2357             : {
    2358           1 :   return routerstatus_format_entry(rs, NULL, NULL, NS_CONTROL_PORT,
    2359             :                                    NULL);
    2360             : }
    2361             : 
    2362             : /**
    2363             :  * Extract status information from <b>ri</b> and from other authority
    2364             :  * functions and store it in <b>rs</b>. <b>rs</b> is zeroed out before it is
    2365             :  * set.
    2366             :  *
    2367             :  * We assume that node-\>is_running has already been set, e.g. by
    2368             :  *   dirserv_set_router_is_running(ri, now);
    2369             :  */
    2370             : void
    2371           6 : set_routerstatus_from_routerinfo(routerstatus_t *rs,
    2372             :                                  const node_t *node,
    2373             :                                  const routerinfo_t *ri)
    2374             : {
    2375           6 :   memset(rs, 0, sizeof(routerstatus_t));
    2376             : 
    2377          12 :   rs->is_authority =
    2378           6 :     router_digest_is_trusted_dir(ri->cache_info.identity_digest);
    2379             : 
    2380             :   /* Set by compute_performance_thresholds or from consensus */
    2381           6 :   rs->is_exit = node->is_exit;
    2382           6 :   rs->is_stable = node->is_stable;
    2383           6 :   rs->is_fast = node->is_fast;
    2384           6 :   rs->is_flagged_running = node->is_running;
    2385           6 :   rs->is_valid = node->is_valid;
    2386           6 :   rs->is_possible_guard = node->is_possible_guard;
    2387           6 :   rs->is_bad_exit = node->is_bad_exit;
    2388           6 :   rs->is_hs_dir = node->is_hs_dir;
    2389           6 :   rs->is_named = rs->is_unnamed = 0;
    2390             : 
    2391           6 :   rs->published_on = ri->cache_info.published_on;
    2392           6 :   memcpy(rs->identity_digest, node->identity, DIGEST_LEN);
    2393           6 :   memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
    2394             :          DIGEST_LEN);
    2395           6 :   tor_addr_copy(&rs->ipv4_addr, &ri->ipv4_addr);
    2396           6 :   strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
    2397           6 :   rs->ipv4_orport = ri->ipv4_orport;
    2398           6 :   rs->ipv4_dirport = ri->ipv4_dirport;
    2399           6 :   rs->is_v2_dir = ri->supports_tunnelled_dir_requests;
    2400             : 
    2401           6 :   tor_addr_copy(&rs->ipv6_addr, &ri->ipv6_addr);
    2402           6 :   rs->ipv6_orport = ri->ipv6_orport;
    2403           6 : }
    2404             : 
    2405             : /** Alloc and return a string describing routerstatuses for the most
    2406             :  * recent info of each router we know about that is of purpose
    2407             :  * <b>purpose_string</b>. Return NULL if unrecognized purpose.
    2408             :  *
    2409             :  * Right now this function is oriented toward listing bridges (you
    2410             :  * shouldn't use this for general-purpose routers, since those
    2411             :  * should be listed from the consensus, not from the routers list). */
    2412             : char *
    2413           1 : networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now)
    2414             : {
    2415           1 :   const time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
    2416           1 :   char *answer;
    2417           1 :   routerlist_t *rl = router_get_routerlist();
    2418           1 :   smartlist_t *statuses;
    2419           1 :   const uint8_t purpose = router_purpose_from_string(purpose_string);
    2420           1 :   routerstatus_t rs;
    2421             : 
    2422           1 :   if (purpose == ROUTER_PURPOSE_UNKNOWN) {
    2423           0 :     log_info(LD_DIR, "Unrecognized purpose '%s' when listing router statuses.",
    2424             :              purpose_string);
    2425           0 :     return NULL;
    2426             :   }
    2427             : 
    2428           1 :   statuses = smartlist_new();
    2429           1 :   SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
    2430           0 :     node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
    2431           0 :     if (!node)
    2432           0 :       continue;
    2433           0 :     if (ri->cache_info.published_on < cutoff)
    2434           0 :       continue;
    2435           0 :     if (ri->purpose != purpose)
    2436           0 :       continue;
    2437           0 :     set_routerstatus_from_routerinfo(&rs, node, ri);
    2438           0 :     smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
    2439           0 :   } SMARTLIST_FOREACH_END(ri);
    2440             : 
    2441           1 :   answer = smartlist_join_strings(statuses, "", 0, NULL);
    2442           1 :   SMARTLIST_FOREACH(statuses, char *, cp, tor_free(cp));
    2443           1 :   smartlist_free(statuses);
    2444           1 :   return answer;
    2445             : }
    2446             : 
    2447             : /**
    2448             :  * Search through a smartlist of "key=int32" strings for a value beginning
    2449             :  * with "param_name=". If one is found, clip it to be between min_val and
    2450             :  * max_val inclusive and return it.  If one is not found, return
    2451             :  * default_val.
    2452             :  ***/
    2453             : static int32_t
    2454         930 : get_net_param_from_list(smartlist_t *net_params, const char *param_name,
    2455             :                         int32_t default_val, int32_t min_val, int32_t max_val)
    2456             : {
    2457         930 :   int32_t res = default_val;
    2458         930 :   size_t name_len = strlen(param_name);
    2459             : 
    2460         930 :   tor_assert(max_val > min_val);
    2461         930 :   tor_assert(min_val <= default_val);
    2462         930 :   tor_assert(max_val >= default_val);
    2463             : 
    2464        5513 :   SMARTLIST_FOREACH_BEGIN(net_params, const char *, p) {
    2465        4941 :     if (!strcmpstart(p, param_name) && p[name_len] == '=') {
    2466         358 :       int ok=0;
    2467         358 :       long v = tor_parse_long(p+name_len+1, 10, INT32_MIN,
    2468             :                               INT32_MAX, &ok, NULL);
    2469         358 :       if (ok) {
    2470         358 :         res = (int32_t) v;
    2471         358 :         break;
    2472             :       }
    2473             :     }
    2474        4583 :   } SMARTLIST_FOREACH_END(p);
    2475             : 
    2476         930 :   if (res < min_val) {
    2477           0 :     log_warn(LD_DIR, "Consensus parameter %s is too small. Got %d, raising to "
    2478             :              "%d.", param_name, res, min_val);
    2479           0 :     res = min_val;
    2480         930 :   } else if (res > max_val) {
    2481           2 :     log_warn(LD_DIR, "Consensus parameter %s is too large. Got %d, capping to "
    2482             :              "%d.", param_name, res, max_val);
    2483           2 :     res = max_val;
    2484             :   }
    2485             : 
    2486         930 :   tor_assert(res >= min_val);
    2487         930 :   tor_assert(res <= max_val);
    2488         930 :   return res;
    2489             : }
    2490             : 
    2491             : /** Return the value of a integer parameter from the networkstatus <b>ns</b>
    2492             :  * whose name is <b>param_name</b>.  If <b>ns</b> is NULL, try loading the
    2493             :  * latest consensus ourselves. Return <b>default_val</b> if no latest
    2494             :  * consensus, or if it has no parameter called <b>param_name</b>.
    2495             :  * Make sure the value parsed from the consensus is at least
    2496             :  * <b>min_val</b> and at most <b>max_val</b> and raise/cap the parsed value
    2497             :  * if necessary. */
    2498       78465 : MOCK_IMPL(int32_t,
    2499             : networkstatus_get_param, (const networkstatus_t *ns, const char *param_name,
    2500             :                         int32_t default_val, int32_t min_val, int32_t max_val))
    2501             : {
    2502       78465 :   if (!ns) /* if they pass in null, go find it ourselves */
    2503       77890 :     ns = networkstatus_get_latest_consensus();
    2504             : 
    2505       78465 :   if (!ns || !ns->net_params)
    2506             :     return default_val;
    2507             : 
    2508         616 :   return get_net_param_from_list(ns->net_params, param_name,
    2509             :                                  default_val, min_val, max_val);
    2510             : }
    2511             : 
    2512             : /**
    2513             :  * As networkstatus_get_param(), but check torrc_value before checking the
    2514             :  * consensus. If torrc_value is in-range, then return it instead of the
    2515             :  * value from the consensus.
    2516             :  */
    2517             : int32_t
    2518           4 : networkstatus_get_overridable_param(const networkstatus_t *ns,
    2519             :                                     int32_t torrc_value,
    2520             :                                     const char *param_name,
    2521             :                                     int32_t default_val,
    2522             :                                     int32_t min_val, int32_t max_val)
    2523             : {
    2524           4 :   if (torrc_value >= min_val && torrc_value <= max_val)
    2525             :     return torrc_value;
    2526             :   else
    2527           2 :     return networkstatus_get_param(
    2528             :                          ns, param_name, default_val, min_val, max_val);
    2529             : }
    2530             : 
    2531             : /**
    2532             :  * Retrieve the consensus parameter that governs the
    2533             :  * fixed-point precision of our network balancing 'bandwidth-weights'
    2534             :  * (which are themselves integer consensus values). We divide them
    2535             :  * by this value and ensure they never exceed this value.
    2536             :  */
    2537             : int
    2538        2205 : networkstatus_get_weight_scale_param(networkstatus_t *ns)
    2539             : {
    2540        2205 :   return networkstatus_get_param(ns, "bwweightscale",
    2541             :                                  BW_WEIGHT_SCALE,
    2542             :                                  BW_MIN_WEIGHT_SCALE,
    2543             :                                  BW_MAX_WEIGHT_SCALE);
    2544             : }
    2545             : 
    2546             : /** Return the value of a integer bw weight parameter from the networkstatus
    2547             :  * <b>ns</b> whose name is <b>weight_name</b>.  If <b>ns</b> is NULL, try
    2548             :  * loading the latest consensus ourselves. Return <b>default_val</b> if no
    2549             :  * latest consensus, or if it has no parameter called <b>weight_name</b>. */
    2550             : int32_t
    2551       13317 : networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name,
    2552             :                             int32_t default_val)
    2553             : {
    2554       13317 :   int32_t param;
    2555       13317 :   int max;
    2556       13317 :   if (!ns) /* if they pass in null, go find it ourselves */
    2557       13053 :     ns = networkstatus_get_latest_consensus();
    2558             : 
    2559       13317 :   if (!ns || !ns->weight_params)
    2560             :     return default_val;
    2561             : 
    2562         314 :   max = networkstatus_get_weight_scale_param(ns);
    2563         314 :   param = get_net_param_from_list(ns->weight_params, weight_name,
    2564             :                                   default_val, -1,
    2565             :                                   BW_MAX_WEIGHT_SCALE);
    2566         314 :   if (param > max) {
    2567           0 :     log_warn(LD_DIR, "Value of consensus weight %s was too large, capping "
    2568             :              "to %d", weight_name, max);
    2569           0 :     param = max;
    2570             :   }
    2571             :   return param;
    2572             : }
    2573             : 
    2574             : /** Return the name of the consensus flavor <b>flav</b> as used to identify
    2575             :  * the flavor in directory documents. */
    2576             : const char *
    2577         330 : networkstatus_get_flavor_name(consensus_flavor_t flav)
    2578             : {
    2579         330 :   switch (flav) {
    2580             :     case FLAV_NS:
    2581             :       return "ns";
    2582         172 :     case FLAV_MICRODESC:
    2583         172 :       return "microdesc";
    2584           0 :     default:
    2585           0 :       tor_fragile_assert();
    2586             :       return "??";
    2587             :   }
    2588             : }
    2589             : 
    2590             : /** Return the consensus_flavor_t value for the flavor called <b>flavname</b>,
    2591             :  * or -1 if the flavor is not recognized. */
    2592             : int
    2593        1639 : networkstatus_parse_flavor_name(const char *flavname)
    2594             : {
    2595        1639 :   if (!strcmp(flavname, "ns"))
    2596             :     return FLAV_NS;
    2597        1614 :   else if (!strcmp(flavname, "microdesc"))
    2598             :     return FLAV_MICRODESC;
    2599             :   else
    2600           9 :     return -1;
    2601             : }
    2602             : 
    2603             : /** Return 0 if this routerstatus is obsolete, too new, isn't
    2604             :  * running, or otherwise not a descriptor that we would make any
    2605             :  * use of even if we had it. Else return 1. */
    2606             : int
    2607          82 : client_would_use_router(const routerstatus_t *rs, time_t now)
    2608             : {
    2609          82 :   if (!rs->is_flagged_running) {
    2610             :     /* If we had this router descriptor, we wouldn't even bother using it.
    2611             :      * (Fetching and storing depends on by we_want_to_fetch_flavor().) */
    2612             :     return 0;
    2613             :   }
    2614           6 :   if (rs->published_on + OLD_ROUTER_DESC_MAX_AGE < now) {
    2615             :     /* We'd drop it immediately for being too old. */
    2616             :     return 0;
    2617             :   }
    2618           6 :   if (!routerstatus_version_supports_extend2_cells(rs, 1)) {
    2619             :     /* We'd ignore it because it doesn't support EXTEND2 cells.
    2620             :      * If we don't know the version, download the descriptor so we can
    2621             :      * check if it supports EXTEND2 cells and ntor. */
    2622           6 :     return 0;
    2623             :   }
    2624             :   return 1;
    2625             : }
    2626             : 
    2627             : /** If <b>question</b> is a string beginning with "ns/" in a format the
    2628             :  * control interface expects for a GETINFO question, set *<b>answer</b> to a
    2629             :  * newly-allocated string containing networkstatus lines for the appropriate
    2630             :  * ORs.  Return 0 on success, -1 on unrecognized question format. */
    2631             : int
    2632           0 : getinfo_helper_networkstatus(control_connection_t *conn,
    2633             :                              const char *question, char **answer,
    2634             :                              const char **errmsg)
    2635             : {
    2636           0 :   const routerstatus_t *status;
    2637           0 :   (void) conn;
    2638             : 
    2639           0 :   if (!networkstatus_get_latest_consensus()) {
    2640           0 :     *answer = tor_strdup("");
    2641           0 :     return 0;
    2642             :   }
    2643             : 
    2644           0 :   if (!strcmp(question, "ns/all")) {
    2645           0 :     smartlist_t *statuses = smartlist_new();
    2646           0 :     SMARTLIST_FOREACH(networkstatus_get_latest_consensus()->routerstatus_list,
    2647             :                       const routerstatus_t *, rs,
    2648             :       {
    2649             :         smartlist_add(statuses, networkstatus_getinfo_helper_single(rs));
    2650             :       });
    2651           0 :     *answer = smartlist_join_strings(statuses, "", 0, NULL);
    2652           0 :     SMARTLIST_FOREACH(statuses, char *, cp, tor_free(cp));
    2653           0 :     smartlist_free(statuses);
    2654           0 :     return 0;
    2655           0 :   } else if (!strcmpstart(question, "ns/id/")) {
    2656           0 :     char d[DIGEST_LEN];
    2657           0 :     const char *q = question + 6;
    2658           0 :     if (*q == '$')
    2659           0 :       ++q;
    2660             : 
    2661           0 :     if (base16_decode(d, DIGEST_LEN, q, strlen(q)) != DIGEST_LEN) {
    2662           0 :       *errmsg = "Data not decodeable as hex";
    2663           0 :       return -1;
    2664             :     }
    2665           0 :     status = router_get_consensus_status_by_id(d);
    2666           0 :   } else if (!strcmpstart(question, "ns/name/")) {
    2667           0 :     const node_t *n = node_get_by_nickname(question+8, 0);
    2668           0 :     status = n ? n->rs : NULL;
    2669           0 :   } else if (!strcmpstart(question, "ns/purpose/")) {
    2670           0 :     *answer = networkstatus_getinfo_by_purpose(question+11, time(NULL));
    2671           0 :     return *answer ? 0 : -1;
    2672           0 :   } else if (!strcmp(question, "consensus/packages")) {
    2673           0 :     const networkstatus_t *ns = networkstatus_get_latest_consensus();
    2674           0 :     if (ns && ns->package_lines)
    2675           0 :       *answer = smartlist_join_strings(ns->package_lines, "\n", 0, NULL);
    2676             :     else
    2677           0 :       *errmsg = "No consensus available";
    2678           0 :     return *answer ? 0 : -1;
    2679           0 :   } else if (!strcmp(question, "consensus/valid-after") ||
    2680           0 :              !strcmp(question, "consensus/fresh-until") ||
    2681           0 :              !strcmp(question, "consensus/valid-until")) {
    2682           0 :     const networkstatus_t *ns = networkstatus_get_latest_consensus();
    2683           0 :     if (ns) {
    2684           0 :       time_t t;
    2685           0 :       if (!strcmp(question, "consensus/valid-after"))
    2686           0 :         t = ns->valid_after;
    2687           0 :       else if (!strcmp(question, "consensus/fresh-until"))
    2688           0 :         t = ns->fresh_until;
    2689             :       else
    2690           0 :         t = ns->valid_until;
    2691             : 
    2692           0 :       char tbuf[ISO_TIME_LEN+1];
    2693           0 :       format_iso_time(tbuf, t);
    2694           0 :       *answer = tor_strdup(tbuf);
    2695             :     } else {
    2696           0 :       *errmsg = "No consensus available";
    2697             :     }
    2698           0 :     return *answer ? 0 : -1;
    2699             :   } else {
    2700             :     return 0;
    2701             :   }
    2702             : 
    2703           0 :   if (status)
    2704           0 :     *answer = networkstatus_getinfo_helper_single(status);
    2705             :   return 0;
    2706             : }
    2707             : 
    2708             : /** Check whether the networkstatus <b>ns</b> lists any protocol
    2709             :  * versions as "required" or "recommended" that we do not support.  If
    2710             :  * so, set *<b>warning_out</b> to a newly allocated string describing
    2711             :  * the problem.
    2712             :  *
    2713             :  * Return 1 if we should exit, 0 if we should not. */
    2714             : int
    2715           5 : networkstatus_check_required_protocols(const networkstatus_t *ns,
    2716             :                                        int client_mode,
    2717             :                                        char **warning_out)
    2718             : {
    2719           5 :   const char *func = client_mode ? "client" : "relay";
    2720           5 :   const char *required, *recommended;
    2721           5 :   char *missing = NULL;
    2722             : 
    2723          10 :   const bool consensus_postdates_this_release =
    2724           5 :     ns->valid_after >= tor_get_approx_release_date();
    2725             : 
    2726           5 :   if (! consensus_postdates_this_release) {
    2727             :     // We can't meaningfully warn about this case: This consensus is from
    2728             :     // before we were released, so whatever is says about required or
    2729             :     // recommended versions may no longer be true.
    2730             :     return 0;
    2731             :   }
    2732             : 
    2733           5 :   tor_assert(warning_out);
    2734             : 
    2735           5 :   if (client_mode) {
    2736           5 :     required = ns->required_client_protocols;
    2737           5 :     recommended = ns->recommended_client_protocols;
    2738             :   } else {
    2739           0 :     required = ns->required_relay_protocols;
    2740           0 :     recommended = ns->recommended_relay_protocols;
    2741             :   }
    2742             : 
    2743           5 :   if (!protover_all_supported(required, &missing)) {
    2744           0 :     tor_asprintf(warning_out, "At least one protocol listed as required in "
    2745             :                  "the consensus is not supported by this version of Tor. "
    2746             :                  "You should upgrade. This version of Tor will not work as a "
    2747             :                  "%s on the Tor network. The missing protocols are: %s",
    2748             :                  func, missing);
    2749           0 :     tor_free(missing);
    2750           0 :     return 1;
    2751             :   }
    2752             : 
    2753           5 :   if (! protover_all_supported(recommended, &missing)) {
    2754           0 :     tor_asprintf(warning_out, "At least one protocol listed as recommended in "
    2755             :                  "the consensus is not supported by this version of Tor. "
    2756             :                  "You should upgrade. This version of Tor will eventually "
    2757             :                  "stop working as a %s on the Tor network. The missing "
    2758             :                  "protocols are: %s",
    2759             :                  func, missing);
    2760           0 :     tor_free(missing);
    2761             :   }
    2762             : 
    2763           5 :   tor_assert_nonfatal(missing == NULL);
    2764             : 
    2765             :   return 0;
    2766             : }
    2767             : 
    2768             : /** Free all storage held locally in this module. */
    2769             : void
    2770         235 : networkstatus_free_all(void)
    2771             : {
    2772         235 :   int i;
    2773         235 :   networkstatus_vote_free(current_ns_consensus);
    2774         235 :   networkstatus_vote_free(current_md_consensus);
    2775         235 :   current_md_consensus = current_ns_consensus = NULL;
    2776             : 
    2777         705 :   for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
    2778         470 :     consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
    2779         470 :     if (waiting->consensus) {
    2780           0 :       networkstatus_vote_free(waiting->consensus);
    2781           0 :       waiting->consensus = NULL;
    2782             :     }
    2783             :   }
    2784         235 : }
    2785             : 
    2786             : /** Return the start of the next interval of size <b>interval</b> (in
    2787             :  * seconds) after <b>now</b>, plus <b>offset</b>. Midnight always
    2788             :  * starts a fresh interval, and if the last interval of a day would be
    2789             :  * truncated to less than half its size, it is rolled into the
    2790             :  * previous interval. */
    2791             : time_t
    2792         281 : voting_sched_get_start_of_interval_after(time_t now, int interval,
    2793             :                                            int offset)
    2794             : {
    2795         281 :   struct tm tm;
    2796         281 :   time_t midnight_today=0;
    2797         281 :   time_t midnight_tomorrow;
    2798         281 :   time_t next;
    2799             : 
    2800         281 :   tor_gmtime_r(&now, &tm);
    2801         281 :   tm.tm_hour = 0;
    2802         281 :   tm.tm_min = 0;
    2803         281 :   tm.tm_sec = 0;
    2804             : 
    2805         281 :   if (tor_timegm(&tm, &midnight_today) < 0) {
    2806             :     // LCOV_EXCL_START
    2807             :     log_warn(LD_BUG, "Ran into an invalid time when trying to find midnight.");
    2808             :     // LCOV_EXCL_STOP
    2809             :   }
    2810         281 :   midnight_tomorrow = midnight_today + (24*60*60);
    2811             : 
    2812         281 :   next = midnight_today + ((now-midnight_today)/interval + 1)*interval;
    2813             : 
    2814             :   /* Intervals never cross midnight. */
    2815         281 :   if (next > midnight_tomorrow)
    2816             :     next = midnight_tomorrow;
    2817             : 
    2818             :   /* If the interval would only last half as long as it's supposed to, then
    2819             :    * skip over to the next day. */
    2820         281 :   if (next + interval/2 > midnight_tomorrow)
    2821          15 :     next = midnight_tomorrow;
    2822             : 
    2823         281 :   next += offset;
    2824         281 :   if (next - interval > now)
    2825          17 :     next -= interval;
    2826             : 
    2827         281 :   return next;
    2828             : }

Generated by: LCOV version 1.14