LCOV - code coverage report
Current view: top level - test - test_dir.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 3777 3809 99.2 %
Date: 2021-11-24 03:28:48 Functions: 120 121 99.2 %

          Line data    Source code
       1             : /* Copyright (c) 2001-2004, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : #include "orconfig.h"
       7             : #include <math.h>
       8             : 
       9             : #define BWAUTH_PRIVATE
      10             : #define CONFIG_PRIVATE
      11             : #define CONTROL_GETINFO_PRIVATE
      12             : #define DIRAUTH_SYS_PRIVATE
      13             : #define DIRCACHE_PRIVATE
      14             : #define DIRCLIENT_PRIVATE
      15             : #define DIRVOTE_PRIVATE
      16             : #define DLSTATUS_PRIVATE
      17             : #define HIBERNATE_PRIVATE
      18             : #define NETWORKSTATUS_PRIVATE
      19             : #define NS_PARSE_PRIVATE
      20             : #define NODE_SELECT_PRIVATE
      21             : #define RELAY_PRIVATE
      22             : #define ROUTERLIST_PRIVATE
      23             : #define ROUTER_PRIVATE
      24             : #define UNPARSEABLE_PRIVATE
      25             : #define VOTEFLAGS_PRIVATE
      26             : 
      27             : #include "core/or/or.h"
      28             : #include "app/config/config.h"
      29             : #include "lib/confmgt/confmgt.h"
      30             : #include "core/mainloop/connection.h"
      31             : #include "core/or/relay.h"
      32             : #include "core/or/protover.h"
      33             : #include "core/or/versions.h"
      34             : #include "feature/client/bridges.h"
      35             : #include "feature/client/entrynodes.h"
      36             : #include "feature/control/control_getinfo.h"
      37             : #include "feature/dirauth/bwauth.h"
      38             : #include "feature/dirauth/dirauth_sys.h"
      39             : #include "feature/dirauth/dirvote.h"
      40             : #include "feature/dirauth/dsigs_parse.h"
      41             : #include "feature/dirauth/process_descs.h"
      42             : #include "feature/dirauth/recommend_pkg.h"
      43             : #include "feature/dirauth/shared_random_state.h"
      44             : #include "feature/dirauth/voteflags.h"
      45             : #include "feature/dircache/dircache.h"
      46             : #include "feature/dircache/dirserv.h"
      47             : #include "feature/dirclient/dirclient.h"
      48             : #include "feature/dirclient/dlstatus.h"
      49             : #include "feature/dircommon/directory.h"
      50             : #include "feature/dircommon/fp_pair.h"
      51             : #include "feature/dirauth/voting_schedule.h"
      52             : #include "feature/hibernate/hibernate.h"
      53             : #include "feature/nodelist/authcert.h"
      54             : #include "feature/nodelist/dirlist.h"
      55             : #include "feature/nodelist/microdesc.h"
      56             : #include "feature/nodelist/networkstatus.h"
      57             : #include "feature/nodelist/nickname.h"
      58             : #include "feature/nodelist/node_select.h"
      59             : #include "feature/nodelist/routerlist.h"
      60             : #include "feature/dirparse/authcert_parse.h"
      61             : #include "feature/dirparse/ns_parse.h"
      62             : #include "feature/dirparse/routerparse.h"
      63             : #include "feature/dirparse/unparseable.h"
      64             : #include "feature/nodelist/routerset.h"
      65             : #include "feature/nodelist/torcert.h"
      66             : #include "feature/relay/router.h"
      67             : #include "feature/relay/routerkeys.h"
      68             : #include "feature/relay/routermode.h"
      69             : #include "lib/compress/compress.h"
      70             : #include "lib/crypt_ops/crypto_ed25519.h"
      71             : #include "lib/crypt_ops/crypto_format.h"
      72             : #include "lib/crypt_ops/crypto_rand.h"
      73             : #include "lib/encoding/confline.h"
      74             : #include "lib/memarea/memarea.h"
      75             : #include "lib/osinfo/uname.h"
      76             : #include "test/log_test_helpers.h"
      77             : #include "test/opts_test_helpers.h"
      78             : #include "test/test.h"
      79             : #include "test/test_dir_common.h"
      80             : 
      81             : #include "core/or/addr_policy_st.h"
      82             : #include "feature/dirauth/dirauth_options_st.h"
      83             : #include "feature/nodelist/authority_cert_st.h"
      84             : #include "feature/nodelist/document_signature_st.h"
      85             : #include "feature/nodelist/extrainfo_st.h"
      86             : #include "feature/nodelist/microdesc_st.h"
      87             : #include "feature/nodelist/networkstatus_st.h"
      88             : #include "feature/nodelist/networkstatus_voter_info_st.h"
      89             : #include "feature/dirauth/ns_detached_signatures_st.h"
      90             : #include "core/or/port_cfg_st.h"
      91             : #include "feature/nodelist/routerinfo_st.h"
      92             : #include "feature/nodelist/routerlist_st.h"
      93             : #include "core/or/tor_version_st.h"
      94             : #include "feature/dirauth/vote_microdesc_hash_st.h"
      95             : #include "feature/nodelist/vote_routerstatus_st.h"
      96             : 
      97             : #ifdef HAVE_SYS_STAT_H
      98             : #include <sys/stat.h>
      99             : #endif
     100             : #ifdef HAVE_UNISTD_H
     101             : #include <unistd.h>
     102             : #endif
     103             : 
     104             : static void setup_ei_digests(void);
     105             : static uint8_t digest_ei_minimal[20];
     106             : static uint8_t digest_ei_bad_nickname[20];
     107             : static uint8_t digest_ei_maximal[20];
     108             : static uint8_t digest_ei_bad_tokens[20];
     109             : static uint8_t digest_ei_bad_sig2[20];
     110             : static uint8_t digest_ei_bad_published[20];
     111             : 
     112             : static networkstatus_t *
     113          18 : networkstatus_parse_vote_from_string_(const char *s,
     114             :                                       const char **eos_out,
     115             :                                       enum networkstatus_type_t ns_type)
     116             : {
     117          18 :   size_t len = strlen(s);
     118             :   // memdup so that it won't be nul-terminated.
     119          18 :   char *tmp = tor_memdup(s, len);
     120          18 :   networkstatus_t *result =
     121          18 :     networkstatus_parse_vote_from_string(tmp, len, eos_out, ns_type);
     122          18 :   if (eos_out && *eos_out) {
     123           0 :     *eos_out = s + (*eos_out - tmp);
     124             :   }
     125          18 :   tor_free(tmp);
     126          18 :   return result;
     127             : }
     128             : 
     129             : static void
     130           1 : test_dir_nicknames(void *arg)
     131             : {
     132           1 :   (void)arg;
     133           1 :   tt_assert( is_legal_nickname("a"));
     134           1 :   tt_assert(!is_legal_nickname(""));
     135           1 :   tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
     136           1 :   tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
     137           1 :   tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
     138           1 :   tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
     139             :   /* valid */
     140           1 :   tt_assert( is_legal_nickname_or_hexdigest(
     141             :                                  "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
     142           1 :   tt_assert( is_legal_nickname_or_hexdigest(
     143             :                          "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
     144           1 :   tt_assert( is_legal_nickname_or_hexdigest(
     145             :                          "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
     146             :   /* too short */
     147           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     148             :                                  "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
     149             :   /* illegal char */
     150           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     151             :                                  "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
     152             :   /* hex part too long */
     153           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     154             :                          "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
     155           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     156             :                          "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
     157             :   /* Bad nickname */
     158           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     159             :                          "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
     160           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     161             :                          "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
     162           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     163             :                        "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
     164           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     165             :                        "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
     166             :                        "abcdefghijklmnoppqrst"));
     167             :   /* Bad extra char. */
     168           1 :   tt_assert(!is_legal_nickname_or_hexdigest(
     169             :                          "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
     170           1 :   tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
     171           1 :   tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
     172           1 :   tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
     173           1 :  done:
     174           1 :   ;
     175           1 : }
     176             : 
     177             : /* Allocate and return a new routerinfo, with the fields set from the
     178             :  * arguments to this function.
     179             :  *
     180             :  * Also sets:
     181             :  *  - random RSA identity and onion keys,
     182             :  *  - the platform field using get_platform_str(), and
     183             :  *  - supports_tunnelled_dir_requests to 1.
     184             :  *
     185             :  * If rsa_onion_keypair_out is not NULL, it is set to the onion keypair.
     186             :  * The caller must free this keypair.
     187             :  */
     188             : static routerinfo_t *
     189           6 : basic_routerinfo_new(const char *nickname, uint32_t ipv4_addr,
     190             :                      uint16_t or_port, uint16_t dir_port,
     191             :                      uint32_t bandwidthrate, uint32_t bandwidthburst,
     192             :                      uint32_t bandwidthcapacity,
     193             :                      time_t published_on,
     194             :                      crypto_pk_t **rsa_onion_keypair_out)
     195             : {
     196           6 :   char platform[256];
     197             : 
     198           6 :   tor_assert(nickname);
     199             : 
     200           6 :   crypto_pk_t *pk1 = NULL, *pk2 = NULL;
     201             :   /* These keys are random: idx is ignored. */
     202           6 :   pk1 = pk_generate(0);
     203           6 :   pk2 = pk_generate(1);
     204             : 
     205           6 :   tor_assert(pk1);
     206           6 :   tor_assert(pk2);
     207             : 
     208           6 :   get_platform_str(platform, sizeof(platform));
     209             : 
     210           6 :   routerinfo_t *r1 = tor_malloc_zero(sizeof(routerinfo_t));
     211             : 
     212           6 :   r1->nickname = tor_strdup(nickname);
     213           6 :   r1->platform = tor_strdup(platform);
     214             : 
     215           6 :   tor_addr_from_ipv4h(&r1->ipv4_addr, ipv4_addr);
     216           6 :   r1->ipv4_orport = or_port;
     217           6 :   r1->ipv4_dirport = dir_port;
     218           6 :   r1->supports_tunnelled_dir_requests = 1;
     219             : 
     220           6 :   router_set_rsa_onion_pkey(pk1, &r1->onion_pkey, &r1->onion_pkey_len);
     221           6 :   r1->identity_pkey = pk2;
     222             : 
     223           6 :   r1->bandwidthrate = bandwidthrate;
     224           6 :   r1->bandwidthburst = bandwidthburst;
     225           6 :   r1->bandwidthcapacity = bandwidthcapacity;
     226             : 
     227           6 :   r1->cache_info.published_on = published_on;
     228           6 :   r1->protocol_list = tor_strdup(protover_get_supported_protocols());
     229             : 
     230           6 :   if (rsa_onion_keypair_out) {
     231           6 :     *rsa_onion_keypair_out = pk1;
     232             :   } else {
     233           0 :     crypto_pk_free(pk1);
     234             :   }
     235             : 
     236           6 :   return r1;
     237             : }
     238             : 
     239             : /* Allocate and return a new string containing a "router" line for r1. */
     240             : static char *
     241           6 : get_new_router_line(const routerinfo_t *r1)
     242             : {
     243           6 :   char *line = NULL;
     244             : 
     245           6 :   tor_assert(r1);
     246             : 
     247          12 :   tor_asprintf(&line,
     248             :                "router %s %s %d 0 %d\n",
     249           6 :                r1->nickname, fmt_addr(&r1->ipv4_addr),
     250           6 :                r1->ipv4_orport, r1->ipv4_dirport);
     251           6 :   tor_assert(line);
     252             : 
     253           6 :   return line;
     254             : }
     255             : 
     256             : /* Allocate and return a new string containing a "platform" line for the
     257             :  * current Tor version and OS. */
     258             : static char *
     259           6 : get_new_platform_line(void)
     260             : {
     261           6 :   char *line = NULL;
     262             : 
     263           6 :   tor_asprintf(&line,
     264             :                "platform Tor %s on %s\n",
     265             :                VERSION, get_uname());
     266           6 :   tor_assert(line);
     267             : 
     268           6 :   return line;
     269             : }
     270             : 
     271             : /* Allocate and return a new string containing a "published" line for r1.
     272             :  * r1->cache_info.published_on must be between 0 and 59 seconds. */
     273             : static char *
     274           6 : get_new_published_line(const routerinfo_t *r1)
     275             : {
     276           6 :   char *line = NULL;
     277             : 
     278           6 :   tor_assert(r1);
     279             : 
     280           6 :   tor_assert(r1->cache_info.published_on >= 0);
     281           6 :   tor_assert(r1->cache_info.published_on <= 59);
     282             : 
     283           6 :   tor_asprintf(&line,
     284             :                "published 1970-01-01 00:00:%02u\n",
     285             :                (unsigned)r1->cache_info.published_on);
     286           6 :   tor_assert(line);
     287             : 
     288           6 :   return line;
     289             : }
     290             : 
     291             : /* Allocate and return a new string containing a "fingerprint" line for r1. */
     292             : static char *
     293           6 : get_new_fingerprint_line(const routerinfo_t *r1)
     294             : {
     295           6 :   char *line = NULL;
     296           6 :   char fingerprint[FINGERPRINT_LEN+1];
     297             : 
     298           6 :   tor_assert(r1);
     299             : 
     300           6 :   tor_assert(!crypto_pk_get_fingerprint(r1->identity_pkey, fingerprint, 1));
     301           6 :   tor_assert(strlen(fingerprint) > 0);
     302             : 
     303           6 :   tor_asprintf(&line,
     304             :                "fingerprint %s\n",
     305             :                fingerprint);
     306           6 :   tor_assert(line);
     307             : 
     308           6 :   return line;
     309             : }
     310             : 
     311             : /* Allocate and return a new string containing an "uptime" line with uptime t.
     312             :  *
     313             :  * You should pass a hard-coded value to this function, because even if we made
     314             :  * it reflect uptime, that still wouldn't make it right, because the two
     315             :  * descriptors might be made on different seconds.
     316             :  */
     317             : static char *
     318           6 : get_new_uptime_line(time_t t)
     319             : {
     320           6 :   char *line = NULL;
     321             : 
     322           6 :   tor_asprintf(&line,
     323             :                "uptime %u\n",
     324             :                (unsigned)t);
     325           6 :   tor_assert(line);
     326             : 
     327           6 :   return line;
     328             : }
     329             : 
     330             : /* Allocate and return a new string containing an "bandwidth" line for r1.
     331             :  */
     332             : static char *
     333           6 : get_new_bandwidth_line(const routerinfo_t *r1)
     334             : {
     335           6 :   char *line = NULL;
     336             : 
     337           6 :   tor_assert(r1);
     338             : 
     339           6 :   tor_asprintf(&line,
     340             :                "bandwidth %u %u %u\n",
     341           6 :                r1->bandwidthrate,
     342           6 :                r1->bandwidthburst,
     343           6 :                r1->bandwidthcapacity);
     344           6 :   tor_assert(line);
     345             : 
     346           6 :   return line;
     347             : }
     348             : 
     349             : /* Allocate and return a new string containing a key_name block for the
     350             :  * RSA key pk1.
     351             :  */
     352             : static char *
     353          12 : get_new_rsa_key_block(const char *key_name, crypto_pk_t *pk1)
     354             : {
     355          12 :   char *block = NULL;
     356          12 :   char *pk1_str = NULL;
     357          12 :   size_t pk1_str_len = 0;
     358             : 
     359          12 :   tor_assert(key_name);
     360          12 :   tor_assert(pk1);
     361             : 
     362          12 :   tor_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
     363             :                                                    &pk1_str_len));
     364          12 :   tor_assert(pk1_str);
     365          12 :   tor_assert(pk1_str_len);
     366             : 
     367          12 :   tor_asprintf(&block,
     368             :                "%s\n%s",
     369             :                key_name,
     370             :                pk1_str);
     371          12 :   tor_free(pk1_str);
     372             : 
     373          12 :   tor_assert(block);
     374          12 :   return block;
     375             : }
     376             : 
     377             : /* Allocate and return a new string containing an "onion-key" block for the
     378             :  * router r1.
     379             :  */
     380             : static char *
     381           6 : get_new_onion_key_block(const routerinfo_t *r1)
     382             : {
     383           6 :   char *block = NULL;
     384           6 :   tor_assert(r1);
     385          12 :   crypto_pk_t *pk_tmp = router_get_rsa_onion_pkey(r1->onion_pkey,
     386           6 :                                                   r1->onion_pkey_len);
     387           6 :   block = get_new_rsa_key_block("onion-key", pk_tmp);
     388           6 :   crypto_pk_free(pk_tmp);
     389           6 :   return block;
     390             : }
     391             : 
     392             : /* Allocate and return a new string containing an "signing-key" block for the
     393             :  * router r1.
     394             :  */
     395             : static char *
     396           6 : get_new_signing_key_block(const routerinfo_t *r1)
     397             : {
     398           6 :   tor_assert(r1);
     399           6 :   return get_new_rsa_key_block("signing-key", r1->identity_pkey);
     400             : }
     401             : 
     402             : /* Allocate and return a new string containing an "ntor-onion-key" line for
     403             :  * the curve25519 public key ntor_onion_pubkey.
     404             :  */
     405             : static char *
     406           6 : get_new_ntor_onion_key_line(const curve25519_public_key_t *ntor_onion_pubkey)
     407             : {
     408           6 :   char *line = NULL;
     409           6 :   char cert_buf[256];
     410             : 
     411           6 :   tor_assert(ntor_onion_pubkey);
     412             : 
     413           6 :   curve25519_public_to_base64(cert_buf, ntor_onion_pubkey, false);
     414           6 :   tor_assert(strlen(cert_buf) > 0);
     415             : 
     416           6 :   tor_asprintf(&line,
     417             :                "ntor-onion-key %s\n",
     418             :                cert_buf);
     419           6 :   tor_assert(line);
     420             : 
     421           6 :   return line;
     422             : }
     423             : 
     424             : /* Allocate and return a new string containing a "bridge-distribution-request"
     425             :  * line for options.
     426             :  */
     427             : static char *
     428           6 : get_new_bridge_distribution_request_line(const or_options_t *options)
     429             : {
     430           6 :   if (options->BridgeRelay) {
     431           3 :     return tor_strdup("bridge-distribution-request any\n");
     432             :   } else {
     433           3 :     return tor_strdup("");
     434             :   }
     435             : }
     436             : 
     437             : static smartlist_t *mocked_configured_ports = NULL;
     438             : 
     439             : /** Returns mocked_configured_ports */
     440             : static const smartlist_t *
     441          18 : mock_get_configured_ports(void)
     442             : {
     443          18 :   return mocked_configured_ports;
     444             : }
     445             : 
     446             : static crypto_pk_t *mocked_server_identitykey = NULL;
     447             : 
     448             : /* Returns mocked_server_identitykey with no checks. */
     449             : static crypto_pk_t *
     450          12 : mock_get_server_identity_key(void)
     451             : {
     452          12 :   return mocked_server_identitykey;
     453             : }
     454             : 
     455             : static crypto_pk_t *mocked_onionkey = NULL;
     456             : 
     457             : /* Returns mocked_onionkey with no checks. */
     458             : static crypto_pk_t *
     459           6 : mock_get_onion_key(void)
     460             : {
     461           6 :   return mocked_onionkey;
     462             : }
     463             : 
     464             : static routerinfo_t *mocked_routerinfo = NULL;
     465             : 
     466             : /* Returns 0 and sets ri_out to mocked_routerinfo.
     467             :  * ri_out must not be NULL. There are no other checks. */
     468             : static int
     469           6 : mock_router_build_fresh_unsigned_routerinfo(routerinfo_t **ri_out)
     470             : {
     471           6 :   tor_assert(ri_out);
     472           6 :   *ri_out = mocked_routerinfo;
     473           6 :   return 0;
     474             : }
     475             : 
     476             : static ed25519_keypair_t *mocked_master_signing_key = NULL;
     477             : 
     478             : /* Returns mocked_master_signing_key with no checks. */
     479             : static const ed25519_keypair_t *
     480          12 : mock_get_master_signing_keypair(void)
     481             : {
     482          12 :   return mocked_master_signing_key;
     483             : }
     484             : 
     485             : static struct tor_cert_st *mocked_signing_key_cert = NULL;
     486             : 
     487             : /* Returns mocked_signing_key_cert with no checks. */
     488             : static const struct tor_cert_st *
     489           6 : mock_get_master_signing_key_cert(void)
     490             : {
     491           6 :   return mocked_signing_key_cert;
     492             : }
     493             : 
     494             : static curve25519_keypair_t *mocked_curve25519_onion_key = NULL;
     495             : 
     496             : /* Returns mocked_curve25519_onion_key with no checks. */
     497             : static const curve25519_keypair_t *
     498           6 : mock_get_current_curve25519_keypair(void)
     499             : {
     500           6 :   return mocked_curve25519_onion_key;
     501             : }
     502             : 
     503             : /* Unmock get_configured_ports() and free mocked_configured_ports. */
     504             : static void
     505          42 : cleanup_mock_configured_ports(void)
     506             : {
     507          42 :   UNMOCK(get_configured_ports);
     508             : 
     509          42 :   if (mocked_configured_ports) {
     510          36 :     SMARTLIST_FOREACH(mocked_configured_ports, port_cfg_t *, p, tor_free(p));
     511          18 :     smartlist_free(mocked_configured_ports);
     512             :   }
     513          42 : }
     514             : 
     515             : /* Mock get_configured_ports() with a list containing or_port and dir_port.
     516             :  * If a port is 0, don't set it.
     517             :  * Only sets the minimal data required for the tests to pass. */
     518             : static void
     519          18 : setup_mock_configured_ports(uint16_t or_port, uint16_t dir_port)
     520             : {
     521          18 :   cleanup_mock_configured_ports();
     522             : 
     523             :   /* Fake just enough of an ORPort and DirPort to get by */
     524          18 :   MOCK(get_configured_ports, mock_get_configured_ports);
     525          18 :   mocked_configured_ports = smartlist_new();
     526             : 
     527          18 :   if (or_port) {
     528          18 :     port_cfg_t *or_port_cfg = tor_malloc_zero(sizeof(*or_port_cfg));
     529          18 :     or_port_cfg->type = CONN_TYPE_OR_LISTENER;
     530          18 :     or_port_cfg->addr.family = AF_INET;
     531          18 :     or_port_cfg->port = or_port;
     532          18 :     smartlist_add(mocked_configured_ports, or_port_cfg);
     533             :   }
     534             : 
     535          18 :   if (dir_port) {
     536           0 :     port_cfg_t *dir_port_cfg = tor_malloc_zero(sizeof(*dir_port_cfg));
     537           0 :     dir_port_cfg->type = CONN_TYPE_DIR_LISTENER;
     538           0 :     dir_port_cfg->addr.family = AF_INET;
     539           0 :     dir_port_cfg->port = dir_port;
     540           0 :     smartlist_add(mocked_configured_ports, dir_port_cfg);
     541             :   }
     542          18 : }
     543             : 
     544             : /* Clean up the data structures and unmock the functions needed for generating
     545             :  * a fresh descriptor. */
     546             : static void
     547          18 : cleanup_mocks_for_fresh_descriptor(void)
     548             : {
     549          18 :   tor_free(get_options_mutable()->Nickname);
     550             : 
     551          18 :   mocked_server_identitykey = NULL;
     552          18 :   UNMOCK(get_server_identity_key);
     553             : 
     554          18 :   crypto_pk_free(mocked_onionkey);
     555          18 :   UNMOCK(get_onion_key);
     556          18 : }
     557             : 
     558             : /* Mock the data structures and functions needed for generating a fresh
     559             :  * descriptor.
     560             :  *
     561             :  * Sets options->Nickname from r1->nickname.
     562             :  * Mocks get_server_identity_key() with r1->identity_pkey.
     563             :  *
     564             :  * If rsa_onion_keypair is not NULL, it is used to mock get_onion_key().
     565             :  * Otherwise, the public key in r1->onion_pkey is used to mock get_onion_key().
     566             :  */
     567             : static void
     568           6 : setup_mocks_for_fresh_descriptor(const routerinfo_t *r1,
     569             :                                  crypto_pk_t *rsa_onion_keypair)
     570             : {
     571           6 :   cleanup_mocks_for_fresh_descriptor();
     572             : 
     573           6 :   tor_assert(r1);
     574             : 
     575             :   /* router_build_fresh_signed_extrainfo() requires options->Nickname */
     576           6 :   get_options_mutable()->Nickname = tor_strdup(r1->nickname);
     577             : 
     578             :   /* router_build_fresh_signed_extrainfo() requires get_server_identity_key().
     579             :    * Use the same one as the call to router_dump_router_to_string() above.
     580             :    */
     581           6 :   mocked_server_identitykey = r1->identity_pkey;
     582           6 :   MOCK(get_server_identity_key, mock_get_server_identity_key);
     583             : 
     584             :   /* router_dump_and_sign_routerinfo_descriptor_body() requires
     585             :    * get_onion_key(). Use the same one as r1.
     586             :    */
     587           6 :   if (rsa_onion_keypair) {
     588           6 :     mocked_onionkey = crypto_pk_dup_key(rsa_onion_keypair);
     589             :   } else {
     590           0 :     mocked_onionkey = router_get_rsa_onion_pkey(r1->onion_pkey,
     591           0 :                                                 r1->onion_pkey_len);
     592             :   }
     593           6 :   MOCK(get_onion_key, mock_get_onion_key);
     594           6 : }
     595             : 
     596             : /* Set options based on arg.
     597             :  *
     598             :  * b: BridgeRelay 1
     599             :  * e: ExtraInfoStatistics 1
     600             :  * s: sets all the individual statistics options to 1
     601             :  *
     602             :  * Always sets AssumeReachable to 1.
     603             :  *
     604             :  * Does not set ServerTransportPlugin, because it's parsed before use.
     605             :  *
     606             :  * Does not set BridgeRecordUsageByCountry, because the tests don't have access
     607             :  * to a GeoIPFile or GeoIPv6File. */
     608             : static void
     609           6 : setup_dir_formats_options(const char *arg, or_options_t *options)
     610             : {
     611             :   /* Skip reachability checks for DirPort, ORPort, and tunnelled-dir-server */
     612           6 :   options->AssumeReachable = 1;
     613             : 
     614           6 :   if (strchr(arg, 'b')) {
     615           3 :     options->BridgeRelay = 1;
     616             :   }
     617             : 
     618           6 :   if (strchr(arg, 'e')) {
     619           4 :     options->ExtraInfoStatistics = 1;
     620             :   }
     621             : 
     622           6 :   if (strchr(arg, 's')) {
     623           2 :     options->DirReqStatistics = 1;
     624           2 :     options->HiddenServiceStatistics = 1;
     625           2 :     options->EntryStatistics = 1;
     626           2 :     options->CellStatistics = 1;
     627           2 :     options->ExitPortStatistics = 1;
     628           2 :     options->ConnDirectionStatistics = 1;
     629           2 :     options->PaddingStatistics = 1;
     630             :   }
     631           6 : }
     632             : 
     633             : /* Check that routerinfos r1 and rp1 are consistent.
     634             :  * Only performs some basic checks.
     635             :  */
     636             : #define CHECK_ROUTERINFO_CONSISTENCY(r1, rp1) \
     637             : STMT_BEGIN \
     638             :   tt_assert(r1); \
     639             :   tt_assert(rp1); \
     640             :   tt_assert(tor_addr_eq(&rp1->ipv4_addr, &r1->ipv4_addr)); \
     641             :   tt_int_op(rp1->ipv4_orport,OP_EQ, r1->ipv4_orport); \
     642             :   tt_int_op(rp1->ipv4_dirport,OP_EQ, r1->ipv4_dirport); \
     643             :   tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate); \
     644             :   tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst); \
     645             :   tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity); \
     646             :   crypto_pk_t *rp1_onion_pkey = router_get_rsa_onion_pkey(rp1->onion_pkey, \
     647             :                                                       rp1->onion_pkey_len); \
     648             :   crypto_pk_t *r1_onion_pkey = router_get_rsa_onion_pkey(r1->onion_pkey, \
     649             :                                                       r1->onion_pkey_len); \
     650             :   tt_int_op(crypto_pk_cmp_keys(rp1_onion_pkey, r1_onion_pkey), OP_EQ, 0); \
     651             :   crypto_pk_free(rp1_onion_pkey); \
     652             :   crypto_pk_free(r1_onion_pkey); \
     653             :   tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, r1->identity_pkey), \
     654             :             OP_EQ, 0); \
     655             :   tt_int_op(rp1->supports_tunnelled_dir_requests, OP_EQ, \
     656             :             r1->supports_tunnelled_dir_requests); \
     657             : STMT_END
     658             : 
     659             : /* Check that routerinfo r1 and extrainfo e1 are consistent.
     660             :  * Only performs some basic checks.
     661             :  */
     662             : #define CHECK_EXTRAINFO_CONSISTENCY(r1, e1) \
     663             : STMT_BEGIN \
     664             :   tt_assert(r1); \
     665             :   tt_assert(e1); \
     666             : \
     667             :   tt_str_op(e1->nickname, OP_EQ, r1->nickname); \
     668             : STMT_END
     669             : 
     670             : /* Check that the exit policy in rp2 is as expected. */
     671             : #define CHECK_PARSED_EXIT_POLICY(rp2) \
     672             : STMT_BEGIN \
     673             :   tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2); \
     674             :  \
     675             :   p = smartlist_get(rp2->exit_policy, 0); \
     676             :   tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT); \
     677             :   tt_assert(tor_addr_is_null(&p->addr)); \
     678             :   tt_int_op(p->maskbits,OP_EQ, 0); \
     679             :   tt_int_op(p->prt_min,OP_EQ, 80); \
     680             :   tt_int_op(p->prt_max,OP_EQ, 80); \
     681             :  \
     682             :   p = smartlist_get(rp2->exit_policy, 1); \
     683             :   tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT); \
     684             :   tt_assert(tor_addr_eq(&p->addr, &ex2->addr)); \
     685             :   tt_int_op(p->maskbits,OP_EQ, 8); \
     686             :   tt_int_op(p->prt_min,OP_EQ, 24); \
     687             :   tt_int_op(p->prt_max,OP_EQ, 24); \
     688             : STMT_END
     689             : 
     690             : /** Run unit tests for router descriptor generation logic for a RSA + ed25519
     691             :  * router.
     692             :  */
     693             : static void
     694           6 : test_dir_formats_rsa_ed25519(void *arg)
     695             : {
     696           6 :   char *buf = NULL;
     697           6 :   char *buf2 = NULL;
     698           6 :   char *cp = NULL;
     699             : 
     700           6 :   crypto_pk_t *r2_onion_pkey = NULL;
     701           6 :   char cert_buf[256];
     702           6 :   uint8_t *rsa_cc = NULL;
     703           6 :   time_t now = time(NULL);
     704             : 
     705           6 :   routerinfo_t *r2 = NULL;
     706           6 :   extrainfo_t *e2 = NULL;
     707           6 :   routerinfo_t *r2_out = NULL;
     708           6 :   routerinfo_t *rp2 = NULL;
     709           6 :   extrainfo_t *ep2 = NULL;
     710           6 :   addr_policy_t *ex1, *ex2;
     711           6 :   const addr_policy_t *p;
     712             : 
     713           6 :   smartlist_t *chunks = NULL;
     714           6 :   int rv = -1;
     715             : 
     716           6 :   or_options_t *options = get_options_mutable();
     717           6 :   setup_dir_formats_options((const char *)arg, options);
     718             : 
     719           6 :   hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
     720             : 
     721             :   /* r2 is a RSA + ed25519 descriptor, with an exit policy, but no DirPort or
     722             :    * IPv6 */
     723           6 :   r2 = basic_routerinfo_new("Fred", 0x0a030201u /* 10.3.2.1 */,
     724             :                             9005, 0,
     725             :                             3000, 3000, 3000,
     726             :                             5,
     727             :                             &r2_onion_pkey);
     728             : 
     729             :   /* Fake just enough of an ntor key to get by */
     730           6 :   curve25519_keypair_t r2_onion_keypair;
     731           6 :   curve25519_keypair_generate(&r2_onion_keypair, 0);
     732           6 :   r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
     733             :                                          sizeof(curve25519_public_key_t));
     734             : 
     735             :   /* Now add relay ed25519 keys
     736             :    * We can't use init_mock_ed_keys() here, because the keys are seeded */
     737           6 :   ed25519_keypair_t kp1, kp2;
     738           6 :   ed25519_secret_key_from_seed(&kp1.seckey,
     739             :                           (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
     740           6 :   ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
     741           6 :   ed25519_secret_key_from_seed(&kp2.seckey,
     742             :                           (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
     743           6 :   ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
     744           6 :   r2->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
     745             :                                          CERT_TYPE_ID_SIGNING,
     746             :                                          &kp2.pubkey,
     747             :                                          now, 86400,
     748             :                                          CERT_FLAG_INCLUDE_SIGNING_KEY);
     749             : 
     750             :   /* Now add an exit policy */
     751           6 :   ex1 = tor_malloc_zero(sizeof(addr_policy_t));
     752           6 :   ex2 = tor_malloc_zero(sizeof(addr_policy_t));
     753           6 :   ex1->policy_type = ADDR_POLICY_ACCEPT;
     754           6 :   tor_addr_from_ipv4h(&ex1->addr, 0);
     755           6 :   ex1->maskbits = 0;
     756           6 :   ex1->prt_min = ex1->prt_max = 80;
     757           6 :   ex2->policy_type = ADDR_POLICY_REJECT;
     758           6 :   tor_addr_from_ipv4h(&ex2->addr, 18<<24);
     759           6 :   ex2->maskbits = 8;
     760           6 :   ex2->prt_min = ex2->prt_max = 24;
     761             : 
     762           6 :   r2->exit_policy = smartlist_new();
     763           6 :   smartlist_add(r2->exit_policy, ex1);
     764           6 :   smartlist_add(r2->exit_policy, ex2);
     765             : 
     766             :   /* Fake just enough of an ORPort to get by */
     767           6 :   setup_mock_configured_ports(r2->ipv4_orport, 0);
     768             : 
     769          12 :   buf = router_dump_router_to_string(r2,
     770           6 :                                      r2->identity_pkey, r2_onion_pkey,
     771             :                                      &r2_onion_keypair, &kp2);
     772           6 :   tt_assert(buf);
     773             : 
     774           6 :   cleanup_mock_configured_ports();
     775             : 
     776           6 :   chunks = smartlist_new();
     777             : 
     778             :   /* Synthesise a router descriptor, without the signatures */
     779           6 :   smartlist_add(chunks, get_new_router_line(r2));
     780             : 
     781           6 :   smartlist_add_strdup(chunks,
     782             :                        "identity-ed25519\n"
     783             :                        "-----BEGIN ED25519 CERT-----\n");
     784           6 :   base64_encode(cert_buf, sizeof(cert_buf),
     785           6 :                 (const char*)r2->cache_info.signing_key_cert->encoded,
     786           6 :                 r2->cache_info.signing_key_cert->encoded_len,
     787             :                 BASE64_ENCODE_MULTILINE);
     788           6 :   smartlist_add_strdup(chunks, cert_buf);
     789           6 :   smartlist_add_strdup(chunks, "-----END ED25519 CERT-----\n");
     790             : 
     791           6 :   smartlist_add_strdup(chunks, "master-key-ed25519 ");
     792             :   {
     793           6 :     char k[ED25519_BASE64_LEN+1];
     794           6 :     ed25519_public_to_base64(k, &r2->cache_info.signing_key_cert->signing_key);
     795           6 :     smartlist_add_strdup(chunks, k);
     796           6 :     smartlist_add_strdup(chunks, "\n");
     797             :   }
     798             : 
     799           6 :   smartlist_add(chunks, get_new_platform_line());
     800           6 :   smartlist_add_asprintf(chunks,
     801             :                          "proto %s\n", protover_get_supported_protocols());
     802           6 :   smartlist_add(chunks, get_new_published_line(r2));
     803           6 :   smartlist_add(chunks, get_new_fingerprint_line(r2));
     804             : 
     805           6 :   smartlist_add(chunks, get_new_uptime_line(0));
     806           6 :   smartlist_add(chunks, get_new_bandwidth_line(r2));
     807             : 
     808           6 :   smartlist_add(chunks, get_new_onion_key_block(r2));
     809           6 :   smartlist_add(chunks, get_new_signing_key_block(r2));
     810             : 
     811           6 :   int rsa_cc_len;
     812          12 :   rsa_cc = make_tap_onion_key_crosscert(r2_onion_pkey,
     813             :                                         &kp1.pubkey,
     814           6 :                                         r2->identity_pkey,
     815             :                                         &rsa_cc_len);
     816           6 :   tt_assert(rsa_cc);
     817           6 :   base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
     818             :                 BASE64_ENCODE_MULTILINE);
     819           6 :   smartlist_add_strdup(chunks, "onion-key-crosscert\n"
     820             :                        "-----BEGIN CROSSCERT-----\n");
     821           6 :   smartlist_add_strdup(chunks, cert_buf);
     822           6 :   smartlist_add_strdup(chunks, "-----END CROSSCERT-----\n");
     823           6 :   int ntor_cc_sign;
     824             :   {
     825           6 :     tor_cert_t *ntor_cc = NULL;
     826           6 :     ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
     827             :                                           &kp1.pubkey,
     828             :                                           r2->cache_info.published_on,
     829           6 :                                           get_onion_key_lifetime(),
     830             :                                           &ntor_cc_sign);
     831           6 :     tt_assert(ntor_cc);
     832           6 :     base64_encode(cert_buf, sizeof(cert_buf),
     833           6 :                 (char*)ntor_cc->encoded, ntor_cc->encoded_len,
     834             :                 BASE64_ENCODE_MULTILINE);
     835           6 :     tor_cert_free(ntor_cc);
     836             :   }
     837           6 :   smartlist_add_asprintf(chunks,
     838             :                "ntor-onion-key-crosscert %d\n"
     839             :                "-----BEGIN ED25519 CERT-----\n"
     840             :                "%s"
     841             :                "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
     842             : 
     843           6 :   smartlist_add_strdup(chunks, "hidden-service-dir\n");
     844             : 
     845           6 :   smartlist_add(chunks, get_new_bridge_distribution_request_line(options));
     846           6 :   smartlist_add(chunks, get_new_ntor_onion_key_line(&r2_onion_keypair.pubkey));
     847           6 :   smartlist_add_strdup(chunks, "accept *:80\nreject 18.0.0.0/8:24\n");
     848           6 :   smartlist_add_strdup(chunks, "tunnelled-dir-server\n");
     849             : 
     850           6 :   smartlist_add_strdup(chunks, "router-sig-ed25519 ");
     851             : 
     852           6 :   size_t len_out = 0;
     853           6 :   buf2 = smartlist_join_strings(chunks, "", 0, &len_out);
     854         156 :   SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
     855           6 :   smartlist_free(chunks);
     856             : 
     857           6 :   tt_assert(len_out > 0);
     858             : 
     859           6 :   buf[strlen(buf2)] = '\0'; /* Don't compare either sig; they're never the same
     860             :                              * twice */
     861             : 
     862           6 :   tt_str_op(buf, OP_EQ, buf2);
     863           6 :   tor_free(buf);
     864             : 
     865           6 :   setup_mock_configured_ports(r2->ipv4_orport, 0);
     866             : 
     867           6 :   buf = router_dump_router_to_string(r2, r2->identity_pkey,
     868             :                                      r2_onion_pkey,
     869             :                                      &r2_onion_keypair, &kp2);
     870           6 :   tt_assert(buf);
     871             : 
     872           6 :   cleanup_mock_configured_ports();
     873             : 
     874             :   /* Now, try to parse buf */
     875           6 :   cp = buf;
     876           6 :   rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
     877             : 
     878           6 :   CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
     879             : 
     880           6 :   tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
     881             :              r2->onion_curve25519_pkey->public_key,
     882           6 :              CURVE25519_PUBKEY_LEN);
     883             : 
     884           6 :   CHECK_PARSED_EXIT_POLICY(rp2);
     885             : 
     886           6 :   tor_free(buf);
     887           6 :   routerinfo_free(rp2);
     888             : 
     889             :   /* Test extrainfo creation. */
     890             : 
     891             :   /* Set up standard mocks and data */
     892           6 :   setup_mocks_for_fresh_descriptor(r2, r2_onion_pkey);
     893             : 
     894             :   /* router_build_fresh_descriptor() requires
     895             :    * router_build_fresh_unsigned_routerinfo(), but the implementation is
     896             :    * too complex. Instead, we re-use r2.
     897             :    */
     898           6 :   mocked_routerinfo = r2;
     899           6 :   MOCK(router_build_fresh_unsigned_routerinfo,
     900             :        mock_router_build_fresh_unsigned_routerinfo);
     901             : 
     902             :   /* r2 uses ed25519, so we need to mock the ed key functions */
     903           6 :   mocked_master_signing_key = &kp2;
     904           6 :   MOCK(get_master_signing_keypair, mock_get_master_signing_keypair);
     905             : 
     906           6 :   mocked_signing_key_cert = r2->cache_info.signing_key_cert;
     907           6 :   MOCK(get_master_signing_key_cert, mock_get_master_signing_key_cert);
     908             : 
     909           6 :   mocked_curve25519_onion_key = &r2_onion_keypair;
     910           6 :   MOCK(get_current_curve25519_keypair, mock_get_current_curve25519_keypair);
     911             : 
     912             :   /* Fake just enough of an ORPort to get by */
     913           6 :   setup_mock_configured_ports(r2->ipv4_orport, 0);
     914             : 
     915             :   /* Test the high-level interface. */
     916           6 :   rv = router_build_fresh_descriptor(&r2_out, &e2);
     917           6 :   if (rv < 0) {
     918             :     /* router_build_fresh_descriptor() frees r2 on failure. */
     919           0 :     r2 = NULL;
     920             :     /* Get rid of an alias to rp2 */
     921           0 :     r2_out = NULL;
     922             :   }
     923           6 :   tt_assert(rv == 0);
     924           6 :   tt_assert(r2_out);
     925           6 :   tt_assert(e2);
     926             :   /* Guaranteed by mock_router_build_fresh_unsigned_routerinfo() */
     927           6 :   tt_ptr_op(r2_out, OP_EQ, r2);
     928             :   /* Get rid of an alias to r2 */
     929           6 :   r2_out = NULL;
     930             : 
     931             :   /* Now cleanup */
     932           6 :   cleanup_mocks_for_fresh_descriptor();
     933             : 
     934           6 :   mocked_routerinfo = NULL;
     935           6 :   UNMOCK(router_build_fresh_unsigned_routerinfo);
     936           6 :   mocked_master_signing_key = NULL;
     937           6 :   UNMOCK(get_master_signing_keypair);
     938           6 :   mocked_signing_key_cert = NULL;
     939           6 :   UNMOCK(get_master_signing_key_cert);
     940           6 :   mocked_curve25519_onion_key = NULL;
     941           6 :   UNMOCK(get_current_curve25519_keypair);
     942             : 
     943           6 :   cleanup_mock_configured_ports();
     944             : 
     945           6 :   CHECK_EXTRAINFO_CONSISTENCY(r2, e2);
     946             : 
     947             :   /* Test that the signed ri is parseable */
     948           6 :   tt_assert(r2->cache_info.signed_descriptor_body);
     949           6 :   cp = r2->cache_info.signed_descriptor_body;
     950           6 :   rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
     951             : 
     952           6 :   CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
     953             : 
     954           6 :   tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
     955             :             r2->onion_curve25519_pkey->public_key,
     956           6 :             CURVE25519_PUBKEY_LEN);
     957             : 
     958           6 :   CHECK_PARSED_EXIT_POLICY(rp2);
     959             : 
     960           6 :   routerinfo_free(rp2);
     961             : 
     962             :   /* Test that the signed ei is parseable */
     963           6 :   tt_assert(e2->cache_info.signed_descriptor_body);
     964           6 :   cp = e2->cache_info.signed_descriptor_body;
     965           6 :   ep2 = extrainfo_parse_entry_from_string((const char*)cp,NULL,1,NULL,NULL);
     966             : 
     967           6 :   CHECK_EXTRAINFO_CONSISTENCY(r2, ep2);
     968             : 
     969             :   /* In future tests, we could check the actual extrainfo statistics. */
     970             : 
     971           6 :   extrainfo_free(ep2);
     972             : 
     973           6 :  done:
     974           6 :   dirserv_free_fingerprint_list();
     975             : 
     976           6 :   tor_free(options->Nickname);
     977             : 
     978           6 :   cleanup_mock_configured_ports();
     979           6 :   cleanup_mocks_for_fresh_descriptor();
     980             : 
     981           6 :   if (chunks) {
     982           0 :     SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
     983           0 :     smartlist_free(chunks);
     984             :   }
     985             : 
     986           6 :   routerinfo_free(r2);
     987           6 :   routerinfo_free(r2_out);
     988           6 :   routerinfo_free(rp2);
     989             : 
     990           6 :   extrainfo_free(e2);
     991           6 :   extrainfo_free(ep2);
     992             : 
     993           6 :   tor_free(rsa_cc);
     994           6 :   crypto_pk_free(r2_onion_pkey);
     995             : 
     996           6 :   tor_free(buf);
     997           6 :   tor_free(buf2);
     998           6 : }
     999             : 
    1000             : #include "failing_routerdescs.inc"
    1001             : 
    1002             : static void
    1003           1 : test_dir_routerinfo_parsing(void *arg)
    1004             : {
    1005           1 :   (void) arg;
    1006             : 
    1007           1 :   int again;
    1008           1 :   routerinfo_t *ri = NULL;
    1009             : 
    1010             : #define CHECK_OK(s)                                                     \
    1011             :   do {                                                                  \
    1012             :     routerinfo_free(ri);                                                \
    1013             :     ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL);   \
    1014             :     tt_assert(ri);                                                      \
    1015             :   } while (0)
    1016             : #define CHECK_FAIL(s, againval)                                         \
    1017             :   do {                                                                  \
    1018             :     routerinfo_free(ri);                                                \
    1019             :     again = 999;                                                        \
    1020             :     ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
    1021             :     tt_assert(ri == NULL);                                              \
    1022             :     tt_int_op(again, OP_EQ, (againval));                                \
    1023             :   } while (0)
    1024             : 
    1025           1 :   CHECK_OK(EX_RI_MINIMAL);
    1026           1 :   CHECK_OK(EX_RI_MAXIMAL);
    1027             : 
    1028             :   /* good annotations prepended */
    1029           1 :   routerinfo_free(ri);
    1030           1 :   ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
    1031             :                                       "@purpose bridge\n", NULL);
    1032           1 :   tt_ptr_op(ri, OP_NE, NULL);
    1033           1 :   tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
    1034           1 :   routerinfo_free(ri);
    1035             : 
    1036             :   /* bad annotations prepended. */
    1037           1 :   ri = router_parse_entry_from_string(EX_RI_MINIMAL,
    1038             :                                       NULL, 0, 0, "@purpose\n", NULL);
    1039           1 :   tt_ptr_op(ri, OP_EQ, NULL);
    1040             : 
    1041             :   /* bad annotations on router. */
    1042           1 :   ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
    1043             :                                       NULL, NULL);
    1044           1 :   tt_ptr_op(ri, OP_EQ, NULL);
    1045             : 
    1046             :   /* unwanted annotations on router. */
    1047           1 :   ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
    1048             :                                       NULL, NULL);
    1049           1 :   tt_ptr_op(ri, OP_EQ, NULL);
    1050             : 
    1051             :   /* No signature. */
    1052           1 :   ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
    1053             :                                       NULL, NULL);
    1054           1 :   tt_ptr_op(ri, OP_EQ, NULL);
    1055             : 
    1056             :   /* Not a router */
    1057           1 :   routerinfo_free(ri);
    1058           1 :   ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
    1059           1 :   tt_ptr_op(ri, OP_EQ, NULL);
    1060             : 
    1061           1 :   CHECK_FAIL(EX_RI_BAD_SIG1, 1);
    1062           1 :   CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
    1063           1 :   CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
    1064           1 :   CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
    1065           1 :   CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
    1066           1 :   CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
    1067           1 :   CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
    1068           1 :   CHECK_FAIL(EX_RI_BAD_ONIONKEY, 0);
    1069           1 :   CHECK_FAIL(EX_RI_BAD_PORTS, 0);
    1070           1 :   CHECK_FAIL(EX_RI_BAD_IP, 0);
    1071           1 :   CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
    1072           1 :   CHECK_FAIL(EX_RI_BAD_NAME2, 0);
    1073           1 :   CHECK_FAIL(EX_RI_BAD_UPTIME, 0);
    1074             : 
    1075           1 :   CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
    1076           1 :   CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
    1077           1 :   CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
    1078           1 :   CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
    1079           1 :   CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
    1080           1 :   CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
    1081           1 :   CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
    1082           1 :   CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
    1083           1 :   CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
    1084             : 
    1085           1 :   CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
    1086           1 :   CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
    1087           1 :   CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
    1088           1 :   CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
    1089           1 :   CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
    1090           1 :   CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
    1091           1 :   CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
    1092           1 :   CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
    1093           1 :   CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
    1094           1 :   CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
    1095             : 
    1096             : #undef CHECK_FAIL
    1097             : #undef CHECK_OK
    1098           1 :  done:
    1099           1 :   routerinfo_free(ri);
    1100           1 : }
    1101             : 
    1102             : #include "example_extrainfo.inc"
    1103             : 
    1104             : static void
    1105          17 : routerinfo_free_wrapper_(void *arg)
    1106             : {
    1107          17 :   routerinfo_free_(arg);
    1108          17 : }
    1109             : 
    1110             : static void
    1111           1 : test_dir_extrainfo_parsing(void *arg)
    1112             : {
    1113           1 :   (void) arg;
    1114             : 
    1115             : #define CHECK_OK(s)                                                     \
    1116             :   do {                                                                  \
    1117             :     extrainfo_free(ei);                                                 \
    1118             :     ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL);    \
    1119             :     tt_assert(ei);                                                      \
    1120             :   } while (0)
    1121             : #define CHECK_FAIL(s, againval)                                         \
    1122             :   do {                                                                  \
    1123             :     extrainfo_free(ei);                                                 \
    1124             :     again = 999;                                                        \
    1125             :     ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again);  \
    1126             :     tt_assert(ei == NULL);                                              \
    1127             :     tt_int_op(again, OP_EQ, (againval));                                   \
    1128             :   } while (0)
    1129             : #define ADD(name)                                                       \
    1130             :   do {                                                                  \
    1131             :     ri = tor_malloc_zero(sizeof(routerinfo_t));                         \
    1132             :     crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new();              \
    1133             :     tt_assert(! crypto_pk_read_public_key_from_string(pk,               \
    1134             :                                       name##_KEY, strlen(name##_KEY))); \
    1135             :     tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
    1136             :     digestmap_set((digestmap_t*)map, d, ri);                            \
    1137             :     ri = NULL;                                                          \
    1138             :   } while (0)
    1139             : 
    1140           1 :   routerinfo_t *ri = NULL;
    1141           1 :   char d[20];
    1142           1 :   struct digest_ri_map_t *map = NULL;
    1143           1 :   extrainfo_t *ei = NULL;
    1144           1 :   int again;
    1145             : 
    1146           1 :   CHECK_OK(EX_EI_MINIMAL);
    1147           1 :   tt_assert(ei->pending_sig);
    1148           1 :   CHECK_OK(EX_EI_MAXIMAL);
    1149           1 :   tt_assert(ei->pending_sig);
    1150             : 
    1151           1 :   map = (struct digest_ri_map_t *)digestmap_new();
    1152           1 :   ADD(EX_EI_MINIMAL);
    1153           1 :   ADD(EX_EI_MAXIMAL);
    1154           1 :   ADD(EX_EI_BAD_NICKNAME);
    1155           1 :   ADD(EX_EI_BAD_TOKENS);
    1156           1 :   ADD(EX_EI_BAD_START);
    1157           1 :   ADD(EX_EI_BAD_PUBLISHED);
    1158             : 
    1159           1 :   ADD(EX_EI_ED_MISSING_SIG);
    1160           1 :   ADD(EX_EI_ED_MISSING_CERT);
    1161           1 :   ADD(EX_EI_ED_BAD_CERT1);
    1162           1 :   ADD(EX_EI_ED_BAD_CERT2);
    1163           1 :   ADD(EX_EI_ED_MISPLACED_CERT);
    1164           1 :   ADD(EX_EI_ED_MISPLACED_SIG);
    1165             : 
    1166           1 :   CHECK_OK(EX_EI_MINIMAL);
    1167           1 :   tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
    1168           1 :   CHECK_OK(EX_EI_MAXIMAL);
    1169           1 :   tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
    1170             : 
    1171           1 :   CHECK_FAIL(EX_EI_BAD_SIG1,1);
    1172           1 :   CHECK_FAIL(EX_EI_BAD_SIG2,0);
    1173           1 :   CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
    1174           1 :   CHECK_FAIL(EX_EI_BAD_TOKENS,0);
    1175           1 :   CHECK_FAIL(EX_EI_BAD_START,0);
    1176           1 :   CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
    1177             : 
    1178           1 :   CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
    1179           1 :   CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
    1180           1 :   CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
    1181           1 :   CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
    1182           1 :   CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
    1183           1 :   CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
    1184             : 
    1185             : #undef CHECK_OK
    1186             : #undef CHECK_FAIL
    1187             : 
    1188           1 :  done:
    1189           1 :   escaped(NULL);
    1190           1 :   extrainfo_free(ei);
    1191           1 :   routerinfo_free(ri);
    1192           1 :   digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
    1193           1 : }
    1194             : 
    1195             : static void
    1196           1 : test_dir_parse_router_list(void *arg)
    1197             : {
    1198           1 :   (void) arg;
    1199           1 :   smartlist_t *invalid = smartlist_new();
    1200           1 :   smartlist_t *dest = smartlist_new();
    1201           1 :   smartlist_t *chunks = smartlist_new();
    1202           1 :   int dest_has_ri = 1;
    1203           1 :   char *list = NULL;
    1204           1 :   const char *cp;
    1205           1 :   digestmap_t *map = NULL;
    1206           1 :   char *mem_op_hex_tmp = NULL;
    1207           1 :   routerinfo_t *ri = NULL;
    1208           1 :   char d[DIGEST_LEN];
    1209             : 
    1210           1 :   smartlist_add_strdup(chunks, EX_RI_MINIMAL);     // ri 0
    1211           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);   // bad ri 0
    1212           1 :   smartlist_add_strdup(chunks, EX_EI_MAXIMAL);     // ei 0
    1213           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_SIG2);    // bad ei --
    1214           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
    1215           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);    // bad ri --
    1216           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);  // bad ei 1
    1217           1 :   smartlist_add_strdup(chunks, EX_RI_MAXIMAL);     // ri 1
    1218           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY);  // bad ri 1
    1219           1 :   smartlist_add_strdup(chunks, EX_EI_MINIMAL);     // ei 1
    1220             : 
    1221           1 :   list = smartlist_join_strings(chunks, "", 0, NULL);
    1222             : 
    1223             :   /* First, parse the routers. */
    1224           1 :   cp = list;
    1225           1 :   tt_int_op(0,OP_EQ,
    1226             :             router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
    1227             :                                           0, 0, NULL, invalid));
    1228           1 :   tt_int_op(2, OP_EQ, smartlist_len(dest));
    1229           1 :   tt_ptr_op(cp, OP_EQ, list + strlen(list));
    1230             : 
    1231           1 :   routerinfo_t *r = smartlist_get(dest, 0);
    1232           1 :   tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
    1233           1 :             EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
    1234           1 :   r = smartlist_get(dest, 1);
    1235           1 :   tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
    1236           1 :             EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));
    1237             : 
    1238           1 :   setup_ei_digests();
    1239             : 
    1240           1 :   tt_int_op(2, OP_EQ, smartlist_len(invalid));
    1241             : 
    1242           1 :   test_memeq_hex(smartlist_get(invalid, 0),
    1243             :                  "10F951AF93AED0D3BC7FA5FFA232EB8C17747ACE");
    1244           1 :   test_memeq_hex(smartlist_get(invalid, 1),
    1245             :                  "41D8723CDD4B1AADCCE538C28CDE7F69828C73D0");
    1246             : 
    1247             :   /* Now tidy up */
    1248           3 :   SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
    1249           3 :   SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
    1250           1 :   smartlist_clear(dest);
    1251           1 :   smartlist_clear(invalid);
    1252             : 
    1253             :   /* And check extrainfos. */
    1254           1 :   dest_has_ri = 0;
    1255           1 :   map = (digestmap_t*)router_get_routerlist()->identity_map;
    1256           1 :   ADD(EX_EI_MINIMAL);
    1257           1 :   ADD(EX_EI_MAXIMAL);
    1258           1 :   ADD(EX_EI_BAD_NICKNAME);
    1259           1 :   ADD(EX_EI_BAD_PUBLISHED);
    1260           1 :   ADD(EX_EI_BAD_SIG2);
    1261           1 :   cp = list;
    1262           1 :   tt_int_op(0,OP_EQ,
    1263             :             router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
    1264             :                                           1, 0, NULL, invalid));
    1265           1 :   tt_int_op(2, OP_EQ, smartlist_len(dest));
    1266           1 :   extrainfo_t *e = smartlist_get(dest, 0);
    1267           1 :   tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
    1268           1 :             EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
    1269           1 :   e = smartlist_get(dest, 1);
    1270           1 :   tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
    1271           1 :             EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));
    1272             : 
    1273           1 :   tt_int_op(3, OP_EQ, smartlist_len(invalid));
    1274           1 :   tt_mem_op(smartlist_get(invalid, 0),
    1275             :             OP_EQ,
    1276           1 :             digest_ei_bad_sig2, DIGEST_LEN);
    1277           1 :   tt_mem_op(smartlist_get(invalid, 1),
    1278             :             OP_EQ,
    1279           1 :             digest_ei_bad_nickname, DIGEST_LEN);
    1280           1 :   tt_mem_op(smartlist_get(invalid, 2),
    1281             :             OP_EQ,
    1282           1 :             digest_ei_bad_published, DIGEST_LEN);
    1283             : 
    1284           1 :  done:
    1285           1 :   tor_free(list);
    1286           1 :   if (dest_has_ri)
    1287           0 :     SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
    1288             :   else
    1289           3 :     SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
    1290           1 :   smartlist_free(dest);
    1291           4 :   SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
    1292           1 :   smartlist_free(invalid);
    1293          11 :   SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
    1294           1 :   smartlist_free(chunks);
    1295           1 :   routerinfo_free(ri);
    1296           1 :   if (map) {
    1297           1 :     digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
    1298           1 :     router_get_routerlist()->identity_map =
    1299           1 :       (struct digest_ri_map_t*)digestmap_new();
    1300             :   }
    1301           1 :   tor_free(mem_op_hex_tmp);
    1302             : 
    1303             : #undef ADD
    1304           1 : }
    1305             : 
    1306             : static download_status_t dls_minimal;
    1307             : static download_status_t dls_maximal;
    1308             : static download_status_t dls_bad_fingerprint;
    1309             : static download_status_t dls_bad_sig1;
    1310             : static download_status_t dls_bad_ports;
    1311             : static download_status_t dls_bad_tokens;
    1312             : 
    1313             : static uint8_t digest_minimal[20];
    1314             : static uint8_t digest_maximal[20];
    1315             : static uint8_t digest_bad_fingerprint[20];
    1316             : static uint8_t digest_bad_sig1[20];
    1317             : static uint8_t digest_bad_ports[20];
    1318             : static uint8_t digest_bad_tokens[20];
    1319             : 
    1320             : static void
    1321           1 : setup_dls_digests(void)
    1322             : {
    1323             : #define SETUP(string, name)                                             \
    1324             :   do {                                                                  \
    1325             :     router_get_router_hash(string, strlen(string), (char*)digest_##name); \
    1326             :   } while (0)
    1327             : 
    1328           1 :   SETUP(EX_RI_MINIMAL, minimal);
    1329           1 :   SETUP(EX_RI_MAXIMAL, maximal);
    1330           1 :   SETUP(EX_RI_BAD_FINGERPRINT, bad_fingerprint);
    1331           1 :   SETUP(EX_RI_BAD_SIG1, bad_sig1);
    1332           1 :   SETUP(EX_RI_BAD_PORTS, bad_ports);
    1333           1 :   SETUP(EX_RI_BAD_TOKENS, bad_tokens);
    1334             : #undef SETUP
    1335           1 : }
    1336             : 
    1337             : static int mock_router_get_dl_status_unrecognized = 0;
    1338             : static int mock_router_get_dl_status_calls = 0;
    1339             : 
    1340             : static download_status_t *
    1341           2 : mock_router_get_dl_status(const char *d)
    1342             : {
    1343           2 :   ++mock_router_get_dl_status_calls;
    1344             : #define CHECK(name)                                         \
    1345             :   do {                                                      \
    1346             :     if (fast_memeq(d, digest_##name, DIGEST_LEN))           \
    1347             :       return &dls_##name;                                   \
    1348             :   } while (0)
    1349             : 
    1350           2 :   CHECK(minimal);
    1351           2 :   CHECK(maximal);
    1352           2 :   CHECK(bad_fingerprint);
    1353           1 :   CHECK(bad_sig1);
    1354           1 :   CHECK(bad_ports);
    1355           1 :   CHECK(bad_tokens);
    1356             : 
    1357           0 :   ++mock_router_get_dl_status_unrecognized;
    1358           0 :   return NULL;
    1359             : #undef CHECK
    1360             : }
    1361             : 
    1362             : static void
    1363           1 : test_dir_load_routers(void *arg)
    1364             : {
    1365           1 :   (void) arg;
    1366           1 :   smartlist_t *chunks = smartlist_new();
    1367           1 :   smartlist_t *wanted = smartlist_new();
    1368           1 :   char buf[DIGEST_LEN];
    1369           1 :   char *mem_op_hex_tmp = NULL;
    1370           1 :   char *list = NULL;
    1371             : 
    1372             : #define ADD(str)                                                        \
    1373             :   do {                                                                  \
    1374             :     tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf));      \
    1375             :     smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN));        \
    1376             :   } while (0)
    1377             : 
    1378           1 :   setup_dls_digests();
    1379             : 
    1380           1 :   MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
    1381             : 
    1382           1 :   update_approx_time(1412510400);
    1383             : 
    1384           1 :   smartlist_add_strdup(chunks, EX_RI_MINIMAL);
    1385           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
    1386           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);
    1387           1 :   smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
    1388           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
    1389           1 :   smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
    1390             : 
    1391             :   /* not ADDing MINIMAL */
    1392           1 :   ADD(EX_RI_MAXIMAL);
    1393           1 :   ADD(EX_RI_BAD_FINGERPRINT);
    1394           1 :   ADD(EX_RI_BAD_SIG1);
    1395             :   /* Not ADDing BAD_PORTS */
    1396           1 :   ADD(EX_RI_BAD_TOKENS);
    1397             : 
    1398           1 :   list = smartlist_join_strings(chunks, "", 0, NULL);
    1399           1 :   tt_int_op(1, OP_EQ,
    1400             :             router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
    1401             :                                             wanted, 1, NULL));
    1402             : 
    1403             :   /* The "maximal" router was added. */
    1404             :   /* "minimal" was not. */
    1405           1 :   tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
    1406           1 :   routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
    1407           1 :   test_memeq_hex(r->cache_info.signed_descriptor_digest,
    1408             :                  "1F437798ACD1FC9CBD1C3C04DBF80F7E9F819C3F");
    1409           1 :   tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
    1410           1 :   tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
    1411             : 
    1412             :   /* "Bad fingerprint" and "Bad tokens" should have gotten marked
    1413             :    * non-retriable. */
    1414           1 :   tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
    1415           1 :   tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
    1416           1 :   tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
    1417           1 :   tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
    1418             : 
    1419             :   /* bad_sig2 and bad ports" are retriable -- one since only the signature
    1420             :    * was bad, and one because we didn't ask for it. */
    1421           1 :   tt_int_op(dls_bad_sig1.n_download_failures, OP_EQ, 0);
    1422           1 :   tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
    1423             : 
    1424           1 :   tt_int_op(smartlist_len(wanted), OP_EQ, 1);
    1425           1 :   tt_str_op(smartlist_get(wanted, 0), OP_EQ,
    1426             :             "3BB7D03C1C4DBC1DDE840096FF3C330914757B77");
    1427             : 
    1428             : #undef ADD
    1429             : 
    1430           1 :  done:
    1431           1 :   tor_free(mem_op_hex_tmp);
    1432           1 :   UNMOCK(router_get_dl_status_by_descriptor_digest);
    1433           7 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    1434           1 :   smartlist_free(chunks);
    1435           2 :   SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
    1436           1 :   smartlist_free(wanted);
    1437           1 :   tor_free(list);
    1438           1 : }
    1439             : 
    1440             : static int mock_get_by_ei_dd_calls = 0;
    1441             : static int mock_get_by_ei_dd_unrecognized = 0;
    1442             : 
    1443             : static signed_descriptor_t sd_ei_minimal;
    1444             : static signed_descriptor_t sd_ei_bad_nickname;
    1445             : static signed_descriptor_t sd_ei_maximal;
    1446             : static signed_descriptor_t sd_ei_bad_tokens;
    1447             : static signed_descriptor_t sd_ei_bad_sig2;
    1448             : 
    1449             : static void
    1450           3 : setup_ei_digests(void)
    1451             : {
    1452             : #define SETUP(string, name)                                             \
    1453             :   do {                                                                  \
    1454             :     router_get_extrainfo_hash(string, strlen(string),                   \
    1455             :                               (char*)digest_ei_##name);                 \
    1456             :   } while (0)
    1457             : 
    1458           3 :   SETUP(EX_EI_MINIMAL, minimal);
    1459           3 :   SETUP(EX_EI_MAXIMAL, maximal);
    1460           3 :   SETUP(EX_EI_BAD_NICKNAME, bad_nickname);
    1461           3 :   SETUP(EX_EI_BAD_TOKENS, bad_tokens);
    1462           3 :   SETUP(EX_EI_BAD_SIG2, bad_sig2);
    1463           3 :   SETUP(EX_EI_BAD_PUBLISHED, bad_published);
    1464             : 
    1465             : #undef SETUP
    1466           3 : }
    1467             : 
    1468             : static signed_descriptor_t *
    1469           2 : mock_get_by_ei_desc_digest(const char *d)
    1470             : {
    1471           2 :   ++mock_get_by_ei_dd_calls;
    1472             : #define CHECK(name)                                         \
    1473             :   do {                                                      \
    1474             :     if (fast_memeq(d, digest_ei_##name, DIGEST_LEN))        \
    1475             :       return &sd_ei_##name;                                 \
    1476             :   } while (0)
    1477             : 
    1478           2 :   CHECK(minimal);
    1479           2 :   CHECK(maximal);
    1480           2 :   CHECK(bad_nickname);
    1481           1 :   CHECK(bad_sig2);
    1482           1 :   CHECK(bad_tokens);
    1483           0 :   ++mock_get_by_ei_dd_unrecognized;
    1484           0 :   return NULL;
    1485             : #undef CHECK
    1486             : }
    1487             : 
    1488             : static signed_descriptor_t *
    1489           1 : mock_ei_get_by_ei_digest(const char *d)
    1490             : {
    1491           1 :   signed_descriptor_t *sd = &sd_ei_minimal;
    1492             : 
    1493           1 :   if (fast_memeq(d, digest_ei_minimal, DIGEST_LEN)) {
    1494           1 :     sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
    1495           1 :     sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
    1496           1 :     sd->annotations_len = 0;
    1497           1 :     sd->saved_location = SAVED_NOWHERE;
    1498           1 :     return sd;
    1499             :   }
    1500             :   return NULL;
    1501             : }
    1502             : 
    1503             : static smartlist_t *mock_ei_insert_list = NULL;
    1504             : static was_router_added_t
    1505           2 : mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
    1506             : {
    1507           2 :   (void) rl;
    1508           2 :   (void) warn_if_incompatible;
    1509           2 :   smartlist_add(mock_ei_insert_list, ei);
    1510           2 :   return ROUTER_ADDED_SUCCESSFULLY;
    1511             : }
    1512             : 
    1513             : static void
    1514           1 : test_dir_load_extrainfo(void *arg)
    1515             : {
    1516           1 :   (void) arg;
    1517           1 :   smartlist_t *chunks = smartlist_new();
    1518           1 :   smartlist_t *wanted = smartlist_new();
    1519           1 :   char buf[DIGEST_LEN];
    1520           1 :   char *mem_op_hex_tmp = NULL;
    1521           1 :   char *list = NULL;
    1522             : 
    1523             : #define ADD(str)                                                        \
    1524             :   do {                                                                  \
    1525             :     tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf));   \
    1526             :     smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN));        \
    1527             :   } while (0)
    1528             : 
    1529           1 :   setup_ei_digests();
    1530           1 :   mock_ei_insert_list = smartlist_new();
    1531           1 :   MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
    1532           1 :   MOCK(extrainfo_insert, mock_ei_insert);
    1533             : 
    1534           1 :   smartlist_add_strdup(chunks, EX_EI_MINIMAL);
    1535           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
    1536           1 :   smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
    1537           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
    1538           1 :   smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
    1539             : 
    1540             :   /* not ADDing MINIMAL */
    1541           1 :   ADD(EX_EI_MAXIMAL);
    1542           1 :   ADD(EX_EI_BAD_NICKNAME);
    1543             :   /* Not ADDing BAD_PUBLISHED */
    1544           1 :   ADD(EX_EI_BAD_TOKENS);
    1545           1 :   ADD(EX_EI_BAD_SIG2);
    1546             : 
    1547           1 :   list = smartlist_join_strings(chunks, "", 0, NULL);
    1548           1 :   router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1);
    1549             : 
    1550             :   /* The "maximal" router was added. */
    1551             :   /* "minimal" was also added, even though we didn't ask for it, since
    1552             :    * that's what we do with extrainfos. */
    1553           1 :   tt_int_op(smartlist_len(mock_ei_insert_list),OP_EQ,2);
    1554             : 
    1555           1 :   extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0);
    1556           1 :   tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
    1557           1 :             digest_ei_minimal, DIGEST_LEN);
    1558             : 
    1559           1 :   e = smartlist_get(mock_ei_insert_list, 1);
    1560           1 :   tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
    1561           1 :             digest_ei_maximal, DIGEST_LEN);
    1562           1 :   tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
    1563           1 :   tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
    1564             : 
    1565             :   /* "Bad nickname" and "Bad tokens" should have gotten marked
    1566             :    * non-retriable. */
    1567           1 :   tt_want_int_op(mock_get_by_ei_dd_calls, OP_EQ, 2);
    1568           1 :   tt_want_int_op(mock_get_by_ei_dd_unrecognized, OP_EQ, 0);
    1569           1 :   tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, OP_EQ, 255);
    1570           1 :   tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, OP_EQ, 255);
    1571             : 
    1572             :   /* bad_ports is retriable -- because we didn't ask for it. */
    1573           1 :   tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
    1574             : 
    1575             :   /* Wanted still contains "BAD_SIG2" */
    1576           1 :   tt_int_op(smartlist_len(wanted), OP_EQ, 1);
    1577           1 :   const char *got_wanted =smartlist_get(wanted, 0);
    1578           1 :   tt_int_op(strlen(got_wanted), OP_EQ, HEX_DIGEST_LEN);
    1579           1 :   char d[DIGEST_LEN];
    1580           1 :   base16_decode(d, DIGEST_LEN, got_wanted, strlen(got_wanted));
    1581           1 :   tt_mem_op(d, OP_EQ, digest_ei_bad_sig2, DIGEST_LEN);
    1582             : 
    1583             : #undef ADD
    1584             : 
    1585           1 :  done:
    1586           1 :   tor_free(mem_op_hex_tmp);
    1587           1 :   UNMOCK(router_get_by_extrainfo_digest);
    1588           6 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    1589           1 :   smartlist_free(chunks);
    1590           2 :   SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
    1591           1 :   smartlist_free(wanted);
    1592           1 :   tor_free(list);
    1593           1 : }
    1594             : 
    1595             : static void
    1596           1 : test_dir_getinfo_extra(void *arg)
    1597             : {
    1598           1 :   int r;
    1599           1 :   char *answer = NULL;
    1600           1 :   const char *errmsg = NULL;
    1601           1 :   char buf[128];
    1602           1 :   char hexdigest[HEX_DIGEST_LEN+1];
    1603           1 :   (void)arg;
    1604             : 
    1605           1 :   setup_ei_digests();
    1606           1 :   base16_encode(hexdigest, sizeof(hexdigest),
    1607             :                 (const char*)digest_ei_minimal, DIGEST_LEN);
    1608           1 :   tor_snprintf(buf, sizeof(buf), "extra-info/digest/%s", hexdigest);
    1609             : 
    1610           1 :   MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
    1611           1 :   r = getinfo_helper_dir(NULL, buf, &answer, &errmsg);
    1612           1 :   tt_int_op(0, OP_EQ, r);
    1613           1 :   tt_ptr_op(NULL, OP_EQ, errmsg);
    1614           1 :   tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
    1615           1 :   tor_free(answer);
    1616             : 
    1617           1 :   answer = NULL;
    1618           1 :   r = getinfo_helper_dir(NULL, "extra-info/digest/"
    1619             :                          "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
    1620             :                          &errmsg);
    1621           1 :   tt_int_op(0, OP_EQ, r);
    1622             :   /* getinfo_helper_dir() should maybe return an error here but doesn't */
    1623           1 :   tt_ptr_op(NULL, OP_EQ, errmsg);
    1624             :   /* In any case, there should be no answer for an invalid hex string. */
    1625           1 :   tt_ptr_op(NULL, OP_EQ, answer);
    1626             : 
    1627           1 :  done:
    1628           1 :   UNMOCK(extrainfo_get_by_descriptor_digest);
    1629           1 : }
    1630             : 
    1631             : static void
    1632           1 : test_dir_versions(void *arg)
    1633             : {
    1634           1 :   tor_version_t ver1;
    1635             : 
    1636             :   /* Try out version parsing functionality */
    1637           1 :   (void)arg;
    1638           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.3.4pre2-cvs", &ver1));
    1639           1 :   tt_int_op(0,OP_EQ, ver1.major);
    1640           1 :   tt_int_op(3,OP_EQ, ver1.minor);
    1641           1 :   tt_int_op(4,OP_EQ, ver1.micro);
    1642           1 :   tt_int_op(VER_PRE,OP_EQ, ver1.status);
    1643           1 :   tt_int_op(2,OP_EQ, ver1.patchlevel);
    1644           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.3.4rc1", &ver1));
    1645           1 :   tt_int_op(0,OP_EQ, ver1.major);
    1646           1 :   tt_int_op(3,OP_EQ, ver1.minor);
    1647           1 :   tt_int_op(4,OP_EQ, ver1.micro);
    1648           1 :   tt_int_op(VER_RC,OP_EQ, ver1.status);
    1649           1 :   tt_int_op(1,OP_EQ, ver1.patchlevel);
    1650           1 :   tt_int_op(0,OP_EQ, tor_version_parse("1.3.4", &ver1));
    1651           1 :   tt_int_op(1,OP_EQ, ver1.major);
    1652           1 :   tt_int_op(3,OP_EQ, ver1.minor);
    1653           1 :   tt_int_op(4,OP_EQ, ver1.micro);
    1654           1 :   tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
    1655           1 :   tt_int_op(0,OP_EQ, ver1.patchlevel);
    1656           1 :   tt_int_op(0,OP_EQ, tor_version_parse("1.3.4.999", &ver1));
    1657           1 :   tt_int_op(1,OP_EQ, ver1.major);
    1658           1 :   tt_int_op(3,OP_EQ, ver1.minor);
    1659           1 :   tt_int_op(4,OP_EQ, ver1.micro);
    1660           1 :   tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
    1661           1 :   tt_int_op(999,OP_EQ, ver1.patchlevel);
    1662           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4-alpha", &ver1));
    1663           1 :   tt_int_op(0,OP_EQ, ver1.major);
    1664           1 :   tt_int_op(1,OP_EQ, ver1.minor);
    1665           1 :   tt_int_op(2,OP_EQ, ver1.micro);
    1666           1 :   tt_int_op(4,OP_EQ, ver1.patchlevel);
    1667           1 :   tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
    1668           1 :   tt_str_op("alpha",OP_EQ, ver1.status_tag);
    1669           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4", &ver1));
    1670           1 :   tt_int_op(0,OP_EQ, ver1.major);
    1671           1 :   tt_int_op(1,OP_EQ, ver1.minor);
    1672           1 :   tt_int_op(2,OP_EQ, ver1.micro);
    1673           1 :   tt_int_op(4,OP_EQ, ver1.patchlevel);
    1674           1 :   tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
    1675           1 :   tt_str_op("",OP_EQ, ver1.status_tag);
    1676             : 
    1677           1 :   tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1));
    1678           1 :   tt_int_op(10, OP_EQ, ver1.major);
    1679           1 :   tt_int_op(1, OP_EQ, ver1.minor);
    1680           1 :   tt_int_op(0, OP_EQ, ver1.micro);
    1681           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1682           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1683           1 :   tt_str_op("", OP_EQ, ver1.status_tag);
    1684           1 :   tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1));
    1685           1 :   tt_int_op(5, OP_EQ, ver1.major);
    1686           1 :   tt_int_op(99, OP_EQ, ver1.minor);
    1687           1 :   tt_int_op(999, OP_EQ, ver1.micro);
    1688           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1689           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1690           1 :   tt_str_op("", OP_EQ, ver1.status_tag);
    1691           1 :   tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1));
    1692           1 :   tt_int_op(10, OP_EQ, ver1.major);
    1693           1 :   tt_int_op(1, OP_EQ, ver1.minor);
    1694           1 :   tt_int_op(0, OP_EQ, ver1.micro);
    1695           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1696           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1697           1 :   tt_str_op("alpha", OP_EQ, ver1.status_tag);
    1698             :   /* Go through the full set of status tags */
    1699           1 :   tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
    1700           1 :   tt_int_op(2, OP_EQ, ver1.major);
    1701           1 :   tt_int_op(1, OP_EQ, ver1.minor);
    1702           1 :   tt_int_op(700, OP_EQ, ver1.micro);
    1703           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1704           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1705           1 :   tt_str_op("alpha", OP_EQ, ver1.status_tag);
    1706           1 :   tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1));
    1707           1 :   tt_int_op(1, OP_EQ, ver1.major);
    1708           1 :   tt_int_op(6, OP_EQ, ver1.minor);
    1709           1 :   tt_int_op(8, OP_EQ, ver1.micro);
    1710           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1711           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1712           1 :   tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
    1713           1 :   tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
    1714           1 :   tt_int_op(0, OP_EQ, ver1.major);
    1715           1 :   tt_int_op(2, OP_EQ, ver1.minor);
    1716           1 :   tt_int_op(9, OP_EQ, ver1.micro);
    1717           1 :   tt_int_op(5, OP_EQ, ver1.patchlevel);
    1718           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1719           1 :   tt_str_op("rc", OP_EQ, ver1.status_tag);
    1720           1 :   tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
    1721           1 :   tt_int_op(0, OP_EQ, ver1.major);
    1722           1 :   tt_int_op(2, OP_EQ, ver1.minor);
    1723           1 :   tt_int_op(9, OP_EQ, ver1.micro);
    1724           1 :   tt_int_op(6, OP_EQ, ver1.patchlevel);
    1725           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1726           1 :   tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
    1727           1 :   tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
    1728           1 :   tt_int_op(0, OP_EQ, ver1.major);
    1729           1 :   tt_int_op(2, OP_EQ, ver1.minor);
    1730           1 :   tt_int_op(9, OP_EQ, ver1.micro);
    1731           1 :   tt_int_op(8, OP_EQ, ver1.patchlevel);
    1732           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1733           1 :   tt_str_op("", OP_EQ, ver1.status_tag);
    1734           1 :   tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
    1735           1 :   tt_int_op(0, OP_EQ, ver1.major);
    1736           1 :   tt_int_op(2, OP_EQ, ver1.minor);
    1737           1 :   tt_int_op(9, OP_EQ, ver1.micro);
    1738           1 :   tt_int_op(9, OP_EQ, ver1.patchlevel);
    1739           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1740           1 :   tt_str_op("dev", OP_EQ, ver1.status_tag);
    1741             :   /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
    1742             :    * between i386 and x86_64, as we used tor_parse_long, and then cast to int
    1743             :    */
    1744           1 :   tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
    1745           1 :   tt_int_op(0, OP_EQ, ver1.major);
    1746           1 :   tt_int_op(2147483647, OP_EQ, ver1.minor);
    1747           1 :   tt_int_op(0, OP_EQ, ver1.micro);
    1748           1 :   tt_int_op(0, OP_EQ, ver1.patchlevel);
    1749           1 :   tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
    1750           1 :   tt_str_op("", OP_EQ, ver1.status_tag);
    1751           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
    1752           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
    1753             :   /* In #21278, we reject negative version components */
    1754           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
    1755           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
    1756           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
    1757             :   /* In #21507, we reject version components with non-numeric prefixes */
    1758           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
    1759           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
    1760             :   /* use the list in isspace() */
    1761           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
    1762           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
    1763           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
    1764           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
    1765           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
    1766           1 :   tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
    1767             : 
    1768             : #define tt_versionstatus_op(vs1, op, vs2)                               \
    1769             :   tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t,       \
    1770             :                       (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
    1771             : #define test_v_i_o(val, ver, lst)                                       \
    1772             :   tt_versionstatus_op(val, OP_EQ, tor_version_is_obsolete(ver, lst))
    1773             : 
    1774             :   /* make sure tor_version_is_obsolete() works */
    1775           1 :   test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
    1776           1 :   test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
    1777           1 :   test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
    1778           1 :   test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
    1779           1 :   test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
    1780           1 :   test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
    1781           1 :   test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
    1782           1 :   test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
    1783           1 :   test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
    1784           1 :   test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
    1785           1 :   test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
    1786           1 :   test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
    1787             :   /* Not on list, but newer than any in same series. */
    1788           1 :   test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
    1789             :              "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
    1790             :   /* Series newer than any on list. */
    1791           1 :   test_v_i_o(VS_NEW, "0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
    1792             :   /* Series older than any on list. */
    1793           1 :   test_v_i_o(VS_OLD, "0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
    1794             :   /* Not on list, not newer than any on same series. */
    1795           1 :   test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
    1796             :              "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
    1797             :   /* On list, not newer than any on same series. */
    1798           1 :   test_v_i_o(VS_UNRECOMMENDED,
    1799             :              "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
    1800           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
    1801           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1802             :           "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
    1803             :           "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
    1804             :           "0.0.8rc2"));
    1805           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1806             :           "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
    1807             :           "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
    1808             : 
    1809             :   /* Now try svn revisions. */
    1810           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
    1811             :                                    "Tor 0.2.1.0-dev (r99)"));
    1812           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1813             :                                    "Tor 0.2.1.0-dev (r100) on Banana Jr",
    1814             :                                    "Tor 0.2.1.0-dev (r99) on Hal 9000"));
    1815           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
    1816             :                                    "Tor 0.2.1.0-dev on Colossus"));
    1817           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
    1818             :                                    "Tor 0.2.1.0-dev (r100)"));
    1819           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
    1820             :                                    "Tor 0.2.1.0-dev (r100) on AM"));
    1821           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev",
    1822             :                                    "Tor 0.2.1.0-dev (r99)"));
    1823           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
    1824             :                                    "Tor 0.2.1.0-dev (r99)"));
    1825             :   /* And git revisions */
    1826           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1827             :                                         "Tor 0.2.9.9 (git-56788a2489127072)",
    1828             :                                         "Tor 0.2.9.9 (git-56788a2489127072)"));
    1829             :   /* a git revision is newer than no git revision */
    1830           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1831             :                                         "Tor 0.2.9.9 (git-56788a2489127072)",
    1832             :                                         "Tor 0.2.9.9"));
    1833             :   /* a longer git revision is newer than a shorter git revision
    1834             :    * this should be true if they prefix-match, but if they don't, they are
    1835             :    * incomparable, because hashes aren't ordered (but we compare their bytes
    1836             :    * anyway) */
    1837           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1838             :                   "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
    1839             :                   "Tor 0.2.9.9 (git-56788a2489127072)"));
    1840           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1841             :                                         "Tor 0.2.9.9 (git-0102)",
    1842             :                                         "Tor 0.2.9.9 (git-03)"));
    1843           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1844             :                                         "Tor 0.2.9.9 (git-0102)",
    1845             :                                         "Tor 0.2.9.9 (git-00)"));
    1846           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1847             :                                            "Tor 0.2.9.9 (git-01)",
    1848             :                                            "Tor 0.2.9.9 (git-00)"));
    1849           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1850             :                                            "Tor 0.2.9.9 (git-00)",
    1851             :                                            "Tor 0.2.9.9 (git-01)"));
    1852             :   /* In #21278, we compare without integer overflows.
    1853             :    * But since #21450 limits version components to [0, INT32_MAX], it is no
    1854             :    * longer possible to cause an integer overflow in tor_version_compare() */
    1855           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1856             :                                            "Tor 0.0.0.0",
    1857             :                                            "Tor 2147483647.0.0.0"));
    1858           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1859             :                                            "Tor 2147483647.0.0.0",
    1860             :                                            "Tor 0.0.0.0"));
    1861             :   /* These versions used to cause an overflow, now they don't parse
    1862             :    * (and authorities reject their descriptors), and log a BUG message */
    1863           1 :   setup_full_capture_of_logs(LOG_WARN);
    1864           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1865             :                                            "Tor 0.0.0.0",
    1866             :                                            "Tor 0.-2147483648.0.0"));
    1867           1 :   expect_single_log_msg_containing("unparseable");
    1868           1 :   mock_clean_saved_logs();
    1869           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1870             :                                            "Tor 0.2147483647.0.0",
    1871             :                                            "Tor 0.-1.0.0"));
    1872           1 :   expect_single_log_msg_containing("unparseable");
    1873           1 :   mock_clean_saved_logs();
    1874           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1875             :                                            "Tor 0.2147483647.0.0",
    1876             :                                            "Tor 0.-2147483648.0.0"));
    1877           1 :   expect_single_log_msg_containing("unparseable");
    1878           1 :   mock_clean_saved_logs();
    1879           1 :   tt_int_op(1,OP_EQ, tor_version_as_new_as(
    1880             :                                            "Tor 4294967295.0.0.0",
    1881             :                                            "Tor 0.0.0.0"));
    1882           1 :   expect_no_log_entry();
    1883           1 :   tt_int_op(0,OP_EQ, tor_version_as_new_as(
    1884             :                                            "Tor 0.4294967295.0.0",
    1885             :                                            "Tor 0.-4294967295.0.0"));
    1886           1 :   expect_single_log_msg_containing("unparseable");
    1887           1 :   mock_clean_saved_logs();
    1888           1 :   teardown_capture_of_logs();
    1889             : 
    1890             :   /* Now try git revisions */
    1891           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
    1892           1 :   tt_int_op(0,OP_EQ, ver1.major);
    1893           1 :   tt_int_op(5,OP_EQ, ver1.minor);
    1894           1 :   tt_int_op(6,OP_EQ, ver1.micro);
    1895           1 :   tt_int_op(7,OP_EQ, ver1.patchlevel);
    1896           1 :   tt_int_op(3,OP_EQ, ver1.git_tag_len);
    1897           1 :   tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
    1898             :   /* reject bad hex digits */
    1899           1 :   tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
    1900             :   /* reject odd hex digit count */
    1901           1 :   tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
    1902             :   /* ignore "git " */
    1903           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
    1904             :   /* standard length is 16 hex digits */
    1905           1 :   tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
    1906             :                                        &ver1));
    1907             :   /* length limit is 40 hex digits */
    1908           1 :   tt_int_op(0,OP_EQ, tor_version_parse(
    1909             :                      "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
    1910             :                      &ver1));
    1911           1 :   tt_int_op(-1,OP_EQ, tor_version_parse(
    1912             :                     "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
    1913             :                     &ver1));
    1914           1 :  done:
    1915           1 :   teardown_capture_of_logs();
    1916           1 : }
    1917             : 
    1918             : /** Run unit tests for directory fp_pair functions. */
    1919             : static void
    1920           1 : test_dir_fp_pairs(void *arg)
    1921             : {
    1922           1 :   smartlist_t *sl = smartlist_new();
    1923           1 :   fp_pair_t *pair;
    1924             : 
    1925           1 :   (void)arg;
    1926           1 :   dir_split_resource_into_fingerprint_pairs(
    1927             :        /* Two pairs, out of order, with one duplicate. */
    1928             :        "73656372657420646174612E0000000000FFFFFF-"
    1929             :        "557365204145532d32353620696e73746561642e+"
    1930             :        "73656372657420646174612E0000000000FFFFFF-"
    1931             :        "557365204145532d32353620696e73746561642e+"
    1932             :        "48657861646563696d616c2069736e277420736f-"
    1933             :        "676f6f6420666f7220686964696e6720796f7572.z", sl);
    1934             : 
    1935           1 :   tt_int_op(smartlist_len(sl),OP_EQ, 2);
    1936           1 :   pair = smartlist_get(sl, 0);
    1937           1 :   tt_mem_op(pair->first,OP_EQ,  "Hexadecimal isn't so", DIGEST_LEN);
    1938           1 :   tt_mem_op(pair->second,OP_EQ, "good for hiding your", DIGEST_LEN);
    1939           1 :   pair = smartlist_get(sl, 1);
    1940           1 :   tt_mem_op(pair->first,OP_EQ,  "secret data.\0\0\0\0\0\xff\xff\xff",
    1941           1 :             DIGEST_LEN);
    1942           1 :   tt_mem_op(pair->second,OP_EQ, "Use AES-256 instead.", DIGEST_LEN);
    1943             : 
    1944           1 :  done:
    1945           3 :   SMARTLIST_FOREACH(sl, fp_pair_t *, pair_to_free, tor_free(pair_to_free));
    1946           1 :   smartlist_free(sl);
    1947           1 : }
    1948             : 
    1949             : static void
    1950           1 : test_dir_split_fps(void *testdata)
    1951             : {
    1952           1 :   smartlist_t *sl = smartlist_new();
    1953           1 :   char *mem_op_hex_tmp = NULL;
    1954           1 :   (void)testdata;
    1955             : 
    1956             :   /* Some example hex fingerprints and their base64 equivalents */
    1957             : #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
    1958             : #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
    1959             : #define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
    1960             : #define HEX256_1 \
    1961             :     "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
    1962             : #define HEX256_2 \
    1963             :     "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
    1964             : #define HEX256_3 \
    1965             :     "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
    1966             : #define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
    1967             : #define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
    1968             : #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
    1969             : #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
    1970             : 
    1971             :   /* no flags set */
    1972           1 :   dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
    1973           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
    1974           1 :   tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
    1975           1 :   tt_str_op(smartlist_get(sl, 1), OP_EQ, "C");
    1976           1 :   tt_str_op(smartlist_get(sl, 2), OP_EQ, "B");
    1977           4 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    1978           1 :   smartlist_clear(sl);
    1979             : 
    1980             :   /* uniq strings. */
    1981           1 :   dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
    1982           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
    1983           1 :   tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
    1984           1 :   tt_str_op(smartlist_get(sl, 1), OP_EQ, "B");
    1985           1 :   tt_str_op(smartlist_get(sl, 2), OP_EQ, "C");
    1986           4 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    1987           1 :   smartlist_clear(sl);
    1988             : 
    1989             :   /* Decode hex. */
    1990           1 :   dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
    1991           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 2);
    1992           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
    1993           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
    1994           3 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    1995           1 :   smartlist_clear(sl);
    1996             : 
    1997             :   /* decode hex and drop weirdness. */
    1998           1 :   dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
    1999             :                                        sl, NULL, DSR_HEX);
    2000           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 2);
    2001           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
    2002           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
    2003           3 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2004           1 :   smartlist_clear(sl);
    2005             : 
    2006             :   /* Decode long hex */
    2007           1 :   dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
    2008             :                                        sl, NULL, DSR_HEX|DSR_DIGEST256);
    2009           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
    2010           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
    2011           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
    2012           1 :   test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_3);
    2013           4 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2014           1 :   smartlist_clear(sl);
    2015             : 
    2016             :   /* Decode hex and sort. */
    2017           1 :   dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
    2018             :                                        sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
    2019           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
    2020           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX3);
    2021           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
    2022           1 :   test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX1);
    2023           4 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2024           1 :   smartlist_clear(sl);
    2025             : 
    2026             :   /* Decode long hex and sort */
    2027           1 :   dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
    2028             :                                        "+"HEX256_1,
    2029             :                                        sl, NULL,
    2030             :                                        DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
    2031           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 3);
    2032           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_3);
    2033           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
    2034           1 :   test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_1);
    2035           4 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2036           1 :   smartlist_clear(sl);
    2037             : 
    2038             :   /* Decode base64 */
    2039           1 :   dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
    2040           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 2);
    2041           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
    2042           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
    2043           3 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2044           1 :   smartlist_clear(sl);
    2045             : 
    2046             :   /* Decode long base64 */
    2047           1 :   dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
    2048             :                                        sl, NULL, DSR_BASE64|DSR_DIGEST256);
    2049           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 2);
    2050           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
    2051           1 :   test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
    2052           3 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2053           1 :   smartlist_clear(sl);
    2054             : 
    2055           1 :   dir_split_resource_into_fingerprints(B64_256_1,
    2056             :                                        sl, NULL, DSR_BASE64|DSR_DIGEST256);
    2057           1 :   tt_int_op(smartlist_len(sl), OP_EQ, 1);
    2058           1 :   test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
    2059           2 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2060           1 :   smartlist_clear(sl);
    2061             : 
    2062           1 :  done:
    2063           1 :   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    2064           1 :   smartlist_free(sl);
    2065           1 :   tor_free(mem_op_hex_tmp);
    2066           1 : }
    2067             : 
    2068             : static void
    2069           1 : test_dir_measured_bw_kb(void *arg)
    2070             : {
    2071           1 :   measured_bw_line_t mbwl;
    2072           1 :   int i;
    2073           1 :   const char *lines_pass[] = {
    2074             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
    2075             :     "node_id=$557365204145532d32353620696e73746561642e\t  bw=1024 \n",
    2076             :     " node_id=$557365204145532d32353620696e73746561642e  bw=1024\n",
    2077             :     "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e  "
    2078             :                 "bw=1024 junk=007\n",
    2079             :     "misc=junk node_id=$557365204145532d32353620696e73746561642e  "
    2080             :                 "bw=1024 junk=007\n",
    2081             :     /* check whether node_id can be at the end */
    2082             :     "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
    2083             :     /* check whether node_id can be at the end and bw has something in front*/
    2084             :     "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
    2085             :     /* check whether node_id can be at the end and something in the
    2086             :      * in the middle of bw and node_id */
    2087             :     "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
    2088             : 
    2089             :     /* Test that a line with vote=1 will pass. */
    2090             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1\n",
    2091             :     /* Test that a line with unmeasured=1 will pass. */
    2092             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=1\n",
    2093             :     /* Test that a line with vote=1 and unmeasured=1 will pass. */
    2094             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
    2095             :     "unmeasured=1\n",
    2096             :     /* Test that a line with unmeasured=0 will pass. */
    2097             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=0\n",
    2098             :     /* Test that a line with vote=1 and unmeasured=0 will pass. */
    2099             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
    2100             :     "unmeasured=0\n",
    2101             :     "end"
    2102             :   };
    2103           1 :   const char *lines_fail[] = {
    2104             :     /* Test possible python stupidity on input */
    2105             :     "node_id=None bw=1024\n",
    2106             :     "node_id=$None bw=1024\n",
    2107             :     "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
    2108             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
    2109             :     "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
    2110             :     "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
    2111             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
    2112             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
    2113             :     "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
    2114             :     /* Test incomplete writes due to race conditions, partial copies, etc */
    2115             :     "node_i",
    2116             :     "node_i\n",
    2117             :     "node_id=",
    2118             :     "node_id=\n",
    2119             :     "node_id=$557365204145532d32353620696e73746561642e bw=",
    2120             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024",
    2121             :     "node_id=$557365204145532d32353620696e73746561642e bw=\n",
    2122             :     "node_id=$557365204145532d32353620696e7374",
    2123             :     "node_id=$557365204145532d32353620696e7374\n",
    2124             :     "",
    2125             :     "\n",
    2126             :     " \n ",
    2127             :     " \n\n",
    2128             :     /* Test assorted noise */
    2129             :     " node_id= ",
    2130             :     "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
    2131             :     "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
    2132             :     "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
    2133             :     "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
    2134             : 
    2135             :     /* Test that a line with vote=0 will fail too, so that it is ignored. */
    2136             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0\n",
    2137             :     /* Test that a line with vote=0 will fail even if unmeasured=0. */
    2138             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0 "
    2139             :     "unmeasured=0\n",
    2140             :     "end"
    2141             :   };
    2142             : 
    2143           1 :   (void)arg;
    2144          30 :   for (i = 0; strcmp(lines_fail[i], "end"); i++) {
    2145             :     //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
    2146             :     /* Testing only with line_is_after_headers = 1. Tests with
    2147             :      * line_is_after_headers = 0 in
    2148             :      * test_dir_measured_bw_kb_line_is_after_headers */
    2149          29 :     tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
    2150             :   }
    2151             : 
    2152          14 :   for (i = 0; strcmp(lines_pass[i], "end"); i++) {
    2153             :     //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
    2154             :     /* Testing only with line_is_after_headers = 1. Tests with
    2155             :      * line_is_after_headers = 0 in
    2156             :      * test_dir_measured_bw_kb_line_is_after_headers */
    2157          13 :     tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0);
    2158          13 :     tt_assert(mbwl.bw_kb == 1024);
    2159          13 :     tt_assert(strcmp(mbwl.node_hex,
    2160             :                 "557365204145532d32353620696e73746561642e") == 0);
    2161             :   }
    2162             : 
    2163           1 :  done:
    2164           1 :   return;
    2165             : }
    2166             : 
    2167             : /* Unit tests for measured_bw_line_parse using line_is_after_headers flag.
    2168             :  * When the end of the header is detected (a first complete bw line is parsed),
    2169             :  * incomplete lines fail and give warnings, but do not give warnings if
    2170             :  * the header is not ended, allowing to ignore additional header lines. */
    2171             : static void
    2172           1 : test_dir_measured_bw_kb_line_is_after_headers(void *arg)
    2173             : {
    2174           1 :   (void)arg;
    2175           1 :   measured_bw_line_t mbwl;
    2176           1 :   const char *line_pass = \
    2177             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024\n";
    2178           1 :   int i;
    2179           1 :   const char *lines_fail[] = {
    2180             :     "node_id=$557365204145532d32353620696e73746561642e \n",
    2181             :     "bw=1024\n",
    2182             :     "rtt=300\n",
    2183             :     "end"
    2184             :   };
    2185             : 
    2186           1 :   setup_capture_of_logs(LOG_DEBUG);
    2187             : 
    2188             :   /* Test bw lines when header has ended */
    2189           5 :   for (i = 0; strcmp(lines_fail[i], "end"); i++) {
    2190           3 :     tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
    2191           3 :     expect_log_msg_containing("Incomplete line in bandwidth file:");
    2192           3 :     mock_clean_saved_logs();
    2193             :   }
    2194             : 
    2195           1 :   tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0);
    2196             : 
    2197             :   /* Test bw lines when header has not ended */
    2198           4 :   for (i = 0; strcmp(lines_fail[i], "end"); i++) {
    2199           3 :     tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1);
    2200           3 :     expect_log_msg_containing("Missing bw or node_id in bandwidth file line:");
    2201           3 :     mock_clean_saved_logs();
    2202             :   }
    2203             : 
    2204           1 :   tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0);
    2205             : 
    2206           1 :  done:
    2207           1 :   teardown_capture_of_logs();
    2208           1 : }
    2209             : 
    2210             : /* Test dirserv_read_measured_bandwidths with headers and complete files. */
    2211             : static void
    2212           1 : test_dir_dirserv_read_measured_bandwidths(void *arg)
    2213             : {
    2214           1 :   (void)arg;
    2215           1 :   char *content = NULL;
    2216           1 :   time_t timestamp = time(NULL);
    2217           1 :   char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
    2218           1 :   smartlist_t *bw_file_headers = smartlist_new();
    2219             :   /* bw file strings in vote */
    2220           1 :   char *bw_file_headers_str = NULL;
    2221           1 :   char *bw_file_headers_str_v100 = NULL;
    2222           1 :   char *bw_file_headers_str_v110 = NULL;
    2223           1 :   char *bw_file_headers_str_bad = NULL;
    2224           1 :   char *bw_file_headers_str_extra = NULL;
    2225           1 :   char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
    2226             :   /* string header lines in bw file */
    2227           1 :   char *header_lines_v100 = NULL;
    2228           1 :   char *header_lines_v110_no_terminator = NULL;
    2229           1 :   char *header_lines_v110 = NULL;
    2230           1 :   char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
    2231           1 :   int i;
    2232           1 :   const char *header_lines_v110_no_terminator_no_timestamp =
    2233             :     "version=1.1.0\n"
    2234             :     "software=sbws\n"
    2235             :     "software_version=0.1.0\n"
    2236             :     "earliest_bandwidth=2018-05-08T16:13:26\n"
    2237             :     "file_created=2018-04-16T21:49:18\n"
    2238             :     "generator_started=2018-05-08T16:13:25\n"
    2239             :     "latest_bandwidth=2018-04-16T20:49:18\n";
    2240           1 :   const char *bw_file_headers_str_v110_no_timestamp =
    2241             :     "version=1.1.0 software=sbws "
    2242             :     "software_version=0.1.0 "
    2243             :     "earliest_bandwidth=2018-05-08T16:13:26 "
    2244             :     "file_created=2018-04-16T21:49:18 "
    2245             :     "generator_started=2018-05-08T16:13:25 "
    2246             :     "latest_bandwidth=2018-04-16T20:49:18";
    2247           1 :   const char *relay_lines_v100 =
    2248             :     "node_id=$557365204145532d32353620696e73746561642e bw=1024 "
    2249             :     "nick=Test measured_at=1523911725 updated_at=1523911725 "
    2250             :     "pid_error=4.11374090719 pid_error_sum=4.11374090719 "
    2251             :     "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 "
    2252             :     "scanner=/filepath\n";
    2253           1 :   const char *relay_lines_v110 =
    2254             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
    2255             :     "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
    2256             :     "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n";
    2257           1 :   const char *relay_lines_bad =
    2258             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n";
    2259             : 
    2260           1 :   tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp);
    2261           1 :   tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp,
    2262             :                header_lines_v110_no_terminator_no_timestamp);
    2263           1 :   tor_asprintf(&header_lines_v110, "%s%s",
    2264             :                header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR);
    2265             : 
    2266           1 :   tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp);
    2267           1 :   tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s",
    2268             :                (long)timestamp, bw_file_headers_str_v110_no_timestamp);
    2269           1 :   tor_asprintf(&bw_file_headers_str_bad, "%s "
    2270             :                "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A",
    2271             :                bw_file_headers_str_v110);
    2272             : 
    2273          52 :   for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) {
    2274          50 :     strlcat(header_lines_long, "foo=bar\n",
    2275             :             sizeof(header_lines_long));
    2276             :   }
    2277             :   /* 8 is the number of v110 lines in header_lines_v110 */
    2278          42 :   for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) {
    2279          41 :     strlcat(bw_file_headers_str_long, "foo=bar ",
    2280             :             sizeof(bw_file_headers_str_long));
    2281             :   }
    2282           1 :   strlcat(bw_file_headers_str_long, "foo=bar",
    2283             :           sizeof(bw_file_headers_str_long));
    2284           1 :   tor_asprintf(&bw_file_headers_str_extra,
    2285             :                "%s %s",
    2286             :                bw_file_headers_str_v110,
    2287             :                bw_file_headers_str_long);
    2288             : 
    2289             :   /* Test an empty bandwidth file. bw_file_headers will be empty string */
    2290           1 :   write_str_to_file(fname, "", 0);
    2291           1 :   setup_capture_of_logs(LOG_WARN);
    2292           1 :   tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2293             :                                                         bw_file_headers,
    2294             :                                                         NULL));
    2295           1 :   expect_log_msg("Empty bandwidth file\n");
    2296           1 :   teardown_capture_of_logs();
    2297           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2298           1 :   tt_str_op("", OP_EQ, bw_file_headers_str);
    2299           1 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2300           1 :   smartlist_free(bw_file_headers);
    2301           1 :   tor_free(bw_file_headers_str);
    2302             : 
    2303             :   /* Test bandwidth file with only timestamp.
    2304             :    * bw_file_headers will be empty string */
    2305           1 :   bw_file_headers = smartlist_new();
    2306           1 :   tor_asprintf(&content, "%ld", (long)timestamp);
    2307           1 :   write_str_to_file(fname, content, 0);
    2308           1 :   tor_free(content);
    2309           1 :   tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2310             :                                                         bw_file_headers,
    2311             :                                                         NULL));
    2312             : 
    2313           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2314           1 :   tt_str_op("", OP_EQ, bw_file_headers_str);
    2315           1 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2316           1 :   smartlist_free(bw_file_headers);
    2317           1 :   tor_free(bw_file_headers_str);
    2318             : 
    2319             :   /* Test v1.0.0 bandwidth file headers */
    2320           1 :   write_str_to_file(fname, header_lines_v100, 0);
    2321           1 :   bw_file_headers = smartlist_new();
    2322           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2323             :                                                        bw_file_headers,
    2324             :                                                        NULL));
    2325             : 
    2326           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2327           1 :   tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
    2328           2 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2329           1 :   smartlist_free(bw_file_headers);
    2330           1 :   tor_free(bw_file_headers_str);
    2331             : 
    2332             :   /* Test v1.0.0 complete bandwidth file */
    2333           1 :   bw_file_headers = smartlist_new();
    2334           1 :   tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
    2335           1 :   write_str_to_file(fname, content, 0);
    2336           1 :   tor_free(content);
    2337           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2338             :                                                        bw_file_headers,
    2339             :                                                        NULL));
    2340             : 
    2341           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2342           1 :   tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
    2343           2 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2344           1 :   smartlist_free(bw_file_headers);
    2345           1 :   tor_free(bw_file_headers_str);
    2346             : 
    2347             :   /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */
    2348           1 :   tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
    2349           1 :   write_str_to_file(fname, content, 0);
    2350           1 :   tor_free(content);
    2351           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
    2352             :                                                        NULL));
    2353             : 
    2354             :   /* Test bandwidth file including v1.1.0 bandwidth headers and
    2355             :    * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */
    2356           1 :   bw_file_headers = smartlist_new();
    2357           1 :   tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110,
    2358             :                relay_lines_v100);
    2359           1 :   write_str_to_file(fname, content, 0);
    2360           1 :   tor_free(content);
    2361           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2362             :                                                        bw_file_headers,
    2363             :                                                        NULL));
    2364             : 
    2365           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2366           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2367           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2368           1 :   smartlist_free(bw_file_headers);
    2369           1 :   tor_free(bw_file_headers_str);
    2370             : 
    2371             :   /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end.
    2372             :    * bw_file_headers will contain only v1.0.0 headers and the additional
    2373             :    * headers will be interpreted as malformed relay lines. */
    2374           1 :   bw_file_headers = smartlist_new();
    2375           1 :   tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100,
    2376             :                header_lines_v110);
    2377           1 :   write_str_to_file(fname, content, 0);
    2378           1 :   tor_free(content);
    2379           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2380             :                                                        bw_file_headers,
    2381             :                                                        NULL));
    2382             : 
    2383           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2384           1 :   tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
    2385           2 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2386           1 :   smartlist_free(bw_file_headers);
    2387           1 :   tor_free(bw_file_headers_str);
    2388             : 
    2389             :   /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay
    2390             :    * lines. bw_file_headers will contain only v1.0.0 headers, the additional
    2391             :    * headers will be interpreted as malformed relay lines and the last relay
    2392             :    * lines will be correctly interpreted as relay lines. */
    2393           1 :   bw_file_headers = smartlist_new();
    2394           1 :   tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100,
    2395             :                header_lines_v110, relay_lines_v100);
    2396           1 :   write_str_to_file(fname, content, 0);
    2397           1 :   tor_free(content);
    2398           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2399             :                                                        bw_file_headers,
    2400             :                                                        NULL));
    2401             : 
    2402           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2403           1 :   tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
    2404           2 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2405           1 :   smartlist_free(bw_file_headers);
    2406           1 :   tor_free(bw_file_headers_str);
    2407             : 
    2408             :   /* Test v1.1.0 bandwidth headers without terminator */
    2409           1 :   bw_file_headers = smartlist_new();
    2410           1 :   write_str_to_file(fname, header_lines_v110_no_terminator, 0);
    2411           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2412             :                                                        bw_file_headers,
    2413             :                                                        NULL));
    2414             : 
    2415           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2416           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2417           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2418           1 :   smartlist_free(bw_file_headers);
    2419           1 :   tor_free(bw_file_headers_str);
    2420             : 
    2421             :   /* Test v1.1.0 bandwidth headers with terminator */
    2422           1 :   bw_file_headers = smartlist_new();
    2423           1 :   write_str_to_file(fname, header_lines_v110, 0);
    2424           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2425             :                                                        bw_file_headers,
    2426             :                                                        NULL));
    2427             : 
    2428           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2429           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2430           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2431           1 :   smartlist_free(bw_file_headers);
    2432           1 :   tor_free(bw_file_headers_str);
    2433             : 
    2434             :   /* Test v1.1.0 bandwidth file without terminator, then relay lines.
    2435             :    * bw_file_headers will contain the v1.1.0 headers. */
    2436           1 :   bw_file_headers = smartlist_new();
    2437           1 :   tor_asprintf(&content, "%s%s",
    2438             :                header_lines_v110_no_terminator, relay_lines_v110);
    2439           1 :   write_str_to_file(fname, content, 0);
    2440           1 :   tor_free(content);
    2441           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2442             :                                                        bw_file_headers,
    2443             :                                                        NULL));
    2444             : 
    2445           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2446           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2447           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2448           1 :   smartlist_free(bw_file_headers);
    2449           1 :   tor_free(bw_file_headers_str);
    2450             : 
    2451             :   /* Test v1.1.0 bandwidth headers with terminator, then relay lines
    2452             :    * bw_file_headers will contain the v1.1.0 headers. */
    2453           1 :   bw_file_headers = smartlist_new();
    2454           1 :   tor_asprintf(&content, "%s%s",
    2455             :                header_lines_v110, relay_lines_v110);
    2456           1 :   write_str_to_file(fname, content, 0);
    2457           1 :   tor_free(content);
    2458           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2459             :                                                        bw_file_headers,
    2460             :                                                        NULL));
    2461             : 
    2462           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2463           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2464           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2465           1 :   smartlist_free(bw_file_headers);
    2466           1 :   tor_free(bw_file_headers_str);
    2467             : 
    2468             :   /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines,
    2469             :    * then terminator, then relay_lines_bad.
    2470             :    * bw_file_headers will contain the v1.1.0 headers. */
    2471           1 :   bw_file_headers = smartlist_new();
    2472           1 :   tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad,
    2473             :                BW_FILE_HEADERS_TERMINATOR, relay_lines_bad);
    2474           1 :   write_str_to_file(fname, content, 0);
    2475           1 :   tor_free(content);
    2476           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2477             :                                                        bw_file_headers,
    2478             :                                                        NULL));
    2479             : 
    2480           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2481           1 :   tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
    2482           9 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2483           1 :   smartlist_free(bw_file_headers);
    2484           1 :   tor_free(bw_file_headers_str);
    2485             : 
    2486             :   /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines,
    2487             :    * then relay lines. bw_file_headers will contain the v1.1.0 headers and
    2488             :    * the bad relay lines. */
    2489           1 :   bw_file_headers = smartlist_new();
    2490           1 :   tor_asprintf(&content, "%s%s%s",
    2491             :                header_lines_v110_no_terminator, relay_lines_bad,
    2492             :                relay_lines_v110);
    2493           1 :   write_str_to_file(fname, content, 0);
    2494           1 :   tor_free(content);
    2495           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2496             :                                                        bw_file_headers,
    2497             :                                                        NULL));
    2498             : 
    2499           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2500           1 :   tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str);
    2501          10 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2502           1 :   smartlist_free(bw_file_headers);
    2503           1 :   tor_free(bw_file_headers_str);
    2504             : 
    2505             :   /* Test v1.1.0 bandwidth headers without terminator,
    2506             :    * then many bad relay lines, then relay lines.
    2507             :    * bw_file_headers will contain the v1.1.0 headers and the bad relay lines
    2508             :    * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */
    2509           1 :   bw_file_headers = smartlist_new();
    2510           1 :   tor_asprintf(&content, "%s%s%s",
    2511             :                header_lines_v110_no_terminator, header_lines_long,
    2512             :                relay_lines_v110);
    2513           1 :   write_str_to_file(fname, content, 0);
    2514           1 :   tor_free(content);
    2515           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2516             :                                                        bw_file_headers,
    2517             :                                                        NULL));
    2518             : 
    2519           1 :   tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
    2520             :             smartlist_len(bw_file_headers));
    2521           1 :   bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
    2522           1 :   tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str);
    2523          51 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2524           1 :   smartlist_free(bw_file_headers);
    2525           1 :   tor_free(bw_file_headers_str);
    2526             : 
    2527             :   /* Test v1.1.0 bandwidth headers without terminator,
    2528             :    * then many bad relay lines, then relay lines.
    2529             :    * bw_file_headers will contain the v1.1.0 headers and the bad relay lines.
    2530             :    * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE
    2531             :    * This test is needed while there is not dirvote test. */
    2532           1 :   bw_file_headers = smartlist_new();
    2533           1 :   tor_asprintf(&content, "%s%s%s",
    2534             :                header_lines_v110_no_terminator, header_lines_long,
    2535             :                relay_lines_v110);
    2536           1 :   write_str_to_file(fname, content, 0);
    2537           1 :   tor_free(content);
    2538           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
    2539             :                                                        bw_file_headers,
    2540             :                                                        NULL));
    2541             : 
    2542           1 :   tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
    2543             :             smartlist_len(bw_file_headers));
    2544             :   /* force bw_file_headers to be bigger than
    2545             :    * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */
    2546           1 :   char line[8] = "foo=bar\0";
    2547           1 :   smartlist_add_strdup(bw_file_headers, line);
    2548           1 :   tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT,
    2549             :             smartlist_len(bw_file_headers));
    2550          52 :   SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
    2551           1 :   smartlist_free(bw_file_headers);
    2552           1 :   tor_free(bw_file_headers_str);
    2553             : 
    2554             :   /* Test v1.x.x bandwidth line with vote=0.
    2555             :    * It will be ignored it and logged it at debug level. */
    2556           1 :   const char *relay_lines_ignore =
    2557             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0\n"
    2558             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
    2559             :     "unmeasured=1\n"
    2560             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
    2561             :     "unmeasured=0\n";
    2562             : 
    2563             :   /* Create the bandwidth file */
    2564           1 :   tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_ignore);
    2565           1 :   write_str_to_file(fname, content, 0);
    2566           1 :   tor_free(content);
    2567             : 
    2568             :   /* Read the bandwidth file */
    2569           1 :   setup_full_capture_of_logs(LOG_DEBUG);
    2570           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
    2571             :                                                        NULL));
    2572           1 :   expect_log_msg_containing("Ignoring bandwidth file line");
    2573           1 :   teardown_capture_of_logs();
    2574             : 
    2575             :   /* Test v1.x.x bandwidth line with "vote=1" or "unmeasured=1" or
    2576             :    * "unmeasured=0".
    2577             :    * They will not be ignored. */
    2578             :   /* Create the bandwidth file */
    2579           1 :   const char *relay_lines_vote =
    2580             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=1\n"
    2581             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=0\n"
    2582             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=1\n";
    2583           1 :   tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_vote);
    2584           1 :   write_str_to_file(fname, content, 0);
    2585           1 :   tor_free(content);
    2586             : 
    2587             :   /* Read the bandwidth file */
    2588           1 :   setup_full_capture_of_logs(LOG_DEBUG);
    2589           1 :   tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
    2590             :                                                        NULL));
    2591           1 :   expect_log_msg_not_containing("Ignoring bandwidth file line");
    2592           1 :   teardown_capture_of_logs();
    2593             : 
    2594           1 :  done:
    2595           1 :   unlink(fname);
    2596           1 :   tor_free(fname);
    2597           1 :   tor_free(header_lines_v100);
    2598           1 :   tor_free(header_lines_v110_no_terminator);
    2599           1 :   tor_free(header_lines_v110);
    2600           1 :   tor_free(bw_file_headers_str_v100);
    2601           1 :   tor_free(bw_file_headers_str_v110);
    2602           1 :   tor_free(bw_file_headers_str_bad);
    2603           1 :   tor_free(bw_file_headers_str_extra);
    2604           1 : }
    2605             : 
    2606             : #define MBWC_INIT_TIME 1000
    2607             : 
    2608             : /** Do the measured bandwidth cache unit test */
    2609             : static void
    2610           1 : test_dir_measured_bw_kb_cache(void *arg)
    2611             : {
    2612             :   /* Initial fake time_t for testing */
    2613           1 :   time_t curr = MBWC_INIT_TIME;
    2614             :   /* Some measured_bw_line_ts */
    2615           1 :   measured_bw_line_t mbwl[3];
    2616             :   /* For receiving output on cache queries */
    2617           1 :   long bw;
    2618           1 :   time_t as_of;
    2619             : 
    2620             :   /* First, clear the cache and assert that it's empty */
    2621           1 :   (void)arg;
    2622           1 :   dirserv_clear_measured_bw_cache();
    2623           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
    2624             :   /*
    2625             :    * Set up test mbwls; none of the dirserv_cache_*() functions care about
    2626             :    * the node_hex field.
    2627             :    */
    2628           1 :   memset(mbwl[0].node_id, 0x01, DIGEST_LEN);
    2629           1 :   mbwl[0].bw_kb = 20;
    2630           1 :   memset(mbwl[1].node_id, 0x02, DIGEST_LEN);
    2631           1 :   mbwl[1].bw_kb = 40;
    2632           1 :   memset(mbwl[2].node_id, 0x03, DIGEST_LEN);
    2633           1 :   mbwl[2].bw_kb = 80;
    2634             :   /* Try caching something */
    2635           1 :   dirserv_cache_measured_bw(&(mbwl[0]), curr);
    2636           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
    2637             :   /* Okay, let's see if we can retrieve it */
    2638           1 :   tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
    2639           1 :   tt_int_op(bw,OP_EQ, 20);
    2640           1 :   tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
    2641             :   /* Try retrieving it without some outputs */
    2642           1 :   tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
    2643           1 :   tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
    2644           1 :   tt_int_op(bw,OP_EQ, 20);
    2645           1 :   tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
    2646           1 :   tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
    2647             :   /* Now expire it */
    2648           1 :   curr += MAX_MEASUREMENT_AGE + 1;
    2649           1 :   dirserv_expire_measured_bw_cache(curr);
    2650             :   /* Check that the cache is empty */
    2651           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
    2652             :   /* Check that we can't retrieve it */
    2653           1 :   tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
    2654             :   /* Try caching a few things now */
    2655           1 :   dirserv_cache_measured_bw(&(mbwl[0]), curr);
    2656           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
    2657           1 :   curr += MAX_MEASUREMENT_AGE / 4;
    2658           1 :   dirserv_cache_measured_bw(&(mbwl[1]), curr);
    2659           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
    2660           1 :   curr += MAX_MEASUREMENT_AGE / 4;
    2661           1 :   dirserv_cache_measured_bw(&(mbwl[2]), curr);
    2662           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
    2663           1 :   curr += MAX_MEASUREMENT_AGE / 4 + 1;
    2664             :   /* Do an expire that's too soon to get any of them */
    2665           1 :   dirserv_expire_measured_bw_cache(curr);
    2666           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
    2667             :   /* Push the oldest one off the cliff */
    2668           1 :   curr += MAX_MEASUREMENT_AGE / 4;
    2669           1 :   dirserv_expire_measured_bw_cache(curr);
    2670           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
    2671             :   /* And another... */
    2672           1 :   curr += MAX_MEASUREMENT_AGE / 4;
    2673           1 :   dirserv_expire_measured_bw_cache(curr);
    2674           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
    2675             :   /* This should empty it out again */
    2676           1 :   curr += MAX_MEASUREMENT_AGE / 4;
    2677           1 :   dirserv_expire_measured_bw_cache(curr);
    2678           1 :   tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
    2679             : 
    2680           1 :  done:
    2681           1 :   return;
    2682             : }
    2683             : 
    2684             : static char *
    2685          12 : my_dirvote_compute_params(smartlist_t *votes, int method,
    2686             :                           int total_authorities)
    2687             : {
    2688          12 :   smartlist_t *s = dirvote_compute_params(votes, method, total_authorities);
    2689          12 :   tor_assert(s);
    2690          12 :   char *res = smartlist_join_strings(s, " ", 0, NULL);
    2691          46 :   SMARTLIST_FOREACH(s, char *, cp, tor_free(cp));
    2692          12 :   smartlist_free(s);
    2693          12 :   return res;
    2694             : }
    2695             : 
    2696             : #define dirvote_compute_params my_dirvote_compute_params
    2697             : 
    2698             : static void
    2699           1 : test_dir_param_voting(void *arg)
    2700             : {
    2701           1 :   networkstatus_t vote1, vote2, vote3, vote4;
    2702           1 :   smartlist_t *votes = smartlist_new();
    2703           1 :   char *res = NULL;
    2704             : 
    2705             :   /* dirvote_compute_params only looks at the net_params field of the votes,
    2706             :      so that's all we need to set.
    2707             :    */
    2708           1 :   (void)arg;
    2709           1 :   memset(&vote1, 0, sizeof(vote1));
    2710           1 :   memset(&vote2, 0, sizeof(vote2));
    2711           1 :   memset(&vote3, 0, sizeof(vote3));
    2712           1 :   memset(&vote4, 0, sizeof(vote4));
    2713           1 :   vote1.net_params = smartlist_new();
    2714           1 :   vote2.net_params = smartlist_new();
    2715           1 :   vote3.net_params = smartlist_new();
    2716           1 :   vote4.net_params = smartlist_new();
    2717           1 :   smartlist_split_string(vote1.net_params,
    2718             :                          "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
    2719           1 :   smartlist_split_string(vote2.net_params,
    2720             :                          "ab=27 cw=5 x-yz=88", NULL, 0, 0);
    2721           1 :   smartlist_split_string(vote3.net_params,
    2722             :                          "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
    2723           1 :   smartlist_split_string(vote4.net_params,
    2724             :                          "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
    2725           1 :   tt_int_op(100,OP_EQ, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
    2726           1 :   tt_int_op(222,OP_EQ, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
    2727           1 :   tt_int_op(80,OP_EQ, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
    2728           1 :   tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
    2729           1 :   tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
    2730             : 
    2731           1 :   tt_int_op(100,OP_EQ, networkstatus_get_overridable_param(
    2732             :                                         &vote4, -1, "x-yz", 50, 0, 300));
    2733           1 :   tt_int_op(30,OP_EQ, networkstatus_get_overridable_param(
    2734             :                                         &vote4, 30, "x-yz", 50, 0, 300));
    2735           1 :   tt_int_op(0,OP_EQ, networkstatus_get_overridable_param(
    2736             :                                         &vote4, -101, "foobar", 0, -100, 8));
    2737           1 :   tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param(
    2738             :                                         &vote4, -99, "foobar", 0, -100, 8));
    2739             : 
    2740           1 :   smartlist_add(votes, &vote1);
    2741             : 
    2742             :   /* Do the first tests without adding all the other votes, for
    2743             :    * networks without many dirauths. */
    2744             : 
    2745           1 :   res = dirvote_compute_params(votes, 12, 2);
    2746           1 :   tt_str_op(res,OP_EQ, "");
    2747           1 :   tor_free(res);
    2748             : 
    2749           1 :   res = dirvote_compute_params(votes, 12, 1);
    2750           1 :   tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-99");
    2751           1 :   tor_free(res);
    2752             : 
    2753           1 :   smartlist_add(votes, &vote2);
    2754             : 
    2755           1 :   res = dirvote_compute_params(votes, 12, 2);
    2756           1 :   tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
    2757           1 :   tor_free(res);
    2758             : 
    2759           1 :   res = dirvote_compute_params(votes, 12, 3);
    2760           1 :   tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
    2761           1 :   tor_free(res);
    2762             : 
    2763           1 :   res = dirvote_compute_params(votes, 12, 6);
    2764           1 :   tt_str_op(res,OP_EQ, "");
    2765           1 :   tor_free(res);
    2766             : 
    2767           1 :   smartlist_add(votes, &vote3);
    2768             : 
    2769           1 :   res = dirvote_compute_params(votes, 12, 3);
    2770           1 :   tt_str_op(res,OP_EQ, "ab=27 abcd=20 cw=50 x-yz=-9");
    2771           1 :   tor_free(res);
    2772             : 
    2773           1 :   res = dirvote_compute_params(votes, 12, 5);
    2774           1 :   tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
    2775           1 :   tor_free(res);
    2776             : 
    2777           1 :   res = dirvote_compute_params(votes, 12, 9);
    2778           1 :   tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
    2779           1 :   tor_free(res);
    2780             : 
    2781           1 :   smartlist_add(votes, &vote4);
    2782             : 
    2783           1 :   res = dirvote_compute_params(votes, 12, 4);
    2784           1 :   tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
    2785           1 :   tor_free(res);
    2786             : 
    2787           1 :   res = dirvote_compute_params(votes, 12, 5);
    2788           1 :   tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
    2789           1 :   tor_free(res);
    2790             : 
    2791             :   /* Test that the special-cased "at least three dirauths voted for
    2792             :    * this param" logic works as expected. */
    2793           1 :   res = dirvote_compute_params(votes, 12, 6);
    2794           1 :   tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
    2795           1 :   tor_free(res);
    2796             : 
    2797           1 :   res = dirvote_compute_params(votes, 12, 10);
    2798           1 :   tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
    2799           1 :   tor_free(res);
    2800             : 
    2801           1 :  done:
    2802           1 :   tor_free(res);
    2803           5 :   SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
    2804           4 :   SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
    2805           6 :   SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
    2806           6 :   SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
    2807           1 :   smartlist_free(vote1.net_params);
    2808           1 :   smartlist_free(vote2.net_params);
    2809           1 :   smartlist_free(vote3.net_params);
    2810           1 :   smartlist_free(vote4.net_params);
    2811           1 :   smartlist_free(votes);
    2812             : 
    2813           1 :   return;
    2814             : }
    2815             : 
    2816             : static void
    2817           1 : test_dir_param_voting_lookup(void *arg)
    2818             : {
    2819           1 :   (void)arg;
    2820           1 :   smartlist_t *lst = smartlist_new();
    2821             : 
    2822           1 :   smartlist_split_string(lst,
    2823             :                          "moomin=9 moomin=10 moomintroll=5 fred "
    2824             :                          "jack= electricity=sdk opa=6z abc=9 abcd=99",
    2825             :                          NULL, 0, 0);
    2826             : 
    2827           1 :   tt_int_op(1000,
    2828             :             OP_EQ, dirvote_get_intermediate_param_value(lst, "ab", 1000));
    2829           1 :   tt_int_op(9, OP_EQ, dirvote_get_intermediate_param_value(lst, "abc", 1000));
    2830           1 :   tt_int_op(99, OP_EQ,
    2831             :             dirvote_get_intermediate_param_value(lst, "abcd", 1000));
    2832             : 
    2833             : #ifndef ALL_BUGS_ARE_FATAL
    2834             :   /* moomin appears twice. That's a bug. */
    2835           1 :   tor_capture_bugs_(1);
    2836           1 :   tt_int_op(-100, OP_EQ,
    2837             :             dirvote_get_intermediate_param_value(lst, "moomin", -100));
    2838           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    2839           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    2840             :             "n_found == 0");
    2841           1 :   tor_end_capture_bugs_();
    2842             :   /* There is no 'fred=', so that is treated as not existing. */
    2843           1 :   tt_int_op(-100, OP_EQ,
    2844             :             dirvote_get_intermediate_param_value(lst, "fred", -100));
    2845             :   /* jack is truncated */
    2846           1 :   tor_capture_bugs_(1);
    2847           1 :   tt_int_op(-100, OP_EQ,
    2848             :             dirvote_get_intermediate_param_value(lst, "jack", -100));
    2849           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    2850           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    2851             :             "!(!ok)");
    2852           1 :   tor_end_capture_bugs_();
    2853             :   /* electricity and opa aren't integers. */
    2854           1 :   tor_capture_bugs_(1);
    2855           1 :   tt_int_op(-100, OP_EQ,
    2856             :             dirvote_get_intermediate_param_value(lst, "electricity", -100));
    2857           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    2858           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    2859             :             "!(!ok)");
    2860           1 :   tor_end_capture_bugs_();
    2861             : 
    2862           1 :   tor_capture_bugs_(1);
    2863           1 :   tt_int_op(-100, OP_EQ,
    2864             :             dirvote_get_intermediate_param_value(lst, "opa", -100));
    2865           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    2866           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    2867             :             "!(!ok)");
    2868           1 :   tor_end_capture_bugs_();
    2869             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    2870             : 
    2871           1 :  done:
    2872          10 :   SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
    2873           1 :   smartlist_free(lst);
    2874           1 :   tor_end_capture_bugs_();
    2875           1 : }
    2876             : 
    2877             : #undef dirvote_compute_params
    2878             : 
    2879             : /** Helper: Test that two networkstatus_voter_info_t do in fact represent the
    2880             :  * same voting authority, and that they do in fact have all the same
    2881             :  * information. */
    2882             : static void
    2883           9 : test_same_voter(networkstatus_voter_info_t *v1,
    2884             :                 networkstatus_voter_info_t *v2)
    2885             : {
    2886           9 :   tt_str_op(v1->nickname,OP_EQ, v2->nickname);
    2887           9 :   tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
    2888           9 :   tt_str_op(v1->address,OP_EQ, v2->address);
    2889           9 :   tt_assert(tor_addr_eq(&v1->ipv4_addr, &v2->ipv4_addr));
    2890           9 :   tt_int_op(v1->ipv4_dirport,OP_EQ, v2->ipv4_dirport);
    2891           9 :   tt_int_op(v1->ipv4_orport,OP_EQ, v2->ipv4_orport);
    2892           9 :   tt_str_op(v1->contact,OP_EQ, v2->contact);
    2893           9 :   tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
    2894           9 :  done:
    2895           9 :   ;
    2896           9 : }
    2897             : 
    2898             : /** Helper: get a detached signatures document for one or two
    2899             :  * consensuses. */
    2900             : static char *
    2901           9 : get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
    2902             : {
    2903           9 :   char *r;
    2904           9 :   smartlist_t *sl;
    2905           9 :   tor_assert(ns && ns->flavor == FLAV_NS);
    2906           9 :   sl = smartlist_new();
    2907           9 :   smartlist_add(sl,ns);
    2908           9 :   if (ns2)
    2909           9 :     smartlist_add(sl,ns2);
    2910           9 :   r = networkstatus_get_detached_signatures(sl);
    2911           9 :   smartlist_free(sl);
    2912           9 :   return r;
    2913             : }
    2914             : 
    2915             : /** Apply tweaks to the vote list for each voter */
    2916             : static int
    2917           3 : vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
    2918             : {
    2919           3 :   vote_routerstatus_t *vrs;
    2920           3 :   const char *msg = NULL;
    2921             : 
    2922           3 :   tt_assert(v);
    2923           3 :   (void)now;
    2924             : 
    2925           3 :   if (voter == 1) {
    2926           1 :     measured_bw_line_t mbw;
    2927           1 :     memset(mbw.node_id, 33, sizeof(mbw.node_id));
    2928           1 :     mbw.bw_kb = 1024;
    2929           1 :     tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1);
    2930           2 :   } else if (voter == 2 || voter == 3) {
    2931             :     /* Monkey around with the list a bit */
    2932           2 :     vrs = smartlist_get(v->routerstatus_list, 2);
    2933           2 :     smartlist_del_keeporder(v->routerstatus_list, 2);
    2934           2 :     vote_routerstatus_free(vrs);
    2935           2 :     vrs = smartlist_get(v->routerstatus_list, 0);
    2936           2 :     vrs->status.is_fast = 1;
    2937             : 
    2938           2 :     if (voter == 3) {
    2939           1 :       vrs = smartlist_get(v->routerstatus_list, 0);
    2940           1 :       smartlist_del_keeporder(v->routerstatus_list, 0);
    2941           1 :       vote_routerstatus_free(vrs);
    2942           1 :       vrs = smartlist_get(v->routerstatus_list, 0);
    2943           1 :       memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
    2944           1 :       tt_assert(router_add_to_routerlist(
    2945             :                   dir_common_generate_ri_from_rs(vrs), &msg,0,0) >= 0);
    2946             :     }
    2947             :   }
    2948             : 
    2949           2 :  done:
    2950           3 :   return 0;
    2951             : }
    2952             : 
    2953             : /**
    2954             :  * Test a parsed vote_routerstatus_t for v3_networkstatus test
    2955             :  */
    2956             : static void
    2957           7 : test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
    2958             : {
    2959           7 :   routerstatus_t *rs;
    2960           7 :   tor_addr_t addr_ipv6;
    2961             : 
    2962           7 :   tt_assert(vrs);
    2963           7 :   rs = &(vrs->status);
    2964           7 :   tt_assert(rs);
    2965             : 
    2966             :   /* Split out by digests to test */
    2967           7 :   if (tor_memeq(rs->identity_digest,
    2968             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    2969             :                 "\x3\x3\x3\x3",
    2970           2 :                 DIGEST_LEN) &&
    2971             :                 (voter == 1)) {
    2972             :     /* Check the first routerstatus. */
    2973           1 :     tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
    2974           1 :     tt_int_op(rs->published_on,OP_EQ, now-1500);
    2975           1 :     tt_str_op(rs->nickname,OP_EQ, "router2");
    2976           1 :     tt_mem_op(rs->identity_digest,OP_EQ,
    2977             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    2978             :                "\x3\x3\x3\x3",
    2979           1 :                DIGEST_LEN);
    2980           1 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
    2981           1 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
    2982           1 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    2983           1 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
    2984             :     /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
    2985           1 :     tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
    2986           6 :   } else if (tor_memeq(rs->identity_digest,
    2987             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    2988             :                        "\x5\x5\x5\x5",
    2989           2 :                        DIGEST_LEN) &&
    2990           2 :                        (voter == 1 || voter == 2)) {
    2991           2 :     tt_mem_op(rs->identity_digest,OP_EQ,
    2992             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    2993             :                "\x5\x5\x5\x5",
    2994           2 :                DIGEST_LEN);
    2995             : 
    2996           2 :     if (voter == 1) {
    2997             :       /* Check the second routerstatus. */
    2998           1 :       tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
    2999           1 :       tt_int_op(rs->published_on,OP_EQ, now-1000);
    3000           1 :       tt_str_op(rs->nickname,OP_EQ, "router1");
    3001             :     }
    3002           2 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
    3003           2 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
    3004           2 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    3005           2 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
    3006           2 :     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
    3007           2 :     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
    3008           2 :     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
    3009           2 :     if (voter == 1) {
    3010             :       /* all except "authority" (1) */
    3011           1 :       tt_u64_op(vrs->flags, OP_EQ, UINT64_C(254));
    3012             :     } else {
    3013             :       /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
    3014           1 :       tt_u64_op(vrs->flags, OP_EQ, UINT64_C(974));
    3015             :     }
    3016           4 :   } else if (tor_memeq(rs->identity_digest,
    3017             :                        "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
    3018             :                        "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
    3019           0 :                        DIGEST_LEN) &&
    3020           0 :                        (voter == 1 || voter == 2)) {
    3021             :     /* Check the measured bandwidth bits */
    3022           0 :     tt_assert(vrs->has_measured_bw &&
    3023             :                 vrs->measured_bw_kb == 1024);
    3024             :   } else {
    3025             :     /*
    3026             :      * Didn't expect this, but the old unit test only checked some of them,
    3027             :      * so don't assert.
    3028             :      */
    3029             :     /* tt_assert(0); */
    3030           7 :   }
    3031             : 
    3032           4 :  done:
    3033           7 :   return;
    3034             : }
    3035             : 
    3036             : /**
    3037             :  * Test a consensus for v3_networkstatus_test
    3038             :  */
    3039             : static void
    3040           1 : test_consensus_for_v3ns(networkstatus_t *con, time_t now)
    3041             : {
    3042           1 :   (void)now;
    3043             : 
    3044           1 :   tt_assert(con);
    3045           1 :   tt_ptr_op(con->cert, OP_EQ, NULL);
    3046           1 :   tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list));
    3047             :   /* There should be two listed routers: one with identity 3, one with
    3048             :    * identity 5. */
    3049             : 
    3050           1 :  done:
    3051           1 :   return;
    3052             : }
    3053             : 
    3054             : /**
    3055             :  * Test a router list entry for v3_networkstatus test
    3056             :  */
    3057             : static void
    3058           2 : test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
    3059             : {
    3060           2 :   tor_addr_t addr_ipv6;
    3061             : 
    3062           2 :   tt_assert(rs);
    3063             : 
    3064             :   /* There should be two listed routers: one with identity 3, one with
    3065             :    * identity 5. */
    3066             :   /* This one showed up in 2 digests. */
    3067           2 :   if (tor_memeq(rs->identity_digest,
    3068             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    3069             :                 "\x3\x3",
    3070             :                 DIGEST_LEN)) {
    3071           1 :     tt_mem_op(rs->identity_digest,OP_EQ,
    3072             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
    3073           1 :                DIGEST_LEN);
    3074           1 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
    3075           1 :     tt_assert(!rs->is_authority);
    3076           1 :     tt_assert(!rs->is_exit);
    3077           1 :     tt_assert(!rs->is_fast);
    3078           1 :     tt_assert(!rs->is_possible_guard);
    3079           1 :     tt_assert(!rs->is_stable);
    3080             :     /* (If it wasn't running it wouldn't be here) */
    3081           1 :     tt_assert(rs->is_flagged_running);
    3082           1 :     tt_assert(rs->is_valid);
    3083           1 :     tt_assert(!rs->is_named);
    3084           1 :     tt_assert(rs->is_v2_dir);
    3085             :     /* XXXX check version */
    3086           1 :   } else if (tor_memeq(rs->identity_digest,
    3087             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    3088             :                        "\x5\x5\x5\x5",
    3089             :                        DIGEST_LEN)) {
    3090             :     /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'.  */
    3091           1 :     tt_mem_op(rs->identity_digest,OP_EQ,
    3092             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
    3093           1 :                DIGEST_LEN);
    3094           1 :     tt_str_op(rs->nickname,OP_EQ, "router1");
    3095           1 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
    3096           1 :     tt_int_op(rs->published_on,OP_EQ, now-1000);
    3097           1 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
    3098           1 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    3099           1 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
    3100           1 :     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
    3101           1 :     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
    3102           1 :     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
    3103           1 :     tt_assert(!rs->is_authority);
    3104           1 :     tt_assert(rs->is_exit);
    3105           1 :     tt_assert(rs->is_fast);
    3106           1 :     tt_assert(rs->is_possible_guard);
    3107           1 :     tt_assert(rs->is_stable);
    3108           1 :     tt_assert(rs->is_flagged_running);
    3109           1 :     tt_assert(rs->is_valid);
    3110           1 :     tt_assert(rs->is_v2_dir);
    3111           1 :     tt_assert(!rs->is_named);
    3112             :     /* XXXX check version */
    3113             :   } else {
    3114             :     /* Weren't expecting this... */
    3115           0 :     tt_abort();
    3116             :   }
    3117             : 
    3118           2 :  done:
    3119           2 :   return;
    3120             : }
    3121             : 
    3122             : static void
    3123           1 : test_dir_networkstatus_compute_bw_weights_v10(void *arg)
    3124             : {
    3125           1 :   (void) arg;
    3126           1 :   smartlist_t *chunks = smartlist_new();
    3127           1 :   int64_t G, M, E, D, T, weight_scale;
    3128           1 :   int ret;
    3129           1 :   weight_scale = 10000;
    3130             : 
    3131             :   /* no case. one or more of the values is 0 */
    3132           1 :   G = M = E = D = 0;
    3133           1 :   T = G + M + E + D;
    3134           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3135             :                                              weight_scale);
    3136           1 :   tt_int_op(ret, OP_EQ, 0);
    3137           1 :   tt_int_op(smartlist_len(chunks), OP_EQ, 0);
    3138             : 
    3139             :   /* case 1 */
    3140             :   /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
    3141             :    * testing current behavior, not spec. */
    3142           1 :   G = E = 10;
    3143           1 :   M = D = 1;
    3144           1 :   T = G + M + E + D;
    3145           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3146             :                                              weight_scale);
    3147           1 :   tt_int_op(ret, OP_EQ, 1);
    3148           1 :   tt_int_op(smartlist_len(chunks), OP_EQ, 1);
    3149           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
    3150             :     "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
    3151             :     "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
    3152             :     "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
    3153           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3154           1 :   smartlist_clear(chunks);
    3155             : 
    3156             :   /* case 2a E scarce */
    3157           1 :   M = 100;
    3158           1 :   G = 20;
    3159           1 :   E = D = 5;
    3160           1 :   T = G + M + E + D;
    3161           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3162             :                                              weight_scale);
    3163           1 :   tt_int_op(ret, OP_EQ, 1);
    3164           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
    3165             :     "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
    3166             :     "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
    3167             :     "Wmg=0 Wmm=10000\n");
    3168           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3169           1 :   smartlist_clear(chunks);
    3170             : 
    3171             :   /* case 2a G scarce */
    3172           1 :   M = 100;
    3173           1 :   E = 20;
    3174           1 :   G = D = 5;
    3175           1 :   T = G + M + E + D;
    3176           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3177             :                                              weight_scale);
    3178           1 :   tt_int_op(ret, OP_EQ, 1);
    3179           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
    3180             :     "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
    3181             :     "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
    3182             :     "Wmm=10000\n");
    3183           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3184           1 :   smartlist_clear(chunks);
    3185             : 
    3186             :   /* case 2b1 (Wgg=1, Wmd=Wgd) */
    3187           1 :   M = 10;
    3188           1 :   E = 30;
    3189           1 :   G = 10;
    3190           1 :   D = 100;
    3191           1 :   T = G + M + E + D;
    3192           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3193             :                                              weight_scale);
    3194           1 :   tt_int_op(ret, OP_EQ, 1);
    3195           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
    3196             :     "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
    3197             :     "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
    3198             :     "Wme=0 Wmg=0 Wmm=10000\n");
    3199           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3200           1 :   smartlist_clear(chunks);
    3201             : 
    3202             :   /* case 2b2 */
    3203           1 :   M = 60;
    3204           1 :   E = 30;
    3205           1 :   G = 10;
    3206           1 :   D = 100;
    3207           1 :   T = G + M + E + D;
    3208           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3209             :                                              weight_scale);
    3210           1 :   tt_int_op(ret, OP_EQ, 1);
    3211           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
    3212             :     "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
    3213             :     "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
    3214             :     "Wme=0 Wmg=0 Wmm=10000\n");
    3215           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3216           1 :   smartlist_clear(chunks);
    3217             : 
    3218             :   /* case 2b3 */
    3219             :   /* XXX I can't get a combination of values that hits this case without error,
    3220             :    * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
    3221             :    * not follow dir-spec. */
    3222             :   /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
    3223           1 :   M = 80;
    3224           1 :   E = 30;
    3225           1 :   G = 30;
    3226           1 :   D = 30;
    3227           1 :   T = G + M + E + D;
    3228           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3229             :                                              weight_scale);
    3230           1 :   tt_int_op(ret, OP_EQ, 0);
    3231           1 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3232           1 :   smartlist_clear(chunks);
    3233             : 
    3234             :   /* case 3a G scarce */
    3235           1 :   M = 10;
    3236           1 :   E = 30;
    3237           1 :   G = 10;
    3238           1 :   D = 5;
    3239           1 :   T = G + M + E + D;
    3240           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3241             :                                              weight_scale);
    3242           1 :   tt_int_op(ret, OP_EQ, 1);
    3243           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
    3244             :     "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
    3245             :     "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
    3246             :     "Wme=3333 Wmg=0 Wmm=10000\n");
    3247           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3248           1 :   smartlist_clear(chunks);
    3249             : 
    3250             :   /* case 3a E scarce */
    3251           1 :   M = 10;
    3252           1 :   E = 10;
    3253           1 :   G = 30;
    3254           1 :   D = 5;
    3255           1 :   T = G + M + E + D;
    3256           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3257             :                                              weight_scale);
    3258           1 :   tt_int_op(ret, OP_EQ, 1);
    3259           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
    3260             :     "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
    3261             :     "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
    3262             :     "Wmg=3333 Wmm=10000\n");
    3263           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3264           1 :   smartlist_clear(chunks);
    3265             : 
    3266             :   /* case 3bg */
    3267           1 :   M = 10;
    3268           1 :   E = 30;
    3269           1 :   G = 10;
    3270           1 :   D = 10;
    3271           1 :   T = G + M + E + D;
    3272           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3273             :                                              weight_scale);
    3274           1 :   tt_int_op(ret, OP_EQ, 1);
    3275           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
    3276             :     "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
    3277             :     "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
    3278             :     "Wme=3334 Wmg=0 Wmm=10000\n");
    3279           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3280           1 :   smartlist_clear(chunks);
    3281             : 
    3282             :   /* case 3be */
    3283           1 :   M = 10;
    3284           1 :   E = 10;
    3285           1 :   G = 30;
    3286           1 :   D = 10;
    3287           1 :   T = G + M + E + D;
    3288           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3289             :                                              weight_scale);
    3290           1 :   tt_int_op(ret, OP_EQ, 1);
    3291           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
    3292             :     "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
    3293             :     "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
    3294             :     "Wmg=3334 Wmm=10000\n");
    3295           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3296           1 :   smartlist_clear(chunks);
    3297             : 
    3298             :   /* case from 21 Jul 2013 (3be) */
    3299           1 :   G = 5483409;
    3300           1 :   M = 1455379;
    3301           1 :   E = 980834;
    3302           1 :   D = 3385803;
    3303           1 :   T = 11305425;
    3304           1 :   tt_i64_op(G+M+E+D, OP_EQ, T);
    3305           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3306             :                                              weight_scale);
    3307           1 :   tt_assert(ret);
    3308           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
    3309             :     "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
    3310             :     "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
    3311             :     "Wmg=3673 Wmm=10000\n");
    3312           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3313           1 :   smartlist_clear(chunks);
    3314             : 
    3315             :   /* case from 04 Oct 2016 (3a E scarce) */
    3316           1 :   G=29322240;
    3317           1 :   M=4721546;
    3318           1 :   E=1522058;
    3319           1 :   D=9273571;
    3320           1 :   T=44839415;
    3321           1 :   tt_i64_op(G+M+E+D, OP_EQ, T);
    3322           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3323             :                                              weight_scale);
    3324           1 :   tt_assert(ret);
    3325           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
    3326             :     "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
    3327             :     "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
    3328             :     "Wmg=4194 Wmm=10000\n");
    3329           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3330           1 :   smartlist_clear(chunks);
    3331             : 
    3332             :   /* case from 04 Sep 2013 (2b1) */
    3333           1 :   G=3091352;
    3334           1 :   M=1838837;
    3335           1 :   E=2109300;
    3336           1 :   D=2469369;
    3337           1 :   T=9508858;
    3338           1 :   tt_i64_op(G+M+E+D, OP_EQ, T);
    3339           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3340             :                                              weight_scale);
    3341           1 :   tt_assert(ret);
    3342           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
    3343             :     "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
    3344             :     "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
    3345             :     "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
    3346           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3347           1 :   smartlist_clear(chunks);
    3348             : 
    3349             :   /* explicitly test initializing weights to 1*/
    3350           1 :   G=1;
    3351           1 :   M=1;
    3352           1 :   E=1;
    3353           1 :   D=1;
    3354           1 :   T=4;
    3355           1 :   tt_i64_op(G+M+E+D, OP_EQ, T);
    3356           1 :   ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
    3357             :                                              weight_scale);
    3358           1 :   tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
    3359             :     "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
    3360             :     "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
    3361             :     "Wme=0 Wmg=0 Wmm=10000\n");
    3362           1 :   tt_assert(ret);
    3363             : 
    3364           1 :  done:
    3365           2 :   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
    3366           1 :   smartlist_free(chunks);
    3367           1 : }
    3368             : 
    3369             : static authority_cert_t *mock_cert;
    3370             : 
    3371             : static authority_cert_t *
    3372           3 : get_my_v3_authority_cert_m(void)
    3373             : {
    3374           3 :   tor_assert(mock_cert);
    3375           3 :   return mock_cert;
    3376             : }
    3377             : 
    3378             : /** Run a unit tests for generating and parsing networkstatuses, with
    3379             :  * the supply test fns. */
    3380             : static void
    3381           3 : test_a_networkstatus(
    3382             :     vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
    3383             :     int (*vote_tweaks)(networkstatus_t *v, int voter, time_t now),
    3384             :     void (*vrs_test)(vote_routerstatus_t *vrs, int voter, time_t now),
    3385             :     void (*consensus_test)(networkstatus_t *con, time_t now),
    3386             :     void (*rs_test)(routerstatus_t *rs, time_t now))
    3387             : {
    3388           3 :   authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
    3389           3 :   crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
    3390           3 :   crypto_pk_t *sign_skey_leg1=NULL;
    3391             :   /*
    3392             :    * Sum the non-zero returns from vote_tweaks() we've seen; if vote_tweaks()
    3393             :    * returns non-zero, it changed net_params and we should skip the tests for
    3394             :    * that later as they will fail.
    3395             :    */
    3396           3 :   int params_tweaked = 0;
    3397             : 
    3398           3 :   time_t now = time(NULL);
    3399           3 :   networkstatus_voter_info_t *voter;
    3400           3 :   document_signature_t *sig;
    3401           3 :   networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
    3402           3 :     *con_md=NULL;
    3403           3 :   vote_routerstatus_t *vrs;
    3404           3 :   routerstatus_t *rs;
    3405           3 :   int idx, n_rs, n_vrs;
    3406           3 :   char *consensus_text=NULL, *cp=NULL;
    3407           3 :   smartlist_t *votes = smartlist_new();
    3408             : 
    3409             :   /* For generating the two other consensuses. */
    3410           3 :   char *detached_text1=NULL, *detached_text2=NULL;
    3411           3 :   char *consensus_text2=NULL, *consensus_text3=NULL;
    3412           3 :   char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
    3413           3 :   char *consensus_text_md=NULL;
    3414           3 :   networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
    3415           3 :   ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
    3416             : 
    3417           3 :   tt_assert(vrs_gen);
    3418           3 :   tt_assert(rs_test);
    3419           3 :   tt_assert(vrs_test);
    3420             : 
    3421           3 :   MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
    3422             : 
    3423             :   /* Parse certificates and keys. */
    3424           3 :   cert1 = mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
    3425             :                                                  strlen(AUTHORITY_CERT_1),
    3426             :                                                  NULL);
    3427           3 :   tt_assert(cert1);
    3428           3 :   cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2,
    3429             :                                            strlen(AUTHORITY_CERT_2),
    3430             :                                            NULL);
    3431           3 :   tt_assert(cert2);
    3432           3 :   cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3,
    3433             :                                            strlen(AUTHORITY_CERT_3),
    3434             :                                            NULL);
    3435           3 :   tt_assert(cert3);
    3436           3 :   sign_skey_1 = crypto_pk_new();
    3437           3 :   sign_skey_2 = crypto_pk_new();
    3438           3 :   sign_skey_3 = crypto_pk_new();
    3439           3 :   sign_skey_leg1 = pk_generate(4);
    3440           3 :   dirauth_sched_recalculate_timing(get_options(), now);
    3441           3 :   sr_state_init(0, 0);
    3442             : 
    3443           3 :   tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
    3444             :                                                    AUTHORITY_SIGNKEY_1, -1));
    3445           3 :   tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
    3446             :                                                    AUTHORITY_SIGNKEY_2, -1));
    3447           3 :   tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
    3448             :                                                    AUTHORITY_SIGNKEY_3, -1));
    3449             : 
    3450           3 :   tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
    3451           3 :   tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
    3452             : 
    3453           3 :   tt_assert(!dir_common_construct_vote_1(&vote, cert1, sign_skey_1, vrs_gen,
    3454             :                                          &v1, &n_vrs, now, 1));
    3455           3 :   tt_assert(v1);
    3456             : 
    3457             :   /* Make sure the parsed thing was right. */
    3458           3 :   tt_int_op(v1->type,OP_EQ, NS_TYPE_VOTE);
    3459           3 :   tt_int_op(v1->published,OP_EQ, vote->published);
    3460           3 :   tt_int_op(v1->valid_after,OP_EQ, vote->valid_after);
    3461           3 :   tt_int_op(v1->fresh_until,OP_EQ, vote->fresh_until);
    3462           3 :   tt_int_op(v1->valid_until,OP_EQ, vote->valid_until);
    3463           3 :   tt_int_op(v1->vote_seconds,OP_EQ, vote->vote_seconds);
    3464           3 :   tt_int_op(v1->dist_seconds,OP_EQ, vote->dist_seconds);
    3465           3 :   tt_str_op(v1->client_versions,OP_EQ, vote->client_versions);
    3466           3 :   tt_str_op(v1->server_versions,OP_EQ, vote->server_versions);
    3467           3 :   tt_assert(v1->voters && smartlist_len(v1->voters));
    3468           3 :   voter = smartlist_get(v1->voters, 0);
    3469           3 :   tt_str_op(voter->nickname,OP_EQ, "Voter1");
    3470           3 :   tt_str_op(voter->address,OP_EQ, "1.2.3.4");
    3471           3 :   tt_assert(tor_addr_eq_ipv4h(&voter->ipv4_addr, 0x01020304));
    3472           3 :   tt_int_op(voter->ipv4_dirport,OP_EQ, 80);
    3473           3 :   tt_int_op(voter->ipv4_orport,OP_EQ, 9000);
    3474           3 :   tt_str_op(voter->contact,OP_EQ, "voter@example.com");
    3475           3 :   tt_assert(v1->cert);
    3476           3 :   tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
    3477           3 :   cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
    3478           3 :   tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
    3479           3 :   tor_free(cp);
    3480           3 :   tt_int_op(smartlist_len(v1->routerstatus_list),OP_EQ, n_vrs);
    3481           3 :   networkstatus_vote_free(vote);
    3482           3 :   vote = NULL;
    3483             : 
    3484           3 :   if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
    3485             : 
    3486             :   /* Check the routerstatuses. */
    3487          15 :   for (idx = 0; idx < n_vrs; ++idx) {
    3488          12 :     vrs = smartlist_get(v1->routerstatus_list, idx);
    3489          12 :     tt_assert(vrs);
    3490          12 :     vrs_test(vrs, 1, now);
    3491             :   }
    3492             : 
    3493             :   /* Generate second vote. It disagrees on some of the times,
    3494             :    * and doesn't list versions, and knows some crazy flags.
    3495             :    * Generate and parse v2. */
    3496           3 :   tt_assert(!dir_common_construct_vote_2(&vote, cert2, sign_skey_2, vrs_gen,
    3497             :                                          &v2, &n_vrs, now, 1));
    3498           3 :   tt_assert(v2);
    3499             : 
    3500           3 :   if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
    3501             : 
    3502             :   /* Check that flags come out right.*/
    3503           3 :   cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
    3504           3 :   tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
    3505             :              "Running:Stable:V2Dir:Valid");
    3506           3 :   tor_free(cp);
    3507             : 
    3508             :   /* Check the routerstatuses. */
    3509           3 :   n_vrs = smartlist_len(v2->routerstatus_list);
    3510          14 :   for (idx = 0; idx < n_vrs; ++idx) {
    3511          11 :     vrs = smartlist_get(v2->routerstatus_list, idx);
    3512          11 :     tt_assert(vrs);
    3513          11 :     vrs_test(vrs, 2, now);
    3514             :   }
    3515           3 :   networkstatus_vote_free(vote);
    3516           3 :   vote = NULL;
    3517             : 
    3518             :   /* Generate the third vote with a legacy id. */
    3519           3 :   tt_assert(!dir_common_construct_vote_3(&vote, cert3, sign_skey_3, vrs_gen,
    3520             :                                          &v3, &n_vrs, now, 1));
    3521           3 :   tt_assert(v3);
    3522             : 
    3523           3 :   if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
    3524             : 
    3525             :   /* Compute a consensus as voter 3. */
    3526           3 :   smartlist_add(votes, v3);
    3527           3 :   smartlist_add(votes, v1);
    3528           3 :   smartlist_add(votes, v2);
    3529           3 :   consensus_text = networkstatus_compute_consensus(votes, 3,
    3530             :                                                    cert3->identity_key,
    3531             :                                                    sign_skey_3,
    3532             :                                                    "AAAAAAAAAAAAAAAAAAAA",
    3533             :                                                    sign_skey_leg1,
    3534             :                                                    FLAV_NS);
    3535           3 :   tt_assert(consensus_text);
    3536           3 :   con = networkstatus_parse_vote_from_string_(consensus_text, NULL,
    3537             :                                              NS_TYPE_CONSENSUS);
    3538           3 :   tt_assert(con);
    3539             :   //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
    3540             :   //           v1_text, v2_text, v3_text);
    3541           3 :   consensus_text_md = networkstatus_compute_consensus(votes, 3,
    3542             :                                                    cert3->identity_key,
    3543             :                                                    sign_skey_3,
    3544             :                                                    "AAAAAAAAAAAAAAAAAAAA",
    3545             :                                                    sign_skey_leg1,
    3546             :                                                    FLAV_MICRODESC);
    3547           3 :   tt_assert(consensus_text_md);
    3548           3 :   con_md = networkstatus_parse_vote_from_string_(consensus_text_md, NULL,
    3549             :                                                 NS_TYPE_CONSENSUS);
    3550           3 :   tt_assert(con_md);
    3551           3 :   tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC);
    3552             : 
    3553             :   /* Check consensus contents. */
    3554           3 :   tt_assert(con->type == NS_TYPE_CONSENSUS);
    3555           3 :   tt_int_op(con->published,OP_EQ, 0); /* this field only appears in votes. */
    3556           3 :   tt_int_op(con->valid_after,OP_EQ, now+1000);
    3557           3 :   tt_int_op(con->fresh_until,OP_EQ, now+2003); /* median */
    3558           3 :   tt_int_op(con->valid_until,OP_EQ, now+3000);
    3559           3 :   tt_int_op(con->vote_seconds,OP_EQ, 100);
    3560           3 :   tt_int_op(con->dist_seconds,OP_EQ, 250); /* median */
    3561           3 :   tt_str_op(con->client_versions,OP_EQ, "0.1.2.14");
    3562           3 :   tt_str_op(con->server_versions,OP_EQ, "0.1.2.15,0.1.2.16");
    3563           3 :   cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
    3564           3 :   tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
    3565             :              "Running:Stable:V2Dir:Valid");
    3566           3 :   tor_free(cp);
    3567           3 :   if (!params_tweaked) {
    3568             :     /* Skip this one if vote_tweaks() messed with the param lists */
    3569           2 :     cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
    3570           2 :     tt_str_op(cp,OP_EQ, "circuitwindow=80:foo=660");
    3571           2 :     tor_free(cp);
    3572             :   }
    3573             : 
    3574           3 :   tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
    3575             :   /* The voter id digests should be in this order. */
    3576           3 :   tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
    3577             :                      cert1->cache_info.identity_digest,DIGEST_LEN)<0);
    3578           3 :   tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
    3579             :                      cert3->cache_info.identity_digest,DIGEST_LEN)<0);
    3580           3 :   test_same_voter(smartlist_get(con->voters, 1),
    3581           3 :                   smartlist_get(v2->voters, 0));
    3582           3 :   test_same_voter(smartlist_get(con->voters, 2),
    3583           3 :                   smartlist_get(v1->voters, 0));
    3584           3 :   test_same_voter(smartlist_get(con->voters, 3),
    3585           3 :                   smartlist_get(v3->voters, 0));
    3586             : 
    3587           3 :   consensus_test(con, now);
    3588             : 
    3589             :   /* Check the routerstatuses. */
    3590           3 :   n_rs = smartlist_len(con->routerstatus_list);
    3591           3 :   tt_assert(n_rs);
    3592          13 :   for (idx = 0; idx < n_rs; ++idx) {
    3593          10 :     rs = smartlist_get(con->routerstatus_list, idx);
    3594          10 :     tt_assert(rs);
    3595          10 :     rs_test(rs, now);
    3596             :   }
    3597             : 
    3598           3 :   n_rs = smartlist_len(con_md->routerstatus_list);
    3599           3 :   tt_assert(n_rs);
    3600          13 :   for (idx = 0; idx < n_rs; ++idx) {
    3601          10 :     rs = smartlist_get(con_md->routerstatus_list, idx);
    3602          10 :     tt_assert(rs);
    3603             :   }
    3604             : 
    3605             :   /* Check signatures.  the first voter is a pseudo-entry with a legacy key.
    3606             :    * The second one hasn't signed.  The fourth one has signed: validate it. */
    3607           3 :   voter = smartlist_get(con->voters, 1);
    3608           3 :   tt_int_op(smartlist_len(voter->sigs),OP_EQ, 0);
    3609             : 
    3610           3 :   voter = smartlist_get(con->voters, 3);
    3611           3 :   tt_int_op(smartlist_len(voter->sigs),OP_EQ, 1);
    3612           3 :   sig = smartlist_get(voter->sigs, 0);
    3613           3 :   tt_assert(sig->signature);
    3614           3 :   tt_assert(!sig->good_signature);
    3615           3 :   tt_assert(!sig->bad_signature);
    3616             : 
    3617           3 :   tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
    3618           3 :   tt_assert(sig->signature);
    3619           3 :   tt_assert(sig->good_signature);
    3620           3 :   tt_assert(!sig->bad_signature);
    3621             : 
    3622             :   {
    3623           3 :     const char *msg=NULL;
    3624             :     /* Compute the other two signed consensuses. */
    3625           3 :     smartlist_shuffle(votes);
    3626           3 :     consensus_text2 = networkstatus_compute_consensus(votes, 3,
    3627             :                                                       cert2->identity_key,
    3628             :                                                       sign_skey_2, NULL,NULL,
    3629             :                                                       FLAV_NS);
    3630           3 :     consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
    3631             :                                                       cert2->identity_key,
    3632             :                                                       sign_skey_2, NULL,NULL,
    3633             :                                                       FLAV_MICRODESC);
    3634           3 :     smartlist_shuffle(votes);
    3635           3 :     consensus_text3 = networkstatus_compute_consensus(votes, 3,
    3636             :                                                       cert1->identity_key,
    3637             :                                                       sign_skey_1, NULL,NULL,
    3638             :                                                       FLAV_NS);
    3639           3 :     consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
    3640             :                                                       cert1->identity_key,
    3641             :                                                       sign_skey_1, NULL,NULL,
    3642             :                                                       FLAV_MICRODESC);
    3643           3 :     tt_assert(consensus_text2);
    3644           3 :     tt_assert(consensus_text3);
    3645           3 :     tt_assert(consensus_text_md2);
    3646           3 :     tt_assert(consensus_text_md3);
    3647           3 :     con2 = networkstatus_parse_vote_from_string_(consensus_text2, NULL,
    3648             :                                                 NS_TYPE_CONSENSUS);
    3649           3 :     con3 = networkstatus_parse_vote_from_string_(consensus_text3, NULL,
    3650             :                                                 NS_TYPE_CONSENSUS);
    3651           3 :     con_md2 = networkstatus_parse_vote_from_string_(consensus_text_md2, NULL,
    3652             :                                                 NS_TYPE_CONSENSUS);
    3653           3 :     con_md3 = networkstatus_parse_vote_from_string_(consensus_text_md3, NULL,
    3654             :                                                 NS_TYPE_CONSENSUS);
    3655           3 :     tt_assert(con2);
    3656           3 :     tt_assert(con3);
    3657           3 :     tt_assert(con_md2);
    3658           3 :     tt_assert(con_md3);
    3659             : 
    3660             :     /* All three should have the same digest. */
    3661           3 :     tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t));
    3662           3 :     tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t));
    3663             : 
    3664           3 :     tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests,
    3665           3 :               sizeof(common_digests_t));
    3666           3 :     tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests,
    3667           3 :               sizeof(common_digests_t));
    3668             : 
    3669             :     /* Extract a detached signature from con3. */
    3670           3 :     detached_text1 = get_detached_sigs(con3, con_md3);
    3671           3 :     tt_assert(detached_text1);
    3672             :     /* Try to parse it. */
    3673           3 :     dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
    3674           3 :     tt_assert(dsig1);
    3675             : 
    3676             :     /* Are parsed values as expected? */
    3677           3 :     tt_int_op(dsig1->valid_after,OP_EQ, con3->valid_after);
    3678           3 :     tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until);
    3679           3 :     tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until);
    3680             :     {
    3681           3 :       common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
    3682           3 :       tt_assert(dsig_digests);
    3683           3 :       tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ,
    3684           3 :                 con3->digests.d[DIGEST_SHA1], DIGEST_LEN);
    3685           3 :       dsig_digests = strmap_get(dsig1->digests, "microdesc");
    3686           3 :       tt_assert(dsig_digests);
    3687           3 :       tt_mem_op(dsig_digests->d[DIGEST_SHA256],OP_EQ,
    3688             :                  con_md3->digests.d[DIGEST_SHA256],
    3689           3 :                  DIGEST256_LEN);
    3690             :     }
    3691             :     {
    3692           3 :       smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
    3693           3 :       tt_assert(dsig_signatures);
    3694           3 :       tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
    3695           3 :       sig = smartlist_get(dsig_signatures, 0);
    3696           3 :       tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
    3697           3 :                  DIGEST_LEN);
    3698           3 :       tt_int_op(sig->alg,OP_EQ, DIGEST_SHA1);
    3699             : 
    3700           3 :       dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
    3701           3 :       tt_assert(dsig_signatures);
    3702           3 :       tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
    3703           3 :       sig = smartlist_get(dsig_signatures, 0);
    3704           3 :       tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
    3705           3 :                  DIGEST_LEN);
    3706           3 :       tt_int_op(sig->alg,OP_EQ, DIGEST_SHA256);
    3707             :     }
    3708             : 
    3709             :     /* Try adding it to con2. */
    3710           3 :     detached_text2 = get_detached_sigs(con2,con_md2);
    3711           3 :     tt_int_op(1,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
    3712             :                                                    "test", LOG_INFO, &msg));
    3713           3 :     tor_free(detached_text2);
    3714           3 :     tt_int_op(1,OP_EQ,
    3715             :               networkstatus_add_detached_signatures(con_md2, dsig1, "test",
    3716             :                                                      LOG_INFO, &msg));
    3717           3 :     tor_free(detached_text2);
    3718           3 :     detached_text2 = get_detached_sigs(con2,con_md2);
    3719             :     //printf("\n<%s>\n", detached_text2);
    3720           3 :     dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
    3721           3 :     tt_assert(dsig2);
    3722             :     /*
    3723             :     printf("\n");
    3724             :     SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
    3725             :         char hd[64];
    3726             :         base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
    3727             :         printf("%s\n", hd);
    3728             :       });
    3729             :     */
    3730           3 :     tt_int_op(2,OP_EQ,
    3731             :             smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
    3732           3 :     tt_int_op(2,OP_EQ,
    3733             :             smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
    3734             :                                                    "microdesc")));
    3735             : 
    3736             :     /* Try adding to con2 twice; verify that nothing changes. */
    3737           3 :     tt_int_op(0,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
    3738             :                                                "test", LOG_INFO, &msg));
    3739             : 
    3740             :     /* Add to con. */
    3741           3 :     tt_int_op(2,OP_EQ, networkstatus_add_detached_signatures(con, dsig2,
    3742             :                                                "test", LOG_INFO, &msg));
    3743             :     /* Check signatures */
    3744           3 :     voter = smartlist_get(con->voters, 1);
    3745           3 :     sig = smartlist_get(voter->sigs, 0);
    3746           3 :     tt_assert(sig);
    3747           3 :     tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
    3748           3 :     voter = smartlist_get(con->voters, 2);
    3749           3 :     sig = smartlist_get(voter->sigs, 0);
    3750           3 :     tt_assert(sig);
    3751           3 :     tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
    3752             :   }
    3753             : 
    3754           3 :  done:
    3755           3 :   tor_free(cp);
    3756           3 :   smartlist_free(votes);
    3757           3 :   tor_free(consensus_text);
    3758           3 :   tor_free(consensus_text_md);
    3759             : 
    3760           3 :   networkstatus_vote_free(vote);
    3761           3 :   networkstatus_vote_free(v1);
    3762           3 :   networkstatus_vote_free(v2);
    3763           3 :   networkstatus_vote_free(v3);
    3764           3 :   networkstatus_vote_free(con);
    3765           3 :   networkstatus_vote_free(con_md);
    3766           3 :   crypto_pk_free(sign_skey_1);
    3767           3 :   crypto_pk_free(sign_skey_2);
    3768           3 :   crypto_pk_free(sign_skey_3);
    3769           3 :   crypto_pk_free(sign_skey_leg1);
    3770           3 :   authority_cert_free(cert1);
    3771           3 :   authority_cert_free(cert2);
    3772           3 :   authority_cert_free(cert3);
    3773             : 
    3774           3 :   tor_free(consensus_text2);
    3775           3 :   tor_free(consensus_text3);
    3776           3 :   tor_free(consensus_text_md2);
    3777           3 :   tor_free(consensus_text_md3);
    3778           3 :   tor_free(detached_text1);
    3779           3 :   tor_free(detached_text2);
    3780             : 
    3781           3 :   networkstatus_vote_free(con2);
    3782           3 :   networkstatus_vote_free(con3);
    3783           3 :   networkstatus_vote_free(con_md2);
    3784           3 :   networkstatus_vote_free(con_md3);
    3785           3 :   ns_detached_signatures_free(dsig1);
    3786           3 :   ns_detached_signatures_free(dsig2);
    3787           3 : }
    3788             : 
    3789             : /** Run unit tests for generating and parsing V3 consensus networkstatus
    3790             :  * documents. */
    3791             : static void
    3792           1 : test_dir_v3_networkstatus(void *arg)
    3793             : {
    3794           1 :   (void)arg;
    3795           1 :   test_a_networkstatus(dir_common_gen_routerstatus_for_v3ns,
    3796             :                        vote_tweaks_for_v3ns,
    3797             :                        test_vrs_for_v3ns,
    3798             :                        test_consensus_for_v3ns,
    3799             :                        test_routerstatus_for_v3ns);
    3800           1 : }
    3801             : 
    3802             : static void
    3803           1 : test_dir_scale_bw(void *testdata)
    3804             : {
    3805           1 :   double v[8] = { 2.0/3,
    3806             :                   7.0,
    3807             :                   1.0,
    3808             :                   3.0,
    3809             :                   1.0/5,
    3810             :                   1.0/7,
    3811             :                   12.0,
    3812             :                   24.0 };
    3813           1 :   double vals_dbl[8];
    3814           1 :   uint64_t vals_u64[8];
    3815           1 :   uint64_t total;
    3816           1 :   int i;
    3817             : 
    3818           1 :   (void) testdata;
    3819             : 
    3820           9 :   for (i=0; i<8; ++i)
    3821           8 :     vals_dbl[i] = v[i];
    3822             : 
    3823           1 :   scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total);
    3824             : 
    3825           1 :   tt_int_op((int)total, OP_EQ, 48);
    3826           1 :   total = 0;
    3827           9 :   for (i=0; i<8; ++i) {
    3828           8 :     total += vals_u64[i];
    3829             :   }
    3830           1 :   tt_assert(total >= (UINT64_C(1)<<60));
    3831           1 :   tt_assert(total <= (UINT64_C(1)<<62));
    3832             : 
    3833           9 :   for (i=0; i<8; ++i) {
    3834             :     /* vals[2].u64 is the scaled value of 1.0 */
    3835           8 :     double ratio = ((double)vals_u64[i]) / vals_u64[2];
    3836           8 :     tt_double_op(fabs(ratio - v[i]), OP_LT, .00001);
    3837             :   }
    3838             : 
    3839             :   /* test handling of no entries */
    3840           1 :   total = 1;
    3841           1 :   scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total);
    3842           1 :   tt_assert(total == 0);
    3843             : 
    3844             :   /* make sure we don't read the array when we have no entries
    3845             :    * may require compiler flags to catch NULL dereferences */
    3846           1 :   total = 1;
    3847           1 :   scale_array_elements_to_u64(NULL, NULL, 0, &total);
    3848           1 :   tt_assert(total == 0);
    3849             : 
    3850           1 :   scale_array_elements_to_u64(NULL, NULL, 0, NULL);
    3851             : 
    3852             :   /* test handling of zero totals */
    3853           1 :   total = 1;
    3854           1 :   vals_dbl[0] = 0.0;
    3855           1 :   scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total);
    3856           1 :   tt_assert(total == 0);
    3857           1 :   tt_assert(vals_u64[0] == 0);
    3858             : 
    3859           1 :   vals_dbl[0] = 0.0;
    3860           1 :   vals_dbl[1] = 0.0;
    3861           1 :   scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL);
    3862           1 :   tt_assert(vals_u64[0] == 0);
    3863           1 :   tt_assert(vals_u64[1] == 0);
    3864             : 
    3865           1 :  done:
    3866           1 :   ;
    3867           1 : }
    3868             : 
    3869             : static void
    3870           1 : test_dir_random_weighted(void *testdata)
    3871             : {
    3872           1 :   int histogram[10];
    3873           1 :   uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
    3874           1 :   uint64_t inp_u64[10];
    3875           1 :   int i, choice;
    3876           1 :   const int n = 50000;
    3877           1 :   double max_sq_error;
    3878           1 :   (void) testdata;
    3879             : 
    3880             :   /* Try a ten-element array with values from 0 through 10. The values are
    3881             :    * in a scrambled order to make sure we don't depend on order. */
    3882           1 :   memset(histogram,0,sizeof(histogram));
    3883          11 :   for (i=0; i<10; ++i) {
    3884          10 :     inp_u64[i] = vals[i];
    3885          10 :     total += vals[i];
    3886             :   }
    3887           1 :   tt_u64_op(total, OP_EQ, 45);
    3888       50001 :   for (i=0; i<n; ++i) {
    3889       50000 :     choice = choose_array_element_by_weight(inp_u64, 10);
    3890       50000 :     tt_int_op(choice, OP_GE, 0);
    3891       50000 :     tt_int_op(choice, OP_LT, 10);
    3892       50000 :     histogram[choice]++;
    3893             :   }
    3894             : 
    3895             :   /* Now see if we chose things about frequently enough. */
    3896             :   max_sq_error = 0;
    3897          11 :   for (i=0; i<10; ++i) {
    3898          10 :     int expected = (int)(n*vals[i]/total);
    3899          10 :     double frac_diff = 0, sq;
    3900          10 :     TT_BLATHER(("  %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
    3901          10 :     if (expected)
    3902           9 :       frac_diff = (histogram[i] - expected) / ((double)expected);
    3903             :     else
    3904           1 :       tt_int_op(histogram[i], OP_EQ, 0);
    3905             : 
    3906          10 :     sq = frac_diff * frac_diff;
    3907          10 :     if (sq > max_sq_error)
    3908           2 :       max_sq_error = sq;
    3909             :   }
    3910             :   /* It should almost always be much much less than this.  If you want to
    3911             :    * figure out the odds, please feel free. */
    3912           1 :   tt_double_op(max_sq_error, OP_LT, .05);
    3913             : 
    3914             :   /* Now try a singleton; do we choose it? */
    3915         101 :   for (i = 0; i < 100; ++i) {
    3916         100 :     choice = choose_array_element_by_weight(inp_u64, 1);
    3917         100 :     tt_int_op(choice, OP_EQ, 0);
    3918             :   }
    3919             : 
    3920             :   /* Now try an array of zeros.  We should choose randomly. */
    3921           1 :   memset(histogram,0,sizeof(histogram));
    3922           6 :   for (i = 0; i < 5; ++i)
    3923           5 :     inp_u64[i] = 0;
    3924       50001 :   for (i = 0; i < n; ++i) {
    3925       50000 :     choice = choose_array_element_by_weight(inp_u64, 5);
    3926       50000 :     tt_int_op(choice, OP_GE, 0);
    3927       50000 :     tt_int_op(choice, OP_LT, 5);
    3928       50000 :     histogram[choice]++;
    3929             :   }
    3930             :   /* Now see if we chose things about frequently enough. */
    3931             :   max_sq_error = 0;
    3932           6 :   for (i=0; i<5; ++i) {
    3933           5 :     int expected = n/5;
    3934           5 :     double frac_diff = 0, sq;
    3935           5 :     TT_BLATHER(("  %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
    3936           5 :     frac_diff = (histogram[i] - expected) / ((double)expected);
    3937           5 :     sq = frac_diff * frac_diff;
    3938           5 :     if (sq > max_sq_error)
    3939           3 :       max_sq_error = sq;
    3940             :   }
    3941             :   /* It should almost always be much much less than this.  If you want to
    3942             :    * figure out the odds, please feel free. */
    3943           1 :   tt_double_op(max_sq_error, OP_LT, .05);
    3944           1 :  done:
    3945           1 :   ;
    3946           1 : }
    3947             : 
    3948             : /* Function pointers for test_dir_clip_unmeasured_bw_kb() */
    3949             : 
    3950             : static uint32_t alternate_clip_bw = 0;
    3951             : 
    3952             : /**
    3953             :  * Generate a routerstatus for clip_unmeasured_bw_kb test; based on the
    3954             :  * v3_networkstatus ones.
    3955             :  */
    3956             : static vote_routerstatus_t *
    3957          30 : gen_routerstatus_for_umbw(int idx, time_t now)
    3958             : {
    3959          30 :   vote_routerstatus_t *vrs = NULL;
    3960          30 :   routerstatus_t *rs;
    3961          30 :   tor_addr_t addr_ipv6;
    3962          60 :   uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
    3963          30 :     alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
    3964             : 
    3965          30 :   switch (idx) {
    3966           6 :     case 0:
    3967             :       /* Generate the first routerstatus. */
    3968           6 :       vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
    3969           6 :       rs = &vrs->status;
    3970           6 :       vrs->version = tor_strdup("0.1.2.14");
    3971           6 :       rs->published_on = now-1500;
    3972           6 :       strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
    3973           6 :       memset(rs->identity_digest, 3, DIGEST_LEN);
    3974           6 :       memset(rs->descriptor_digest, 78, DIGEST_LEN);
    3975           6 :       tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
    3976           6 :       rs->ipv4_orport = 443;
    3977           6 :       rs->ipv4_dirport = 8000;
    3978             :       /* all flags but running and valid cleared */
    3979           6 :       rs->is_flagged_running = 1;
    3980           6 :       rs->is_valid = 1;
    3981             :       /*
    3982             :        * This one has measured bandwidth below the clip cutoff, and
    3983             :        * so shouldn't be clipped; we'll have to test that it isn't
    3984             :        * later.
    3985             :        */
    3986           6 :       vrs->has_measured_bw = 1;
    3987           6 :       rs->has_bandwidth = 1;
    3988           6 :       vrs->measured_bw_kb = rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
    3989           6 :       vrs->protocols = tor_strdup("Link=2 Wombat=40");
    3990           6 :       break;
    3991           6 :     case 1:
    3992             :       /* Generate the second routerstatus. */
    3993           6 :       vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
    3994           6 :       rs = &vrs->status;
    3995           6 :       vrs->version = tor_strdup("0.2.0.5");
    3996           6 :       rs->published_on = now-1000;
    3997           6 :       strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
    3998           6 :       memset(rs->identity_digest, 5, DIGEST_LEN);
    3999           6 :       memset(rs->descriptor_digest, 77, DIGEST_LEN);
    4000           6 :       tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
    4001           6 :       rs->ipv4_orport = 443;
    4002           6 :       rs->ipv4_dirport = 0;
    4003           6 :       tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
    4004           6 :       tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
    4005           6 :       rs->ipv6_orport = 4711;
    4006           6 :       rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
    4007           6 :         rs->is_valid = rs->is_possible_guard = 1;
    4008             :       /*
    4009             :        * This one has measured bandwidth above the clip cutoff, and
    4010             :        * so shouldn't be clipped; we'll have to test that it isn't
    4011             :        * later.
    4012             :        */
    4013           6 :       vrs->has_measured_bw = 1;
    4014           6 :       rs->has_bandwidth = 1;
    4015           6 :       vrs->measured_bw_kb = rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
    4016           6 :       vrs->protocols = tor_strdup("Link=2 Wombat=40");
    4017           6 :       break;
    4018           6 :     case 2:
    4019             :       /* Generate the third routerstatus. */
    4020           6 :       vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
    4021           6 :       rs = &vrs->status;
    4022           6 :       vrs->version = tor_strdup("0.1.0.3");
    4023           6 :       rs->published_on = now-1000;
    4024           6 :       strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
    4025           6 :       memset(rs->identity_digest, 0x33, DIGEST_LEN);
    4026           6 :       memset(rs->descriptor_digest, 79, DIGEST_LEN);
    4027           6 :       tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
    4028           6 :       rs->ipv4_orport = 400;
    4029           6 :       rs->ipv4_dirport = 9999;
    4030           6 :       rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
    4031           6 :         rs->is_flagged_running = rs->is_valid =
    4032           6 :         rs->is_possible_guard = 1;
    4033             :       /*
    4034             :        * This one has unmeasured bandwidth above the clip cutoff, and
    4035             :        * so should be clipped; we'll have to test that it isn't
    4036             :        * later.
    4037             :        */
    4038           6 :       vrs->has_measured_bw = 0;
    4039           6 :       rs->has_bandwidth = 1;
    4040           6 :       vrs->measured_bw_kb = 0;
    4041           6 :       rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
    4042           6 :       vrs->protocols = tor_strdup("Link=2 Wombat=40");
    4043           6 :       break;
    4044           6 :     case 3:
    4045             :       /* Generate a fourth routerstatus that is not running. */
    4046           6 :       vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
    4047           6 :       rs = &vrs->status;
    4048           6 :       vrs->version = tor_strdup("0.1.6.3");
    4049           6 :       rs->published_on = now-1000;
    4050           6 :       strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
    4051           6 :       memset(rs->identity_digest, 0x34, DIGEST_LEN);
    4052           6 :       memset(rs->descriptor_digest, 47, DIGEST_LEN);
    4053           6 :       tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
    4054           6 :       rs->ipv4_orport = 500;
    4055           6 :       rs->ipv4_dirport = 1999;
    4056             :       /* all flags but running and valid cleared */
    4057           6 :       rs->is_flagged_running = 1;
    4058           6 :       rs->is_valid = 1;
    4059             :       /*
    4060             :        * This one has unmeasured bandwidth below the clip cutoff, and
    4061             :        * so shouldn't be clipped; we'll have to test that it isn't
    4062             :        * later.
    4063             :        */
    4064           6 :       vrs->has_measured_bw = 0;
    4065           6 :       rs->has_bandwidth = 1;
    4066           6 :       vrs->measured_bw_kb = 0;
    4067           6 :       rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
    4068           6 :       vrs->protocols = tor_strdup("Link=2 Wombat=40");
    4069           6 :       break;
    4070             :     case 4:
    4071             :       /* No more for this test; return NULL */
    4072             :       vrs = NULL;
    4073             :       break;
    4074           0 :     default:
    4075             :       /* Shouldn't happen */
    4076           0 :       tt_abort();
    4077             :   }
    4078          24 :   if (vrs) {
    4079          24 :     vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
    4080          24 :     tor_asprintf(&vrs->microdesc->microdesc_hash_line,
    4081             :                  "m 25,26,27,28 "
    4082             :                  "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
    4083             :                  idx);
    4084             :   }
    4085             : 
    4086          30 :  done:
    4087          30 :   return vrs;
    4088             : }
    4089             : 
    4090             : /** Apply tweaks to the vote list for each voter; for the umbw test this is
    4091             :  * just adding the right consensus methods to let clipping happen */
    4092             : static int
    4093           6 : vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
    4094             : {
    4095           6 :   char *maxbw_param = NULL;
    4096           6 :   int rv = 0;
    4097             : 
    4098           6 :   tt_assert(v);
    4099           6 :   (void)voter;
    4100           6 :   (void)now;
    4101             : 
    4102           6 :   tt_assert(v->supported_methods);
    4103          30 :   SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
    4104           6 :   smartlist_clear(v->supported_methods);
    4105             :   /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
    4106           6 :   smartlist_split_string(v->supported_methods,
    4107             :                          "25 26 27 28",
    4108             :                          NULL, 0, -1);
    4109             :   /* If we're using a non-default clip bandwidth, add it to net_params */
    4110           6 :   if (alternate_clip_bw > 0) {
    4111           3 :     tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
    4112           3 :     tt_assert(maxbw_param);
    4113           3 :     if (maxbw_param) {
    4114           3 :       smartlist_add(v->net_params, maxbw_param);
    4115           3 :       rv = 1;
    4116             :     }
    4117             :   }
    4118             : 
    4119           3 :  done:
    4120           6 :   return rv;
    4121             : }
    4122             : 
    4123             : /**
    4124             :  * Test a parsed vote_routerstatus_t for umbw test.
    4125             :  */
    4126             : static void
    4127          16 : test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
    4128             : {
    4129          16 :   routerstatus_t *rs;
    4130          16 :   tor_addr_t addr_ipv6;
    4131          32 :   uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
    4132          16 :     alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
    4133             : 
    4134          16 :   (void)voter;
    4135          16 :   tt_assert(vrs);
    4136          16 :   rs = &(vrs->status);
    4137          16 :   tt_assert(rs);
    4138             : 
    4139             :   /* Split out by digests to test */
    4140          16 :   if (tor_memeq(rs->identity_digest,
    4141             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    4142             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
    4143             :                 DIGEST_LEN)) {
    4144             :     /*
    4145             :      * Check the first routerstatus - measured bandwidth below the clip
    4146             :      * cutoff.
    4147             :      */
    4148           4 :     tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
    4149           4 :     tt_int_op(rs->published_on,OP_EQ, now-1500);
    4150           4 :     tt_str_op(rs->nickname,OP_EQ, "router2");
    4151           4 :     tt_mem_op(rs->identity_digest,OP_EQ,
    4152             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    4153             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
    4154           4 :                DIGEST_LEN);
    4155           4 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
    4156           4 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
    4157           4 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    4158           4 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
    4159           4 :     tt_assert(rs->has_bandwidth);
    4160           4 :     tt_assert(vrs->has_measured_bw);
    4161           4 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
    4162           4 :     tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb / 2);
    4163          12 :   } else if (tor_memeq(rs->identity_digest,
    4164             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    4165             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
    4166             :                        DIGEST_LEN)) {
    4167             : 
    4168             :     /*
    4169             :      * Check the second routerstatus - measured bandwidth above the clip
    4170             :      * cutoff.
    4171             :      */
    4172           4 :     tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
    4173           4 :     tt_int_op(rs->published_on,OP_EQ, now-1000);
    4174           4 :     tt_str_op(rs->nickname,OP_EQ, "router1");
    4175           4 :     tt_mem_op(rs->identity_digest,OP_EQ,
    4176             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    4177             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
    4178           4 :                DIGEST_LEN);
    4179           4 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
    4180           4 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
    4181           4 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    4182           4 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
    4183           4 :     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
    4184           4 :     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
    4185           4 :     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
    4186           4 :     tt_assert(rs->has_bandwidth);
    4187           4 :     tt_assert(vrs->has_measured_bw);
    4188           4 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
    4189           4 :     tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb * 2);
    4190           8 :   } else if (tor_memeq(rs->identity_digest,
    4191             :                        "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
    4192             :                        "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
    4193             :                        DIGEST_LEN)) {
    4194             :     /*
    4195             :      * Check the third routerstatus - unmeasured bandwidth above the clip
    4196             :      * cutoff; this one should be clipped later on in the consensus, but
    4197             :      * appears unclipped in the vote.
    4198             :      */
    4199           4 :     tt_assert(rs->has_bandwidth);
    4200           4 :     tt_assert(!(vrs->has_measured_bw));
    4201           4 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
    4202           4 :     tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
    4203           4 :   } else if (tor_memeq(rs->identity_digest,
    4204             :                        "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
    4205             :                        "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
    4206             :                        DIGEST_LEN)) {
    4207             :     /*
    4208             :      * Check the fourth routerstatus - unmeasured bandwidth below the clip
    4209             :      * cutoff; this one should not be clipped.
    4210             :      */
    4211           4 :     tt_assert(rs->has_bandwidth);
    4212           4 :     tt_assert(!(vrs->has_measured_bw));
    4213           4 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
    4214           4 :     tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
    4215             :   } else {
    4216           0 :     tt_abort();
    4217             :   }
    4218             : 
    4219          16 :  done:
    4220          16 :   return;
    4221             : }
    4222             : 
    4223             : /**
    4224             :  * Test a consensus for v3_networkstatus_test
    4225             :  */
    4226             : static void
    4227           2 : test_consensus_for_umbw(networkstatus_t *con, time_t now)
    4228             : {
    4229           2 :   (void)now;
    4230             : 
    4231           2 :   tt_assert(con);
    4232           2 :   tt_ptr_op(con->cert, OP_EQ, NULL);
    4233             :   // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
    4234           2 :   tt_int_op(con->consensus_method, OP_GE, 16);
    4235           2 :   tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list));
    4236             :   /* There should be four listed routers; all voters saw the same in this */
    4237             : 
    4238           2 :  done:
    4239           2 :   return;
    4240             : }
    4241             : 
    4242             : /**
    4243             :  * Test a router list entry for umbw test
    4244             :  */
    4245             : static void
    4246           8 : test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
    4247             : {
    4248           8 :   tor_addr_t addr_ipv6;
    4249          16 :   uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
    4250           8 :     alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
    4251             : 
    4252           8 :   tt_assert(rs);
    4253             : 
    4254             :   /* There should be four listed routers, as constructed above */
    4255           8 :   if (tor_memeq(rs->identity_digest,
    4256             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    4257             :                 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
    4258             :                 DIGEST_LEN)) {
    4259           2 :     tt_mem_op(rs->identity_digest,OP_EQ,
    4260             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
    4261             :                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
    4262           2 :                DIGEST_LEN);
    4263           2 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
    4264           2 :     tt_assert(!rs->is_authority);
    4265           2 :     tt_assert(!rs->is_exit);
    4266           2 :     tt_assert(!rs->is_fast);
    4267           2 :     tt_assert(!rs->is_possible_guard);
    4268           2 :     tt_assert(!rs->is_stable);
    4269             :     /* (If it wasn't running and valid it wouldn't be here) */
    4270           2 :     tt_assert(rs->is_flagged_running);
    4271           2 :     tt_assert(rs->is_valid);
    4272           2 :     tt_assert(!rs->is_named);
    4273             :     /* This one should have measured bandwidth below the clip cutoff */
    4274           2 :     tt_assert(rs->has_bandwidth);
    4275           2 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
    4276           2 :     tt_assert(!(rs->bw_is_unmeasured));
    4277           6 :   } else if (tor_memeq(rs->identity_digest,
    4278             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    4279             :                        "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
    4280             :                        DIGEST_LEN)) {
    4281             :     /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'.  */
    4282           2 :     tt_mem_op(rs->identity_digest,OP_EQ,
    4283             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
    4284             :                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
    4285           2 :                DIGEST_LEN);
    4286           2 :     tt_str_op(rs->nickname,OP_EQ, "router1");
    4287           2 :     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
    4288           2 :     tt_int_op(rs->published_on,OP_EQ, now-1000);
    4289           2 :     tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
    4290           2 :     tt_int_op(rs->ipv4_orport,OP_EQ, 443);
    4291           2 :     tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
    4292           2 :     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
    4293           2 :     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
    4294           2 :     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
    4295           2 :     tt_assert(!rs->is_authority);
    4296           2 :     tt_assert(rs->is_exit);
    4297           2 :     tt_assert(rs->is_fast);
    4298           2 :     tt_assert(rs->is_possible_guard);
    4299           2 :     tt_assert(rs->is_stable);
    4300           2 :     tt_assert(rs->is_flagged_running);
    4301           2 :     tt_assert(rs->is_valid);
    4302           2 :     tt_assert(!rs->is_named);
    4303             :     /* This one should have measured bandwidth above the clip cutoff */
    4304           2 :     tt_assert(rs->has_bandwidth);
    4305           2 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
    4306           2 :     tt_assert(!(rs->bw_is_unmeasured));
    4307           4 :   } else if (tor_memeq(rs->identity_digest,
    4308             :                 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
    4309             :                 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
    4310             :                 DIGEST_LEN)) {
    4311             :     /*
    4312             :      * This one should have unmeasured bandwidth above the clip cutoff,
    4313             :      * and so should be clipped
    4314             :      */
    4315           2 :     tt_assert(rs->has_bandwidth);
    4316           2 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb);
    4317           2 :     tt_assert(rs->bw_is_unmeasured);
    4318           2 :   } else if (tor_memeq(rs->identity_digest,
    4319             :                 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
    4320             :                 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
    4321             :                 DIGEST_LEN)) {
    4322             :     /*
    4323             :      * This one should have unmeasured bandwidth below the clip cutoff,
    4324             :      * and so should not be clipped
    4325             :      */
    4326           2 :     tt_assert(rs->has_bandwidth);
    4327           2 :     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
    4328           2 :     tt_assert(rs->bw_is_unmeasured);
    4329             :   } else {
    4330             :     /* Weren't expecting this... */
    4331           0 :     tt_abort();
    4332             :   }
    4333             : 
    4334           8 :  done:
    4335           8 :   return;
    4336             : }
    4337             : 
    4338             : /**
    4339             :  * Compute a consensus involving clipping unmeasured bandwidth with consensus
    4340             :  * method 17; this uses the same test_a_networkstatus() function that the
    4341             :  * v3_networkstatus test uses.
    4342             :  */
    4343             : 
    4344             : static void
    4345           1 : test_dir_clip_unmeasured_bw_kb(void *arg)
    4346             : {
    4347             :   /* Run the test with the default clip bandwidth */
    4348           1 :   (void)arg;
    4349           1 :   alternate_clip_bw = 0;
    4350           1 :   test_a_networkstatus(gen_routerstatus_for_umbw,
    4351             :                        vote_tweaks_for_umbw,
    4352             :                        test_vrs_for_umbw,
    4353             :                        test_consensus_for_umbw,
    4354             :                        test_routerstatus_for_umbw);
    4355           1 : }
    4356             : 
    4357             : /**
    4358             :  * This version of test_dir_clip_unmeasured_bw_kb() uses a non-default choice
    4359             :  * of clip bandwidth.
    4360             :  */
    4361             : 
    4362             : static void
    4363           1 : test_dir_clip_unmeasured_bw_kb_alt(void *arg)
    4364             : {
    4365             :   /*
    4366             :    * Try a different one; this value is chosen so that the below-the-cutoff
    4367             :    * unmeasured nodes the test uses, at alternate_clip_bw / 2, will be above
    4368             :    * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
    4369             :    * cutoff it will fail the test.
    4370             :    */
    4371           1 :   (void)arg;
    4372           1 :   alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
    4373           1 :   test_a_networkstatus(gen_routerstatus_for_umbw,
    4374             :                        vote_tweaks_for_umbw,
    4375             :                        test_vrs_for_umbw,
    4376             :                        test_consensus_for_umbw,
    4377             :                        test_routerstatus_for_umbw);
    4378           1 : }
    4379             : 
    4380             : static void
    4381           1 : test_dir_fmt_control_ns(void *arg)
    4382             : {
    4383           1 :   char *s = NULL;
    4384           1 :   routerstatus_t rs;
    4385           1 :   (void)arg;
    4386             : 
    4387           1 :   memset(&rs, 0, sizeof(rs));
    4388           1 :   rs.published_on = 1364925198;
    4389           1 :   strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
    4390           1 :   memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
    4391           1 :   memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
    4392           1 :   tor_addr_from_ipv4h(&rs.ipv4_addr, 0x20304050);
    4393           1 :   rs.ipv4_orport = 9001;
    4394           1 :   rs.ipv4_dirport = 9002;
    4395           1 :   rs.is_exit = 1;
    4396           1 :   rs.is_fast = 1;
    4397           1 :   rs.is_flagged_running = 1;
    4398           1 :   rs.has_bandwidth = 1;
    4399           1 :   rs.is_v2_dir = 1;
    4400           1 :   rs.bandwidth_kb = 1000;
    4401             : 
    4402           1 :   s = networkstatus_getinfo_helper_single(&rs);
    4403           1 :   tt_assert(s);
    4404           1 :   tt_str_op(s, OP_EQ,
    4405             :             "r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
    4406             :                "TXVsbGlnYW4gY2FtZSB1cCBmcm8 2013-04-02 17:53:18 "
    4407             :                "32.48.64.80 9001 9002\n"
    4408             :             "s Exit Fast Running V2Dir\n"
    4409             :             "w Bandwidth=1000\n");
    4410             : 
    4411           1 :  done:
    4412           1 :   tor_free(s);
    4413           1 : }
    4414             : 
    4415             : static int mock_get_options_calls = 0;
    4416             : static or_options_t *mock_options = NULL;
    4417             : 
    4418             : static void
    4419          18 : reset_options(or_options_t *options, int *get_options_calls)
    4420             : {
    4421          18 :   memset(options, 0, sizeof(or_options_t));
    4422          18 :   options->TestingTorNetwork = 1;
    4423             : 
    4424          18 :   *get_options_calls = 0;
    4425          18 : }
    4426             : 
    4427             : static const or_options_t *
    4428          91 : mock_get_options(void)
    4429             : {
    4430          91 :   ++mock_get_options_calls;
    4431          91 :   tor_assert(mock_options);
    4432          91 :   return mock_options;
    4433             : }
    4434             : 
    4435             : /**
    4436             :  * Test dirauth_get_b64_digest_bw_file.
    4437             :  * This function should be near the other bwauth functions, but it needs
    4438             :  * mock_get_options, that is only defined here.
    4439             :  */
    4440             : 
    4441             : static void
    4442           1 : test_dir_bwauth_bw_file_digest256(void *arg)
    4443             : {
    4444           1 :   (void)arg;
    4445           1 :   const char *content =
    4446             :     "1541171221\n"
    4447             :     "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
    4448             :     "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
    4449             :     "bw=760 nick=Test time=2018-05-08T16:13:26\n";
    4450             : 
    4451           1 :   char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
    4452             :   /* Initialize to a wrong digest. */
    4453           1 :   uint8_t digest[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
    4454             : 
    4455             :   /* Digest of an empty string. Initialize to a wrong digest. */
    4456           1 :   char digest_empty_str[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
    4457           1 :   crypto_digest256(digest_empty_str, "", 0, DIGEST_SHA256);
    4458             : 
    4459             :   /* Digest of the content. Initialize to a wrong digest. */
    4460           1 :   char digest_expected[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
    4461           1 :   crypto_digest256(digest_expected, content, strlen(content), DIGEST_SHA256);
    4462             : 
    4463             :   /* When the bandwidth file can not be found. */
    4464           1 :   tt_int_op(-1, OP_EQ,
    4465             :             dirserv_read_measured_bandwidths(fname,
    4466             :                                              NULL, NULL, digest));
    4467           1 :   tt_mem_op(digest, OP_EQ, digest_empty_str, DIGEST256_LEN);
    4468             : 
    4469             :   /* When there is a timestamp but it is too old. */
    4470           1 :   write_str_to_file(fname, content, 0);
    4471           1 :   tt_int_op(-1, OP_EQ,
    4472             :             dirserv_read_measured_bandwidths(fname,
    4473             :                                              NULL, NULL, digest));
    4474             :   /* The digest will be correct. */
    4475           1 :   tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
    4476             : 
    4477           1 :   update_approx_time(1541171221);
    4478             : 
    4479             :   /* When there is a bandwidth file and it can be read. */
    4480           1 :   tt_int_op(0, OP_EQ,
    4481             :             dirserv_read_measured_bandwidths(fname,
    4482             :                                              NULL, NULL, digest));
    4483           1 :   tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
    4484             : 
    4485           1 :  done:
    4486           1 :   unlink(fname);
    4487           1 :   tor_free(fname);
    4488           1 :   update_approx_time(time(NULL));
    4489           1 : }
    4490             : 
    4491             : static void
    4492          13 : reset_routerstatus(routerstatus_t *rs,
    4493             :                    const char *hex_identity_digest,
    4494             :                    uint32_t ipv4_addr)
    4495             : {
    4496          13 :   memset(rs, 0, sizeof(routerstatus_t));
    4497          13 :   base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
    4498             :                 hex_identity_digest, HEX_DIGEST_LEN);
    4499             :   /* A zero address matches everything, so the address needs to be set.
    4500             :    * But the specific value is irrelevant. */
    4501          13 :   tor_addr_from_ipv4h(&rs->ipv4_addr, ipv4_addr);
    4502          13 : }
    4503             : 
    4504             : #define ROUTER_A_ID_STR    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
    4505             : #define ROUTER_A_IPV4      0xAA008801
    4506             : #define ROUTER_B_ID_STR    "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
    4507             : #define ROUTER_B_IPV4      0xBB008801
    4508             : 
    4509             : #define ROUTERSET_ALL_STR  "*"
    4510             : #define ROUTERSET_A_STR    ROUTER_A_ID_STR
    4511             : #define ROUTERSET_NONE_STR ""
    4512             : 
    4513             : /*
    4514             :  * Test that dirserv_set_routerstatus_testing sets router flags correctly
    4515             :  * Using "*"  sets flags on A and B
    4516             :  * Using "A"  sets flags on A
    4517             :  * Using ""   sets flags on Neither
    4518             :  * If the router is not included:
    4519             :  *   - if *Strict is set, the flag is set to 0,
    4520             :  *   - otherwise, the flag is not modified. */
    4521             : static void
    4522           1 : test_dir_dirserv_set_routerstatus_testing(void *arg)
    4523             : {
    4524           1 :   (void)arg;
    4525             : 
    4526             :   /* Init options */
    4527           2 :   dirauth_options_t *dirauth_options =
    4528           1 :     tor_malloc_zero(sizeof(dirauth_options_t));
    4529             : 
    4530           1 :   mock_options = tor_malloc(sizeof(or_options_t));
    4531           1 :   reset_options(mock_options, &mock_get_options_calls);
    4532           1 :   MOCK(get_options, mock_get_options);
    4533           1 :   dirauth_set_options(dirauth_options);
    4534             : 
    4535             :   /* Init routersets */
    4536           1 :   routerset_t *routerset_all  = routerset_new();
    4537           1 :   routerset_parse(routerset_all,  ROUTERSET_ALL_STR,  "All routers");
    4538             : 
    4539           1 :   routerset_t *routerset_a    = routerset_new();
    4540           1 :   routerset_parse(routerset_a,    ROUTERSET_A_STR,    "Router A only");
    4541             : 
    4542           1 :   routerset_t *routerset_none = routerset_new();
    4543             :   /* Routersets are empty when provided by routerset_new(),
    4544             :    * so this is not strictly necessary */
    4545           1 :   routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
    4546             : 
    4547             :   /* Init routerstatuses */
    4548           1 :   routerstatus_t *rs_a = tor_malloc(sizeof(routerstatus_t));
    4549           1 :   reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
    4550             : 
    4551           1 :   routerstatus_t *rs_b = tor_malloc(sizeof(routerstatus_t));
    4552           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4553             : 
    4554             :   /* Sanity check that routersets correspond to routerstatuses.
    4555             :    * Return values are {2, 3, 4} */
    4556             : 
    4557             :   /* We want 3 ("*" means match all addresses) */
    4558           1 :   tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3);
    4559           1 :   tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3);
    4560             : 
    4561             :   /* We want 4 (match id_digest [or nickname]) */
    4562           1 :   tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4);
    4563           1 :   tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0);
    4564             : 
    4565           1 :   tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ,
    4566             :             0);
    4567           1 :   tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ,
    4568             :             0);
    4569             : 
    4570             :   /* Check that "*" sets flags on all routers: Exit
    4571             :    * Check the flags aren't being confused with each other */
    4572           1 :   reset_options(mock_options, &mock_get_options_calls);
    4573           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4574           1 :   reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
    4575           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4576             : 
    4577           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_all;
    4578           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
    4579             : 
    4580           1 :   dirserv_set_routerstatus_testing(rs_a);
    4581           1 :   dirserv_set_routerstatus_testing(rs_b);
    4582             : 
    4583           1 :   tt_uint_op(rs_a->is_exit, OP_EQ, 1);
    4584           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 1);
    4585             :   /* Be paranoid - check no other flags are set */
    4586           1 :   tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
    4587           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
    4588           1 :   tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
    4589           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
    4590             : 
    4591             :   /* Check that "*" sets flags on all routers: Guard & HSDir
    4592             :    * Cover the remaining flags in one test */
    4593           1 :   reset_options(mock_options, &mock_get_options_calls);
    4594           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4595           1 :   reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
    4596           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4597             : 
    4598           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_all;
    4599           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
    4600           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_all;
    4601           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
    4602             : 
    4603           1 :   dirserv_set_routerstatus_testing(rs_a);
    4604           1 :   dirserv_set_routerstatus_testing(rs_b);
    4605             : 
    4606           1 :   tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
    4607           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
    4608           1 :   tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
    4609           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
    4610             :   /* Be paranoid - check exit isn't set */
    4611           1 :   tt_uint_op(rs_a->is_exit, OP_EQ, 0);
    4612           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 0);
    4613             : 
    4614             :   /* Check routerset A sets all flags on router A,
    4615             :    * but leaves router B unmodified */
    4616           1 :   reset_options(mock_options, &mock_get_options_calls);
    4617           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4618           1 :   reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
    4619           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4620             : 
    4621           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_a;
    4622           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
    4623           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_a;
    4624           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
    4625           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
    4626           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
    4627             : 
    4628           1 :   dirserv_set_routerstatus_testing(rs_a);
    4629           1 :   dirserv_set_routerstatus_testing(rs_b);
    4630             : 
    4631           1 :   tt_uint_op(rs_a->is_exit, OP_EQ, 1);
    4632           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 0);
    4633           1 :   tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
    4634           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
    4635           1 :   tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
    4636           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
    4637             : 
    4638             :   /* Check routerset A unsets all flags on router B when Strict is set */
    4639           1 :   reset_options(mock_options, &mock_get_options_calls);
    4640           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4641           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4642             : 
    4643           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_a;
    4644           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
    4645           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_a;
    4646           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
    4647           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
    4648           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
    4649             : 
    4650           1 :   rs_b->is_exit = 1;
    4651           1 :   rs_b->is_possible_guard = 1;
    4652           1 :   rs_b->is_hs_dir = 1;
    4653             : 
    4654           1 :   dirserv_set_routerstatus_testing(rs_b);
    4655             : 
    4656           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 0);
    4657           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
    4658           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
    4659             : 
    4660             :   /* Check routerset A doesn't modify flags on router B without Strict set */
    4661           1 :   reset_options(mock_options, &mock_get_options_calls);
    4662           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4663           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4664             : 
    4665           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_a;
    4666           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
    4667           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_a;
    4668           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
    4669           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
    4670           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
    4671             : 
    4672           1 :   rs_b->is_exit = 1;
    4673           1 :   rs_b->is_possible_guard = 1;
    4674           1 :   rs_b->is_hs_dir = 1;
    4675             : 
    4676           1 :   dirserv_set_routerstatus_testing(rs_b);
    4677             : 
    4678           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 1);
    4679           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
    4680           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
    4681             : 
    4682             :   /* Check the empty routerset zeroes all flags
    4683             :    * on routers A & B with Strict set */
    4684           1 :   reset_options(mock_options, &mock_get_options_calls);
    4685           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4686           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4687             : 
    4688           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_none;
    4689           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
    4690           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_none;
    4691           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
    4692           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
    4693           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
    4694             : 
    4695           1 :   rs_b->is_exit = 1;
    4696           1 :   rs_b->is_possible_guard = 1;
    4697           1 :   rs_b->is_hs_dir = 1;
    4698             : 
    4699           1 :   dirserv_set_routerstatus_testing(rs_b);
    4700             : 
    4701           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 0);
    4702           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
    4703           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
    4704             : 
    4705             :   /* Check the empty routerset doesn't modify any flags
    4706             :    * on A or B without Strict set */
    4707           1 :   reset_options(mock_options, &mock_get_options_calls);
    4708           1 :   memset(dirauth_options, 0, sizeof(*dirauth_options));
    4709           1 :   reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
    4710           1 :   reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
    4711             : 
    4712           1 :   dirauth_options->TestingDirAuthVoteExit = routerset_none;
    4713           1 :   dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
    4714           1 :   dirauth_options->TestingDirAuthVoteGuard = routerset_none;
    4715           1 :   dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
    4716           1 :   dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
    4717           1 :   dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
    4718             : 
    4719           1 :   rs_b->is_exit = 1;
    4720           1 :   rs_b->is_possible_guard = 1;
    4721           1 :   rs_b->is_hs_dir = 1;
    4722             : 
    4723           1 :   dirserv_set_routerstatus_testing(rs_a);
    4724           1 :   dirserv_set_routerstatus_testing(rs_b);
    4725             : 
    4726           1 :   tt_uint_op(rs_a->is_exit, OP_EQ, 0);
    4727           1 :   tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
    4728           1 :   tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
    4729           1 :   tt_uint_op(rs_b->is_exit, OP_EQ, 1);
    4730           1 :   tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
    4731           1 :   tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
    4732             : 
    4733           1 :  done:
    4734           1 :   tor_free(mock_options);
    4735           1 :   tor_free(dirauth_options);
    4736           1 :   mock_options = NULL;
    4737             : 
    4738           1 :   UNMOCK(get_options);
    4739             : 
    4740           1 :   routerset_free(routerset_all);
    4741           1 :   routerset_free(routerset_a);
    4742           1 :   routerset_free(routerset_none);
    4743             : 
    4744           1 :   tor_free(rs_a);
    4745           1 :   tor_free(rs_b);
    4746           1 : }
    4747             : 
    4748             : static void
    4749           1 : test_dir_http_handling(void *args)
    4750             : {
    4751           1 :   char *url = NULL;
    4752           1 :   (void)args;
    4753             : 
    4754             :   /* Parse http url tests: */
    4755             :   /* Good headers */
    4756           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
    4757             :                            "Host: example.com\r\n"
    4758             :                            "User-Agent: Mozilla/5.0 (Windows;"
    4759             :                            " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
    4760             :                            &url),OP_EQ, 0);
    4761           1 :   tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
    4762           1 :   tor_free(url);
    4763             : 
    4764           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),OP_EQ, 0);
    4765           1 :   tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
    4766           1 :   tor_free(url);
    4767             : 
    4768           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),
    4769             :             OP_EQ, 0);
    4770           1 :   tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
    4771           1 :   tor_free(url);
    4772             : 
    4773             :   /* Should prepend '/tor/' to url if required */
    4774           1 :   tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
    4775             :                            "Host: example.com\r\n"
    4776             :                            "User-Agent: Mozilla/5.0 (Windows;"
    4777             :                            " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
    4778             :                            &url),OP_EQ, 0);
    4779           1 :   tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
    4780           1 :   tor_free(url);
    4781             : 
    4782             :   /* Bad headers -- no HTTP/1.x*/
    4783           1 :   tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
    4784             :                            "Host: example.com\r\n"
    4785             :                            "User-Agent: Mozilla/5.0 (Windows;"
    4786             :                            " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
    4787             :                            &url),OP_EQ, -1);
    4788           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4789             : 
    4790             :   /* Bad headers */
    4791           1 :   tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
    4792             :                            "Host: example.com\r\n"
    4793             :                            "User-Agent: Mozilla/5.0 (Windows;"
    4794             :                            " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
    4795             :                            &url),OP_EQ, -1);
    4796           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4797             : 
    4798           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1);
    4799           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4800             : 
    4801           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1);
    4802           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4803             : 
    4804           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),
    4805             :             OP_EQ, -1);
    4806           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4807             : 
    4808           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1);
    4809           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4810             : 
    4811           1 :   tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1);
    4812           1 :   tt_ptr_op(url, OP_EQ, NULL);
    4813             : 
    4814           1 :  done:
    4815           1 :   tor_free(url);
    4816           1 : }
    4817             : 
    4818             : static void
    4819           1 : test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
    4820             : {
    4821           1 :   (void)arg;
    4822             : 
    4823             : #ifdef ALL_BUGS_ARE_FATAL
    4824             :   /* Coverity (and maybe clang analyser) complain that the code following
    4825             :    * tt_skip() is unconditionally unreachable. */
    4826             : #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
    4827             :   tt_skip();
    4828             : #endif
    4829             : #endif /* defined(ALL_BUGS_ARE_FATAL) */
    4830             : 
    4831           1 :   tor_capture_bugs_(1);
    4832           1 :   setup_full_capture_of_logs(LOG_WARN);
    4833           1 :   tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
    4834           1 :   tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
    4835           1 :   expect_single_log_msg_containing("Called with dir_purpose=0");
    4836             : 
    4837           1 :   tor_end_capture_bugs_();
    4838           1 :  done:
    4839           1 :   tor_end_capture_bugs_();
    4840           1 :   teardown_capture_of_logs();
    4841           1 : }
    4842             : 
    4843             : static void
    4844           1 : test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
    4845             : {
    4846           1 :   (void)arg;
    4847             : 
    4848           1 :   tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
    4849           1 :   tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
    4850             :                                            "foobar"));
    4851           1 :  done: ;
    4852           1 : }
    4853             : 
    4854             : static void
    4855           1 : test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
    4856             : {
    4857           1 :   (void)arg;
    4858           1 :   tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
    4859             :                                            ROUTER_PURPOSE_BRIDGE,
    4860             :                                            "authority.z"));
    4861           1 :  done: ;
    4862           1 : }
    4863             : 
    4864             : static void
    4865           1 : test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
    4866             : {
    4867           1 :   (void)arg;
    4868             : 
    4869           1 :   tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
    4870             :                                            ROUTER_PURPOSE_GENERAL, NULL));
    4871           1 :   tt_int_op(0, OP_EQ,
    4872             :             purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
    4873           1 :   tt_int_op(0, OP_EQ,
    4874             :             purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
    4875           1 :   tt_int_op(0, OP_EQ,
    4876             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
    4877           1 :   tt_int_op(0, OP_EQ, purpose_needs_anonymity(
    4878             :                     DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
    4879           1 :   tt_int_op(0, OP_EQ,
    4880             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
    4881           1 :   tt_int_op(0, OP_EQ,
    4882             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
    4883           1 :   tt_int_op(0, OP_EQ,
    4884             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
    4885           1 :   tt_int_op(0, OP_EQ,
    4886             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
    4887           1 :   tt_int_op(0, OP_EQ,
    4888             :             purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
    4889           1 :   done: ;
    4890           1 : }
    4891             : 
    4892             : static void
    4893           1 : test_dir_fetch_type(void *arg)
    4894             : {
    4895           1 :   (void)arg;
    4896             : 
    4897           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
    4898             :                            NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
    4899           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
    4900             :                            NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
    4901             : 
    4902           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
    4903             :                            NULL), OP_EQ, BRIDGE_DIRINFO);
    4904           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
    4905             :                            ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
    4906             : 
    4907           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
    4908             :                            ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
    4909           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
    4910             :                            ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
    4911           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
    4912             :                            ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
    4913             : 
    4914           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
    4915             :                            "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
    4916           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
    4917             :                            NULL), OP_EQ, V3_DIRINFO);
    4918             : 
    4919           1 :   tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
    4920             :                            NULL), OP_EQ, MICRODESC_DIRINFO);
    4921             : 
    4922           1 :  done:
    4923           1 :   teardown_capture_of_logs();
    4924           1 : }
    4925             : 
    4926             : static void
    4927           1 : test_dir_packages(void *arg)
    4928             : {
    4929           1 :   smartlist_t *votes = smartlist_new();
    4930           1 :   char *res = NULL;
    4931           1 :   (void)arg;
    4932             : 
    4933             : #define BAD(s) \
    4934             :   tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
    4935             : #define GOOD(s) \
    4936             :   tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
    4937           1 :   GOOD("tor 0.2.6.3-alpha "
    4938             :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
    4939           1 :        "sha256=sssdlkfjdsklfjdskfljasdklfj");
    4940           1 :   GOOD("tor 0.2.6.3-alpha "
    4941             :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
    4942           1 :        "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
    4943           1 :   BAD("tor 0.2.6.3-alpha "
    4944             :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
    4945           1 :        "sha256=sssdlkfjdsklfjdskfljasdklfj=");
    4946           1 :   BAD("tor 0.2.6.3-alpha "
    4947             :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
    4948           1 :        "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
    4949           1 :   BAD("tor 0.2.6.3-alpha "
    4950           1 :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
    4951           1 :   BAD("tor 0.2.6.3-alpha "
    4952           1 :        "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
    4953           1 :   BAD("tor 0.2.6.3-alpha ");
    4954           1 :   BAD("tor 0.2.6.3-alpha");
    4955           1 :   BAD("tor ");
    4956           1 :   BAD("tor");
    4957           1 :   BAD("");
    4958           1 :   BAD("=foobar sha256="
    4959           1 :       "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
    4960           1 :   BAD("= = sha256="
    4961           1 :       "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
    4962             : 
    4963           1 :   BAD("sha512= sha256="
    4964           1 :       "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
    4965             : 
    4966           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4967           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4968           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4969           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4970           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4971           1 :   smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
    4972           7 :   SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
    4973             :                     ns->package_lines = smartlist_new());
    4974             : 
    4975             : #define ADD(i, s)                                                       \
    4976             :   smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
    4977             :                 (void*)(s));
    4978             : 
    4979             :   /* Only one vote for this one. */
    4980           1 :   ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
    4981             : 
    4982             :   /* Only two matching entries for this one, but 3 voters */
    4983           1 :   ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
    4984           1 :   ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
    4985           1 :   ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
    4986             : 
    4987             :   /* Only two matching entries for this one, but at least 4 voters */
    4988           1 :   ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
    4989           1 :   ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
    4990           1 :   ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
    4991           1 :   ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
    4992             : 
    4993             :   /* This one has only invalid votes. */
    4994           1 :   ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
    4995           1 :   ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
    4996           1 :   ADD(2, "haffenreffer 1.2 ");
    4997           1 :   ADD(3, "haffenreffer ");
    4998           1 :   ADD(4, "haffenreffer");
    4999             : 
    5000             :   /* Three matching votes for this; it should actually go in! */
    5001           1 :   ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
    5002           1 :   ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
    5003           1 :   ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
    5004           1 :   ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
    5005           1 :   ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
    5006             : 
    5007             :   /* Three votes for A, three votes for B */
    5008           1 :   ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
    5009           1 :   ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
    5010           1 :   ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
    5011           1 :   ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
    5012           1 :   ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
    5013           1 :   ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
    5014             : 
    5015             :   /* Three votes for A, two votes for B */
    5016           1 :   ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
    5017           1 :   ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
    5018           1 :   ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
    5019           1 :   ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
    5020           1 :   ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
    5021             : 
    5022             :   /* Four votes for A, two for B. */
    5023           1 :   ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
    5024           1 :   ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
    5025           1 :   ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
    5026           1 :   ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
    5027           1 :   ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
    5028           1 :   ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
    5029             : 
    5030             :   /* Five votes for A ... all from the same authority.  Three for B. */
    5031           1 :   ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5032           1 :   ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5033           1 :   ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5034           1 :   ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
    5035           1 :   ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
    5036           1 :   ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
    5037           1 :   ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
    5038           1 :   ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
    5039             : 
    5040             :   /* As above but new replaces old: no two match. */
    5041           1 :   ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5042           1 :   ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5043           1 :   ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
    5044           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
    5045           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
    5046           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
    5047           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
    5048           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
    5049           1 :   ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
    5050             : 
    5051           1 :   res = compute_consensus_package_lines(votes);
    5052           1 :   tt_assert(res);
    5053           1 :   tt_str_op(res, OP_EQ,
    5054             :     "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
    5055             :     "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
    5056             :     "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
    5057             :     "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
    5058             :     "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
    5059             :             );
    5060             : 
    5061             : #undef ADD
    5062             : #undef BAD
    5063             : #undef GOOD
    5064           1 :  done:
    5065           7 :   SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
    5066             :                     { smartlist_free(ns->package_lines); tor_free(ns); });
    5067           1 :   smartlist_free(votes);
    5068           1 :   tor_free(res);
    5069           1 : }
    5070             : 
    5071             : static void
    5072           4 : download_status_random_backoff_helper(int min_delay)
    5073             : {
    5074           4 :   download_status_t dls_random =
    5075             :     { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
    5076             :                DL_SCHED_INCREMENT_FAILURE, 0, 0 };
    5077           4 :   int increment = -1;
    5078           4 :   int old_increment = -1;
    5079           4 :   time_t current_time = time(NULL);
    5080             : 
    5081             :   /* Check the random backoff cases */
    5082           4 :   int n_attempts = 0;
    5083        4000 :   do {
    5084        4000 :     increment = download_status_schedule_get_delay(&dls_random,
    5085             :                                                    min_delay,
    5086             :                                                    current_time);
    5087             : 
    5088        4000 :     log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
    5089             :               min_delay, increment, old_increment);
    5090             : 
    5091             :     /* Regression test for 20534 and friends
    5092             :      * increment must always increase after the first */
    5093        4000 :     if (dls_random.last_backoff_position > 0) {
    5094             :       /* Always increment the exponential backoff */
    5095        3996 :       tt_int_op(increment, OP_GE, 1);
    5096             :     }
    5097             : 
    5098             :     /* Test */
    5099        4000 :     tt_int_op(increment, OP_GE, min_delay);
    5100             : 
    5101             :     /* Advance */
    5102        4000 :     if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
    5103        1016 :       ++(dls_random.n_download_attempts);
    5104        1016 :       ++(dls_random.n_download_failures);
    5105             :     }
    5106             : 
    5107             :     /* Try another maybe */
    5108        4000 :     old_increment = increment;
    5109        4000 :   } while (++n_attempts < 1000);
    5110             : 
    5111           4 :  done:
    5112           4 :   return;
    5113             : }
    5114             : 
    5115             : static void
    5116           1 : test_dir_download_status_random_backoff(void *arg)
    5117             : {
    5118           1 :   (void)arg;
    5119             : 
    5120             :   /* Do a standard test */
    5121           1 :   download_status_random_backoff_helper(0);
    5122             :   /* regression tests for 17750: initial delay */
    5123           1 :   download_status_random_backoff_helper(10);
    5124           1 :   download_status_random_backoff_helper(20);
    5125             : 
    5126             :   /* Pathological cases */
    5127           1 :   download_status_random_backoff_helper(INT_MAX/2);
    5128           1 : }
    5129             : 
    5130             : static void
    5131           1 : test_dir_download_status_random_backoff_ranges(void *arg)
    5132             : {
    5133           1 :   (void)arg;
    5134           1 :   int lo, hi;
    5135           1 :   next_random_exponential_delay_range(&lo, &hi, 0, 10);
    5136           1 :   tt_int_op(lo, OP_EQ, 10);
    5137           1 :   tt_int_op(hi, OP_EQ, 11);
    5138             : 
    5139           1 :   next_random_exponential_delay_range(&lo, &hi, 6, 10);
    5140           1 :   tt_int_op(lo, OP_EQ, 10);
    5141           1 :   tt_int_op(hi, OP_EQ, 6*3);
    5142             : 
    5143           1 :   next_random_exponential_delay_range(&lo, &hi, 13, 10);
    5144           1 :   tt_int_op(lo, OP_EQ, 10);
    5145           1 :   tt_int_op(hi, OP_EQ, 13 * 3);
    5146             : 
    5147           1 :   next_random_exponential_delay_range(&lo, &hi, 37, 10);
    5148           1 :   tt_int_op(lo, OP_EQ, 10);
    5149           1 :   tt_int_op(hi, OP_EQ, 111);
    5150             : 
    5151           1 :   next_random_exponential_delay_range(&lo, &hi, 123, 10);
    5152           1 :   tt_int_op(lo, OP_EQ, 10);
    5153           1 :   tt_int_op(hi, OP_EQ, 369);
    5154             : 
    5155           1 :   next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
    5156           1 :   tt_int_op(lo, OP_EQ, 10);
    5157           1 :   tt_int_op(hi, OP_EQ, INT_MAX);
    5158           1 :  done:
    5159           1 :   ;
    5160           1 : }
    5161             : 
    5162             : static void
    5163           1 : test_dir_download_status_increment(void *arg)
    5164             : {
    5165           1 :   (void)arg;
    5166           1 :   download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
    5167             :     DL_WANT_ANY_DIRSERVER,
    5168             :     DL_SCHED_INCREMENT_ATTEMPT,
    5169             :     0, 0 };
    5170           1 :   or_options_t test_options;
    5171           1 :   time_t current_time = time(NULL);
    5172             : 
    5173           1 :   const int delay0 = 10;
    5174           1 :   const int no_delay = 0;
    5175           1 :   const int schedule = 10;
    5176           1 :   const int schedule_no_initial_delay = 0;
    5177             : 
    5178             :   /* Put it in the options */
    5179           1 :   mock_options = &test_options;
    5180           1 :   reset_options(mock_options, &mock_get_options_calls);
    5181           1 :   mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
    5182           1 :   mock_options->TestingClientDownloadInitialDelay = schedule;
    5183             : 
    5184           1 :   MOCK(get_options, mock_get_options);
    5185             : 
    5186             :   /* Check that the initial value of the schedule is the first value used,
    5187             :    * whether or not it was reset before being used */
    5188             : 
    5189             :   /* regression test for 17750: no initial delay */
    5190           1 :   mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
    5191           1 :   mock_get_options_calls = 0;
    5192             :   /* we really want to test that it's equal to time(NULL) + delay0, but that's
    5193             :    * an unrealiable test, because time(NULL) might change. */
    5194             : 
    5195             :   /* regression test for 17750: exponential, no initial delay */
    5196           1 :   mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
    5197           1 :   mock_get_options_calls = 0;
    5198             :   /* we really want to test that it's equal to time(NULL) + delay0, but that's
    5199             :    * an unrealiable test, because time(NULL) might change. */
    5200           1 :   tt_assert(download_status_get_next_attempt_at(&dls_exp)
    5201             :             >= current_time + no_delay);
    5202           1 :   tt_assert(download_status_get_next_attempt_at(&dls_exp)
    5203             :             != TIME_MAX);
    5204           1 :   tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
    5205           1 :   tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
    5206           1 :   tt_int_op(mock_get_options_calls, OP_GE, 1);
    5207             : 
    5208             :   /* regression test for 17750: exponential, initial delay */
    5209           1 :   mock_options->TestingClientDownloadInitialDelay = schedule;
    5210           1 :   mock_get_options_calls = 0;
    5211             :   /* we really want to test that it's equal to time(NULL) + delay0, but that's
    5212             :    * an unrealiable test, because time(NULL) might change. */
    5213           1 :   tt_assert(download_status_get_next_attempt_at(&dls_exp)
    5214             :             >= current_time + delay0);
    5215           1 :   tt_assert(download_status_get_next_attempt_at(&dls_exp)
    5216             :             != TIME_MAX);
    5217           1 :   tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
    5218           1 :   tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
    5219           1 :   tt_int_op(mock_get_options_calls, OP_GE, 1);
    5220             : 
    5221           1 :  done:
    5222           1 :   UNMOCK(get_options);
    5223           1 :   mock_options = NULL;
    5224           1 :   mock_get_options_calls = 0;
    5225           1 :   teardown_capture_of_logs();
    5226           1 : }
    5227             : 
    5228             : static void
    5229           1 : test_dir_authdir_type_to_string(void *data)
    5230             : {
    5231           1 :   (void)data;
    5232           1 :   char *res;
    5233             : 
    5234           1 :   tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
    5235             :             "[Not an authority]");
    5236           1 :   tor_free(res);
    5237             : 
    5238           1 :   tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
    5239             :             "[Not an authority]");
    5240           1 :   tor_free(res);
    5241             : 
    5242           1 :   tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
    5243             :             "[Not an authority]");
    5244           1 :   tor_free(res);
    5245             : 
    5246           1 :   tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
    5247           1 :   tor_free(res);
    5248             : 
    5249           1 :   tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
    5250           1 :   tor_free(res);
    5251             : 
    5252           1 :   tt_str_op(res = authdir_type_to_string(
    5253             :             V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
    5254             :             "V3, Bridge");
    5255           1 :   done:
    5256           1 :   tor_free(res);
    5257           1 : }
    5258             : 
    5259             : static void
    5260           1 : test_dir_conn_purpose_to_string(void *data)
    5261             : {
    5262           1 :   (void)data;
    5263             : 
    5264             : #define EXPECT_CONN_PURPOSE(purpose, expected) \
    5265             :   tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
    5266             : 
    5267           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
    5268           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
    5269           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
    5270           1 :                       "consensus signature upload");
    5271           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
    5272           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
    5273           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
    5274           1 :                       "consensus network-status fetch");
    5275           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
    5276           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
    5277           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
    5278           1 :                       "consensus signature fetch");
    5279           1 :   EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
    5280             : 
    5281             :   /* This will give a warning, because there is no purpose 1024. */
    5282           1 :   setup_full_capture_of_logs(LOG_WARN);
    5283           1 :   EXPECT_CONN_PURPOSE(1024, "(unknown)");
    5284           1 :   expect_single_log_msg_containing("Called with unknown purpose 1024");
    5285             : 
    5286           1 :  done:
    5287           1 :   teardown_capture_of_logs();
    5288           1 : }
    5289             : 
    5290             : static int dir_tests_public_server_mode(const or_options_t *options);
    5291             : ATTR_UNUSED static int dir_tests_public_server_mode_called = 0;
    5292             : 
    5293             : static int
    5294           7 : dir_tests_public_server_mode(const or_options_t *options)
    5295             : {
    5296           7 :   (void)options;
    5297             : 
    5298           7 :   if (dir_tests_public_server_mode_called++ == 0) {
    5299           1 :     return 1;
    5300             :   }
    5301             : 
    5302             :   return 0;
    5303             : }
    5304             : 
    5305             : static void
    5306           1 : test_dir_should_use_directory_guards(void *data)
    5307             : {
    5308           1 :   or_options_t *options;
    5309           1 :   char *errmsg = NULL;
    5310           1 :   (void)data;
    5311             : 
    5312           1 :   MOCK(public_server_mode,
    5313             :        dir_tests_public_server_mode);
    5314             : 
    5315           1 :   options = options_new();
    5316           1 :   options_init(options);
    5317             : 
    5318           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5319           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 1);
    5320             : 
    5321           1 :   options->UseEntryGuards = 1;
    5322           1 :   options->DownloadExtraInfo = 0;
    5323           1 :   options->FetchDirInfoEarly = 0;
    5324           1 :   options->FetchDirInfoExtraEarly = 0;
    5325           1 :   options->FetchUselessDescriptors = 0;
    5326           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
    5327           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 2);
    5328             : 
    5329           1 :   options->UseEntryGuards = 0;
    5330           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5331           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 3);
    5332           1 :   options->UseEntryGuards = 1;
    5333             : 
    5334           1 :   options->DownloadExtraInfo = 1;
    5335           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5336           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 4);
    5337           1 :   options->DownloadExtraInfo = 0;
    5338             : 
    5339           1 :   options->FetchDirInfoEarly = 1;
    5340           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5341           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 5);
    5342           1 :   options->FetchDirInfoEarly = 0;
    5343             : 
    5344           1 :   options->FetchDirInfoExtraEarly = 1;
    5345           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5346           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 6);
    5347           1 :   options->FetchDirInfoExtraEarly = 0;
    5348             : 
    5349           1 :   options->FetchUselessDescriptors = 1;
    5350           1 :   tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
    5351           1 :   tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 7);
    5352           1 :   options->FetchUselessDescriptors = 0;
    5353             : 
    5354           1 :   done:
    5355           1 :     UNMOCK(public_server_mode);
    5356           1 :     or_options_free(options);
    5357           1 :     tor_free(errmsg);
    5358           1 : }
    5359             : 
    5360             : static void dir_tests_directory_initiate_request(directory_request_t *req);
    5361             : ATTR_UNUSED static int dir_tests_directory_initiate_request_called = 0;
    5362             : 
    5363             : static void
    5364           1 : test_dir_should_not_init_request_to_ourselves(void *data)
    5365             : {
    5366           1 :   char digest[DIGEST_LEN];
    5367           1 :   dir_server_t *ourself = NULL;
    5368           1 :   crypto_pk_t *key = pk_generate(2);
    5369           1 :   (void) data;
    5370             : 
    5371           1 :   MOCK(directory_initiate_request,
    5372             :        dir_tests_directory_initiate_request);
    5373             : 
    5374           1 :   clear_dir_servers();
    5375           1 :   routerlist_free_all();
    5376             : 
    5377           1 :   set_server_identity_key(key);
    5378           1 :   crypto_pk_get_digest(key, (char*) &digest);
    5379           1 :   ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
    5380             :                                    NULL, digest,
    5381             :                                    NULL, V3_DIRINFO, 1.0);
    5382             : 
    5383           1 :   tt_assert(ourself);
    5384           1 :   dir_server_add(ourself);
    5385             : 
    5386           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
    5387           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
    5388             : 
    5389           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
    5390             :                                      NULL);
    5391             : 
    5392           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
    5393             : 
    5394           1 :   done:
    5395           1 :     UNMOCK(directory_initiate_request);
    5396           1 :     clear_dir_servers();
    5397           1 :     routerlist_free_all();
    5398           1 :     crypto_pk_free(key);
    5399           1 : }
    5400             : 
    5401             : static void
    5402           1 : test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
    5403             : {
    5404           1 :   dir_server_t *ds = NULL;
    5405           1 :   dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
    5406             :                                 | MICRODESC_DIRINFO;
    5407           1 :   (void) data;
    5408             : 
    5409           1 :   MOCK(directory_initiate_request,
    5410             :        dir_tests_directory_initiate_request);
    5411             : 
    5412           1 :   clear_dir_servers();
    5413           1 :   routerlist_free_all();
    5414             : 
    5415           1 :   ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
    5416             :                               "12345678901234567890", NULL, dirinfo_type, 1.0);
    5417           1 :   tt_assert(ds);
    5418           1 :   dir_server_add(ds);
    5419             : 
    5420           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
    5421           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
    5422             : 
    5423           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
    5424             :                                      NULL);
    5425           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
    5426             : 
    5427           1 :   done:
    5428           1 :     UNMOCK(directory_initiate_request);
    5429           1 :     clear_dir_servers();
    5430           1 :     routerlist_free_all();
    5431           1 : }
    5432             : 
    5433             : static void
    5434           1 : test_dir_should_init_request_to_dir_auths(void *data)
    5435             : {
    5436           1 :   dir_server_t *ds = NULL;
    5437           1 :   (void) data;
    5438             : 
    5439           1 :   MOCK(directory_initiate_request,
    5440             :        dir_tests_directory_initiate_request);
    5441             : 
    5442           1 :   clear_dir_servers();
    5443           1 :   routerlist_free_all();
    5444             : 
    5445           1 :   ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
    5446             :                               "12345678901234567890", NULL, V3_DIRINFO, 1.0);
    5447           1 :   tt_assert(ds);
    5448           1 :   dir_server_add(ds);
    5449             : 
    5450           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
    5451           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 1);
    5452             : 
    5453           1 :   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
    5454             :                                      NULL);
    5455           1 :   tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 2);
    5456             : 
    5457           1 :   done:
    5458           1 :     UNMOCK(directory_initiate_request);
    5459           1 :     clear_dir_servers();
    5460           1 :     routerlist_free_all();
    5461           1 : }
    5462             : 
    5463             : void
    5464           2 : dir_tests_directory_initiate_request(directory_request_t *req)
    5465             : {
    5466           2 :   (void)req;
    5467           2 :   dir_tests_directory_initiate_request_called++;
    5468           2 : }
    5469             : 
    5470             : /*
    5471             :  * Mock check_private_dir(), and always succeed - no need to actually
    5472             :  * look at or create anything on the filesystem.
    5473             :  */
    5474             : 
    5475             : static int
    5476           0 : mock_check_private_dir(const char *dirname, cpd_check_t check,
    5477             :                        const char *effective_user)
    5478             : {
    5479           0 :   (void)dirname;
    5480           0 :   (void)check;
    5481           0 :   (void)effective_user;
    5482             : 
    5483           0 :   return 0;
    5484             : }
    5485             : 
    5486             : /*
    5487             :  * This really mocks options_get_datadir_fname2_suffix(), but for testing
    5488             :  * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
    5489             :  * in config.h as:
    5490             :  *
    5491             :  * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
    5492             :  */
    5493             : 
    5494             : static char *
    5495          20 : mock_get_datadir_fname(const or_options_t *options,
    5496             :                        directory_root_t roottype,
    5497             :                        const char *sub1, const char *sub2,
    5498             :                        const char *suffix)
    5499             : {
    5500          20 :   (void) roottype;
    5501          20 :   char *rv = NULL;
    5502             : 
    5503             :   /*
    5504             :    * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
    5505             :    * since that's all we implement here.
    5506             :    */
    5507          20 :   tt_ptr_op(options, OP_NE, NULL);
    5508          20 :   tt_ptr_op(sub1, OP_NE, NULL);
    5509             :   /*
    5510             :    * No particular assertions about sub2, since we could be in the
    5511             :    * get_datadir_fname() or get_datadir_fname2() case.
    5512             :    */
    5513          20 :   tt_ptr_op(suffix, OP_EQ, NULL);
    5514             : 
    5515             :   /* Just duplicate the basename and return it for this mock */
    5516          20 :   if (sub2) {
    5517             :     /* If we have sub2, it's the basename, otherwise sub1 */
    5518          20 :     rv = tor_strdup(sub2);
    5519             :   } else {
    5520           0 :     rv = tor_strdup(sub1);
    5521             :   }
    5522             : 
    5523          20 :  done:
    5524          20 :   return rv;
    5525             : }
    5526             : 
    5527             : static char *last_unlinked_path = NULL;
    5528             : static int unlinked_count = 0;
    5529             : 
    5530             : static void
    5531          12 : mock_unlink_reset(void)
    5532             : {
    5533          12 :   tor_free(last_unlinked_path);
    5534          12 :   unlinked_count = 0;
    5535          12 : }
    5536             : 
    5537             : static int
    5538          11 : mock_unlink(const char *path)
    5539             : {
    5540          11 :   tt_ptr_op(path, OP_NE, NULL);
    5541             : 
    5542          11 :   tor_free(last_unlinked_path);
    5543          11 :   last_unlinked_path = tor_strdup(path);
    5544          11 :   ++unlinked_count;
    5545             : 
    5546          11 :  done:
    5547          11 :   return 0;
    5548             : }
    5549             : 
    5550             : static char *last_write_str_path = NULL;
    5551             : static uint8_t last_write_str_hash[DIGEST256_LEN];
    5552             : static int write_str_count = 0;
    5553             : 
    5554             : static void
    5555           9 : mock_write_str_to_file_reset(void)
    5556             : {
    5557           9 :   tor_free(last_write_str_path);
    5558           9 :   write_str_count = 0;
    5559           9 : }
    5560             : 
    5561             : static int
    5562          16 : mock_write_str_to_file(const char *path, const char *str, int bin)
    5563             : {
    5564          16 :   size_t len;
    5565          16 :   uint8_t hash[DIGEST256_LEN];
    5566             : 
    5567          16 :   (void)bin;
    5568             : 
    5569          16 :   tt_ptr_op(path, OP_NE, NULL);
    5570          16 :   tt_ptr_op(str, OP_NE, NULL);
    5571             : 
    5572          16 :   len = strlen(str);
    5573          16 :   crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
    5574             : 
    5575          16 :   tor_free(last_write_str_path);
    5576          16 :   last_write_str_path = tor_strdup(path);
    5577          16 :   memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
    5578          16 :   ++write_str_count;
    5579             : 
    5580          16 :  done:
    5581          16 :   return 0;
    5582             : }
    5583             : 
    5584             : static void
    5585           1 : test_dir_dump_unparseable_descriptors(void *data)
    5586             : {
    5587             :   /*
    5588             :    * These bogus descriptors look nothing at all like real bogus descriptors
    5589             :    * we might see, but we're only testing dump_desc() here, not the parser.
    5590             :    */
    5591           1 :   const char *test_desc_type = "squamous";
    5592             :   /* strlen(test_desc_1) = 583 bytes */
    5593           1 :   const char *test_desc_1 =
    5594             :     "The most merciful thing in the world, I think, is the inability of the "
    5595             :     "human mind to correlate all its contents. We live on a placid island of"
    5596             :     " ignorance in the midst of black seas of infinity, and it was not meant"
    5597             :     " that we should voyage far. The sciences, each straining in its own dir"
    5598             :     "ection, have hitherto harmed us little; but some day the piecing togeth"
    5599             :     "er of dissociated knowledge will open up such terrifying vistas of real"
    5600             :     "ity, and of our frightful position therein, that we shall either go mad"
    5601             :     "from the revelation or flee from the light into the peace and safety of"
    5602             :     "a new dark age.";
    5603           1 :   uint8_t test_desc_1_hash[DIGEST256_LEN];
    5604           1 :   char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
    5605             :   /* strlen(test_desc_2) = 650 bytes */
    5606           1 :   const char *test_desc_2 =
    5607             :     "I think their predominant colour was a greyish-green, though they had w"
    5608             :     "hite bellies. They were mostly shiny and slippery, but the ridges of th"
    5609             :     "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
    5610             :     "le their heads were the heads of fish, with prodigious bulging eyes tha"
    5611             :     "t never closed. At the sides of their necks were palpitating gills, and"
    5612             :     "their long paws were webbed. They hopped irregularly, sometimes on two "
    5613             :     "legs and sometimes on four. I was somehow glad that they had no more th"
    5614             :     "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
    5615             :     "e speech, held all the dark shades of expression which their staring fa"
    5616             :     "ces lacked.";
    5617           1 :   uint8_t test_desc_2_hash[DIGEST256_LEN];
    5618           1 :   char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
    5619             :   /* strlen(test_desc_3) = 700 bytes */
    5620           1 :   const char *test_desc_3 =
    5621             :     "Without knowing what futurism is like, Johansen achieved something very"
    5622             :     "close to it when he spoke of the city; for instead of describing any de"
    5623             :     "finite structure or building, he dwells only on broad impressions of va"
    5624             :     "st angles and stone surfaces - surfaces too great to belong to anything"
    5625             :     "right or proper for this earth, and impious with horrible images and hi"
    5626             :     "eroglyphs. I mention his talk about angles because it suggests somethin"
    5627             :     "g Wilcox had told me of his awful dreams. He said that the geometry of "
    5628             :     "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
    5629             :     "olent of spheres and dimensions apart from ours. Now an unlettered seam"
    5630             :     "an felt the same thing whilst gazing at the terrible reality.";
    5631           1 :   uint8_t test_desc_3_hash[DIGEST256_LEN];
    5632           1 :   char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
    5633             :   /* strlen(test_desc_3) = 604 bytes */
    5634           1 :   const char *test_desc_4 =
    5635             :     "So we glanced back simultaneously, it would appear; though no doubt the"
    5636             :     "incipient motion of one prompted the imitation of the other. As we did "
    5637             :     "so we flashed both torches full strength at the momentarily thinned mis"
    5638             :     "t; either from sheer primitive anxiety to see all we could, or in a les"
    5639             :     "s primitive but equally unconscious effort to dazzle the entity before "
    5640             :     "we dimmed our light and dodged among the penguins of the labyrinth cent"
    5641             :     "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
    5642             :     "re dearly for a backward glance. And again came that shocking, wide-ran"
    5643             :     "ged piping - \"Tekeli-li! Tekeli-li!\"";
    5644           1 :   uint8_t test_desc_4_hash[DIGEST256_LEN];
    5645           1 :   char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
    5646           1 :   (void)data;
    5647             : 
    5648             :   /*
    5649             :    * Set up options mock so we can force a tiny FIFO size and generate
    5650             :    * cleanups.
    5651             :    */
    5652           1 :   mock_options = tor_malloc(sizeof(or_options_t));
    5653           1 :   reset_options(mock_options, &mock_get_options_calls);
    5654           1 :   mock_options->MaxUnparseableDescSizeToLog = 1536;
    5655           1 :   MOCK(get_options, mock_get_options);
    5656           1 :   MOCK(check_private_dir, mock_check_private_dir);
    5657           1 :   MOCK(options_get_dir_fname2_suffix,
    5658             :        mock_get_datadir_fname);
    5659             : 
    5660             :   /*
    5661             :    * Set up unlink and write mocks
    5662             :    */
    5663           1 :   MOCK(tor_unlink, mock_unlink);
    5664           1 :   mock_unlink_reset();
    5665           1 :   MOCK(write_str_to_file, mock_write_str_to_file);
    5666           1 :   mock_write_str_to_file_reset();
    5667             : 
    5668             :   /*
    5669             :    * Compute hashes we'll need to recognize which descriptor is which
    5670             :    */
    5671           1 :   crypto_digest256((char *)test_desc_1_hash, test_desc_1,
    5672             :                    strlen(test_desc_1), DIGEST_SHA256);
    5673           1 :   base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
    5674             :                 (const char *)test_desc_1_hash,
    5675             :                 sizeof(test_desc_1_hash));
    5676           1 :   crypto_digest256((char *)test_desc_2_hash, test_desc_2,
    5677             :                    strlen(test_desc_2), DIGEST_SHA256);
    5678           1 :   base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
    5679             :                 (const char *)test_desc_2_hash,
    5680             :                 sizeof(test_desc_2_hash));
    5681           1 :   crypto_digest256((char *)test_desc_3_hash, test_desc_3,
    5682             :                    strlen(test_desc_3), DIGEST_SHA256);
    5683           1 :   base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
    5684             :                 (const char *)test_desc_3_hash,
    5685             :                 sizeof(test_desc_3_hash));
    5686           1 :   crypto_digest256((char *)test_desc_4_hash, test_desc_4,
    5687             :                    strlen(test_desc_4), DIGEST_SHA256);
    5688           1 :   base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
    5689             :                 (const char *)test_desc_4_hash,
    5690             :                 sizeof(test_desc_4_hash));
    5691             : 
    5692             :   /*
    5693             :    * Reset the FIFO and check its state
    5694             :    */
    5695           1 :   dump_desc_fifo_cleanup();
    5696           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5697           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5698             : 
    5699             :   /*
    5700             :    * (1) Fire off dump_desc() once; these descriptors should all be safely
    5701             :    * smaller than configured FIFO size.
    5702             :    */
    5703             : 
    5704           1 :   dump_desc(test_desc_1, test_desc_type);
    5705             : 
    5706             :   /*
    5707             :    * Assert things about the FIFO state
    5708             :    */
    5709           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
    5710           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    5711             : 
    5712             :   /*
    5713             :    * Assert things about the mocks
    5714             :    */
    5715           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5716           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    5717           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
    5718             : 
    5719             :   /*
    5720             :    * Reset the FIFO and check its state
    5721             :    */
    5722           1 :   dump_desc_fifo_cleanup();
    5723           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5724           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5725             : 
    5726             :   /*
    5727             :    * Reset the mocks and check their state
    5728             :    */
    5729           1 :   mock_unlink_reset();
    5730           1 :   mock_write_str_to_file_reset();
    5731           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5732           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    5733             : 
    5734             :   /*
    5735             :    * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
    5736             :    */
    5737             : 
    5738             :   /* First time */
    5739           1 :   dump_desc(test_desc_2, test_desc_type);
    5740             : 
    5741             :   /*
    5742             :    * Assert things about the FIFO state
    5743             :    */
    5744           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
    5745           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    5746             : 
    5747             :   /*
    5748             :    * Assert things about the mocks
    5749             :    */
    5750           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5751           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    5752           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
    5753             : 
    5754             :   /* Second time */
    5755           1 :   dump_desc(test_desc_3, test_desc_type);
    5756             : 
    5757             :   /*
    5758             :    * Assert things about the FIFO state
    5759             :    */
    5760           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5761             :             strlen(test_desc_2) + strlen(test_desc_3));
    5762           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5763             : 
    5764             :   /*
    5765             :    * Assert things about the mocks
    5766             :    */
    5767           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5768           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5769           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
    5770             : 
    5771             :   /*
    5772             :    * Reset the FIFO and check its state
    5773             :    */
    5774           1 :   dump_desc_fifo_cleanup();
    5775           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5776           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5777             : 
    5778             :   /*
    5779             :    * Reset the mocks and check their state
    5780             :    */
    5781           1 :   mock_unlink_reset();
    5782           1 :   mock_write_str_to_file_reset();
    5783           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5784           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    5785             : 
    5786             :   /*
    5787             :    * (3) Three calls to dump_desc cause a FIFO cleanup
    5788             :    */
    5789             : 
    5790             :   /* First time */
    5791           1 :   dump_desc(test_desc_4, test_desc_type);
    5792             : 
    5793             :   /*
    5794             :    * Assert things about the FIFO state
    5795             :    */
    5796           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
    5797           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    5798             : 
    5799             :   /*
    5800             :    * Assert things about the mocks
    5801             :    */
    5802           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5803           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    5804           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    5805             : 
    5806             :   /* Second time */
    5807           1 :   dump_desc(test_desc_1, test_desc_type);
    5808             : 
    5809             :   /*
    5810             :    * Assert things about the FIFO state
    5811             :    */
    5812           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5813             :             strlen(test_desc_4) + strlen(test_desc_1));
    5814           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5815             : 
    5816             :   /*
    5817             :    * Assert things about the mocks
    5818             :    */
    5819           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5820           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5821           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
    5822             : 
    5823             :   /* Third time - we should unlink the dump of test_desc_4 here */
    5824           1 :   dump_desc(test_desc_2, test_desc_type);
    5825             : 
    5826             :   /*
    5827             :    * Assert things about the FIFO state
    5828             :    */
    5829           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5830             :             strlen(test_desc_1) + strlen(test_desc_2));
    5831           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5832             : 
    5833             :   /*
    5834             :    * Assert things about the mocks
    5835             :    */
    5836           1 :   tt_int_op(unlinked_count, OP_EQ, 1);
    5837           1 :   tt_int_op(write_str_count, OP_EQ, 3);
    5838           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
    5839             : 
    5840             :   /*
    5841             :    * Reset the FIFO and check its state
    5842             :    */
    5843           1 :   dump_desc_fifo_cleanup();
    5844           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5845           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5846             : 
    5847             :   /*
    5848             :    * Reset the mocks and check their state
    5849             :    */
    5850           1 :   mock_unlink_reset();
    5851           1 :   mock_write_str_to_file_reset();
    5852           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5853           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    5854             : 
    5855             :   /*
    5856             :    * (4) But repeating one (A B B) doesn't overflow and cleanup
    5857             :    */
    5858             : 
    5859             :   /* First time */
    5860           1 :   dump_desc(test_desc_3, test_desc_type);
    5861             : 
    5862             :   /*
    5863             :    * Assert things about the FIFO state
    5864             :    */
    5865           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
    5866           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    5867             : 
    5868             :   /*
    5869             :    * Assert things about the mocks
    5870             :    */
    5871           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5872           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    5873           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
    5874             : 
    5875             :   /* Second time */
    5876           1 :   dump_desc(test_desc_4, test_desc_type);
    5877             : 
    5878             :   /*
    5879             :    * Assert things about the FIFO state
    5880             :    */
    5881           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5882             :             strlen(test_desc_3) + strlen(test_desc_4));
    5883           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5884             : 
    5885             :   /*
    5886             :    * Assert things about the mocks
    5887             :    */
    5888           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5889           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5890           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    5891             : 
    5892             :   /* Third time */
    5893           1 :   dump_desc(test_desc_4, test_desc_type);
    5894             : 
    5895             :   /*
    5896             :    * Assert things about the FIFO state
    5897             :    */
    5898           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5899             :             strlen(test_desc_3) + strlen(test_desc_4));
    5900           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5901             : 
    5902             :   /*
    5903             :    * Assert things about the mocks
    5904             :    */
    5905           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5906           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5907           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    5908             : 
    5909             :   /*
    5910             :    * Reset the FIFO and check its state
    5911             :    */
    5912           1 :   dump_desc_fifo_cleanup();
    5913           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5914           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5915             : 
    5916             :   /*
    5917             :    * Reset the mocks and check their state
    5918             :    */
    5919           1 :   mock_unlink_reset();
    5920           1 :   mock_write_str_to_file_reset();
    5921           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5922           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    5923             : 
    5924             :   /*
    5925             :    * (5) Same for the (A B A) repetition
    5926             :    */
    5927             : 
    5928             :   /* First time */
    5929           1 :   dump_desc(test_desc_1, test_desc_type);
    5930             : 
    5931             :   /*
    5932             :    * Assert things about the FIFO state
    5933             :    */
    5934           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
    5935           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    5936             : 
    5937             :   /*
    5938             :    * Assert things about the mocks
    5939             :    */
    5940           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5941           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    5942           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
    5943             : 
    5944             :   /* Second time */
    5945           1 :   dump_desc(test_desc_2, test_desc_type);
    5946             : 
    5947             :   /*
    5948             :    * Assert things about the FIFO state
    5949             :    */
    5950           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5951             :             strlen(test_desc_1) + strlen(test_desc_2));
    5952           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5953             : 
    5954             :   /*
    5955             :    * Assert things about the mocks
    5956             :    */
    5957           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5958           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5959           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
    5960             : 
    5961             :   /* Third time */
    5962           1 :   dump_desc(test_desc_1, test_desc_type);
    5963             : 
    5964             :   /*
    5965             :    * Assert things about the FIFO state
    5966             :    */
    5967           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    5968             :             strlen(test_desc_1) + strlen(test_desc_2));
    5969           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    5970             : 
    5971             :   /*
    5972             :    * Assert things about the mocks
    5973             :    */
    5974           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5975           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    5976           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
    5977             : 
    5978             :   /*
    5979             :    * Reset the FIFO and check its state
    5980             :    */
    5981           1 :   dump_desc_fifo_cleanup();
    5982           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    5983           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    5984             : 
    5985             :   /*
    5986             :    * Reset the mocks and check their state
    5987             :    */
    5988           1 :   mock_unlink_reset();
    5989           1 :   mock_write_str_to_file_reset();
    5990           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    5991           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    5992             : 
    5993             :   /*
    5994             :    * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
    5995             :    */
    5996             : 
    5997             :   /* First time */
    5998           1 :   dump_desc(test_desc_3, test_desc_type);
    5999             : 
    6000             :   /*
    6001             :    * Assert things about the FIFO state
    6002             :    */
    6003           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
    6004           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    6005             : 
    6006             :   /*
    6007             :    * Assert things about the mocks
    6008             :    */
    6009           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6010           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    6011           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
    6012             : 
    6013             :   /* Second time */
    6014           1 :   dump_desc(test_desc_4, test_desc_type);
    6015             : 
    6016             :   /*
    6017             :    * Assert things about the FIFO state
    6018             :    */
    6019           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6020             :             strlen(test_desc_3) + strlen(test_desc_4));
    6021           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6022             : 
    6023             :   /*
    6024             :    * Assert things about the mocks
    6025             :    */
    6026           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6027           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    6028           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    6029             : 
    6030             :   /* Third time */
    6031           1 :   dump_desc(test_desc_4, test_desc_type);
    6032             : 
    6033             :   /*
    6034             :    * Assert things about the FIFO state
    6035             :    */
    6036           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6037             :             strlen(test_desc_3) + strlen(test_desc_4));
    6038           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6039             : 
    6040             :   /*
    6041             :    * Assert things about the mocks
    6042             :    */
    6043           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6044           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    6045           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    6046             : 
    6047             :   /* Fourth time - we should unlink the dump of test_desc_3 here */
    6048           1 :   dump_desc(test_desc_1, test_desc_type);
    6049             : 
    6050             :   /*
    6051             :    * Assert things about the FIFO state
    6052             :    */
    6053           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6054             :             strlen(test_desc_4) + strlen(test_desc_1));
    6055           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6056             : 
    6057             :   /*
    6058             :    * Assert things about the mocks
    6059             :    */
    6060           1 :   tt_int_op(unlinked_count, OP_EQ, 1);
    6061           1 :   tt_int_op(write_str_count, OP_EQ, 3);
    6062           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
    6063             : 
    6064             :   /*
    6065             :    * Reset the FIFO and check its state
    6066             :    */
    6067           1 :   dump_desc_fifo_cleanup();
    6068           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    6069           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    6070             : 
    6071             :   /*
    6072             :    * Reset the mocks and check their state
    6073             :    */
    6074           1 :   mock_unlink_reset();
    6075           1 :   mock_write_str_to_file_reset();
    6076           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6077           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    6078             : 
    6079             :   /*
    6080             :    * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
    6081             :    */
    6082             : 
    6083             :   /* First time */
    6084           1 :   dump_desc(test_desc_2, test_desc_type);
    6085             : 
    6086             :   /*
    6087             :    * Assert things about the FIFO state
    6088             :    */
    6089           1 :   tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
    6090           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
    6091             : 
    6092             :   /*
    6093             :    * Assert things about the mocks
    6094             :    */
    6095           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6096           1 :   tt_int_op(write_str_count, OP_EQ, 1);
    6097           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
    6098             : 
    6099             :   /* Second time */
    6100           1 :   dump_desc(test_desc_3, test_desc_type);
    6101             : 
    6102             :   /*
    6103             :    * Assert things about the FIFO state
    6104             :    */
    6105           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6106             :             strlen(test_desc_2) + strlen(test_desc_3));
    6107           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6108             : 
    6109             :   /*
    6110             :    * Assert things about the mocks
    6111             :    */
    6112           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6113           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    6114           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
    6115             : 
    6116             :   /* Third time */
    6117           1 :   dump_desc(test_desc_2, test_desc_type);
    6118             : 
    6119             :   /*
    6120             :    * Assert things about the FIFO state
    6121             :    */
    6122           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6123             :             strlen(test_desc_2) + strlen(test_desc_3));
    6124           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6125             : 
    6126             :   /*
    6127             :    * Assert things about the mocks
    6128             :    */
    6129           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6130           1 :   tt_int_op(write_str_count, OP_EQ, 2);
    6131           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
    6132             : 
    6133             :   /* Fourth time - we should unlink the dump of test_desc_3 here */
    6134           1 :   dump_desc(test_desc_4, test_desc_type);
    6135             : 
    6136             :   /*
    6137             :    * Assert things about the FIFO state
    6138             :    */
    6139           1 :   tt_u64_op(len_descs_dumped, OP_EQ,
    6140             :             strlen(test_desc_2) + strlen(test_desc_4));
    6141           1 :   tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
    6142             : 
    6143             :   /*
    6144             :    * Assert things about the mocks
    6145             :    */
    6146           1 :   tt_int_op(unlinked_count, OP_EQ, 1);
    6147           1 :   tt_int_op(write_str_count, OP_EQ, 3);
    6148           1 :   tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
    6149             : 
    6150             :   /*
    6151             :    * Reset the FIFO and check its state
    6152             :    */
    6153           1 :   dump_desc_fifo_cleanup();
    6154           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 0);
    6155           1 :   tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
    6156             : 
    6157             :   /*
    6158             :    * Reset the mocks and check their state
    6159             :    */
    6160           1 :   mock_unlink_reset();
    6161           1 :   mock_write_str_to_file_reset();
    6162           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6163           1 :   tt_int_op(write_str_count, OP_EQ, 0);
    6164             : 
    6165           1 :  done:
    6166             : 
    6167             :   /* Clean up the fifo */
    6168           1 :   dump_desc_fifo_cleanup();
    6169             : 
    6170             :   /* Remove mocks */
    6171           1 :   UNMOCK(tor_unlink);
    6172           1 :   mock_unlink_reset();
    6173           1 :   UNMOCK(write_str_to_file);
    6174           1 :   mock_write_str_to_file_reset();
    6175           1 :   UNMOCK(options_get_dir_fname2_suffix);
    6176           1 :   UNMOCK(check_private_dir);
    6177           1 :   UNMOCK(get_options);
    6178           1 :   tor_free(mock_options);
    6179           1 :   mock_options = NULL;
    6180             : 
    6181           1 :   return;
    6182             : }
    6183             : 
    6184             : /* Variables for reset_read_file_to_str_mock() */
    6185             : 
    6186             : static int enforce_expected_filename = 0;
    6187             : static char *expected_filename = NULL;
    6188             : static char *file_content = NULL;
    6189             : static size_t file_content_len = 0;
    6190             : static struct stat file_stat;
    6191             : static int read_count = 0, read_call_count = 0;
    6192             : 
    6193             : static void
    6194           3 : reset_read_file_to_str_mock(void)
    6195             : {
    6196           3 :   tor_free(expected_filename);
    6197           3 :   tor_free(file_content);
    6198           3 :   file_content_len = 0;
    6199           3 :   memset(&file_stat, 0, sizeof(file_stat));
    6200           3 :   read_count = 0;
    6201           3 :   read_call_count = 0;
    6202           3 : }
    6203             : 
    6204             : static char *
    6205           3 : read_file_to_str_mock(const char *filename, int flags,
    6206             :                       struct stat *stat_out) {
    6207           3 :   char *result = NULL;
    6208             : 
    6209             :   /* Insist we got a filename */
    6210           3 :   tt_ptr_op(filename, OP_NE, NULL);
    6211             : 
    6212             :   /* We ignore flags */
    6213           3 :   (void)flags;
    6214             : 
    6215             :   /* Bump the call count */
    6216           3 :   ++read_call_count;
    6217             : 
    6218           3 :   if (enforce_expected_filename) {
    6219           1 :     tt_assert(expected_filename);
    6220           1 :     tt_str_op(filename, OP_EQ, expected_filename);
    6221             :   }
    6222             : 
    6223           3 :   if (expected_filename != NULL &&
    6224           2 :       file_content != NULL &&
    6225           2 :       strcmp(filename, expected_filename) == 0) {
    6226             :     /* You asked for it, you got it */
    6227             : 
    6228             :     /*
    6229             :      * This is the same behavior as the real read_file_to_str();
    6230             :      * if there's a NUL, the real size ends up in stat_out.
    6231             :      */
    6232           2 :     result = tor_malloc(file_content_len + 1);
    6233           2 :     if (file_content_len > 0) {
    6234           2 :       memcpy(result, file_content, file_content_len);
    6235             :     }
    6236           2 :     result[file_content_len] = '\0';
    6237             : 
    6238             :     /* Do we need to set up stat_out? */
    6239           2 :     if (stat_out != NULL) {
    6240           2 :       memcpy(stat_out, &file_stat, sizeof(file_stat));
    6241             :       /* We always return the correct length here */
    6242           2 :       stat_out->st_size = file_content_len;
    6243             :     }
    6244             : 
    6245             :     /* Wooo, we have a return value - bump the counter */
    6246           2 :     ++read_count;
    6247             :   }
    6248             :   /* else no match, return NULL */
    6249             : 
    6250           1 :  done:
    6251           3 :   return result;
    6252             : }
    6253             : 
    6254             : /* This one tests dump_desc_populate_one_file() */
    6255             : static void
    6256           1 : test_dir_populate_dump_desc_fifo(void *data)
    6257             : {
    6258           1 :   const char *dirname = "foo";
    6259           1 :   const char *fname = NULL;
    6260           1 :   dumped_desc_t *ent;
    6261             : 
    6262           1 :   (void)data;
    6263             : 
    6264             :   /*
    6265             :    * Set up unlink and read_file_to_str mocks
    6266             :    */
    6267           1 :   MOCK(tor_unlink, mock_unlink);
    6268           1 :   mock_unlink_reset();
    6269           1 :   MOCK(read_file_to_str, read_file_to_str_mock);
    6270           1 :   reset_read_file_to_str_mock();
    6271             : 
    6272             :   /* Check state of unlink mock */
    6273           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6274             : 
    6275             :   /* Some cases that should fail before trying to read the file */
    6276           1 :   ent = dump_desc_populate_one_file(dirname, "bar");
    6277           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6278           1 :   tt_int_op(unlinked_count, OP_EQ, 1);
    6279           1 :   tt_int_op(read_count, OP_EQ, 0);
    6280           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6281             : 
    6282           1 :   ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
    6283           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6284           1 :   tt_int_op(unlinked_count, OP_EQ, 2);
    6285           1 :   tt_int_op(read_count, OP_EQ, 0);
    6286           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6287             : 
    6288           1 :   ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
    6289           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6290           1 :   tt_int_op(unlinked_count, OP_EQ, 3);
    6291           1 :   tt_int_op(read_count, OP_EQ, 0);
    6292           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6293             : 
    6294           1 :   ent = dump_desc_populate_one_file(
    6295             :       dirname,
    6296             :       "unparseable-desc.08AE85E90461F59E");
    6297           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6298           1 :   tt_int_op(unlinked_count, OP_EQ, 4);
    6299           1 :   tt_int_op(read_count, OP_EQ, 0);
    6300           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6301             : 
    6302           1 :   ent = dump_desc_populate_one_file(
    6303             :       dirname,
    6304             :       "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
    6305             :       "287D72F7B72F242E85C8CB0EDA8854A99");
    6306           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6307           1 :   tt_int_op(unlinked_count, OP_EQ, 5);
    6308           1 :   tt_int_op(read_count, OP_EQ, 0);
    6309           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6310             : 
    6311             :   /* This is a correct-length digest but base16_decode() will fail */
    6312           1 :   ent = dump_desc_populate_one_file(
    6313             :       dirname,
    6314             :       "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
    6315             :       "D5ECE250D912E686B");
    6316           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6317           1 :   tt_int_op(unlinked_count, OP_EQ, 6);
    6318           1 :   tt_int_op(read_count, OP_EQ, 0);
    6319           1 :   tt_int_op(read_call_count, OP_EQ, 0);
    6320             : 
    6321             :   /* This one has a correctly formed filename and should try reading */
    6322             : 
    6323             :   /* Read fails */
    6324           1 :   ent = dump_desc_populate_one_file(
    6325             :       dirname,
    6326             :       "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
    6327             :       "85C8CB0EDA8854A99");
    6328           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6329           1 :   tt_int_op(unlinked_count, OP_EQ, 7);
    6330           1 :   tt_int_op(read_count, OP_EQ, 0);
    6331           1 :   tt_int_op(read_call_count, OP_EQ, 1);
    6332             : 
    6333             :   /* This read will succeed but the digest won't match the file content */
    6334           1 :   fname =
    6335             :     "unparseable-desc."
    6336             :     "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
    6337           1 :   enforce_expected_filename = 1;
    6338           1 :   tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
    6339           1 :   file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
    6340           1 :   file_content_len = strlen(file_content);
    6341           1 :   file_stat.st_mtime = 123456;
    6342           1 :   ent = dump_desc_populate_one_file(dirname, fname);
    6343           1 :   enforce_expected_filename = 0;
    6344           1 :   tt_ptr_op(ent, OP_EQ, NULL);
    6345           1 :   tt_int_op(unlinked_count, OP_EQ, 8);
    6346           1 :   tt_int_op(read_count, OP_EQ, 1);
    6347           1 :   tt_int_op(read_call_count, OP_EQ, 2);
    6348           1 :   tor_free(expected_filename);
    6349           1 :   tor_free(file_content);
    6350             : 
    6351             :   /* This one will match */
    6352           1 :   fname =
    6353             :     "unparseable-desc."
    6354             :     "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
    6355           1 :   tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
    6356           1 :   file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
    6357           1 :   file_content_len = strlen(file_content);
    6358           1 :   file_stat.st_mtime = 789012;
    6359           1 :   ent = dump_desc_populate_one_file(dirname, fname);
    6360           1 :   tt_ptr_op(ent, OP_NE, NULL);
    6361           1 :   tt_int_op(unlinked_count, OP_EQ, 8);
    6362           1 :   tt_int_op(read_count, OP_EQ, 2);
    6363           1 :   tt_int_op(read_call_count, OP_EQ, 3);
    6364           1 :   tt_str_op(ent->filename, OP_EQ, expected_filename);
    6365           1 :   tt_int_op(ent->len, OP_EQ, file_content_len);
    6366           1 :   tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
    6367           1 :   tor_free(ent->filename);
    6368           1 :   tor_free(ent);
    6369           1 :   tor_free(expected_filename);
    6370             : 
    6371             :   /*
    6372             :    * Reset the mocks and check their state
    6373             :    */
    6374           1 :   mock_unlink_reset();
    6375           1 :   tt_int_op(unlinked_count, OP_EQ, 0);
    6376           1 :   reset_read_file_to_str_mock();
    6377           1 :   tt_int_op(read_count, OP_EQ, 0);
    6378             : 
    6379           1 :  done:
    6380             : 
    6381           1 :   UNMOCK(tor_unlink);
    6382           1 :   mock_unlink_reset();
    6383           1 :   UNMOCK(read_file_to_str);
    6384           1 :   reset_read_file_to_str_mock();
    6385             : 
    6386           1 :   tor_free(file_content);
    6387             : 
    6388           1 :   return;
    6389             : }
    6390             : 
    6391             : static smartlist_t *
    6392           1 : listdir_mock(const char *dname)
    6393             : {
    6394           1 :   smartlist_t *l;
    6395             : 
    6396             :   /* Ignore the name, always return this list */
    6397           1 :   (void)dname;
    6398             : 
    6399           1 :   l = smartlist_new();
    6400           1 :   smartlist_add_strdup(l, "foo");
    6401           1 :   smartlist_add_strdup(l, "bar");
    6402           1 :   smartlist_add_strdup(l, "baz");
    6403             : 
    6404           1 :   return l;
    6405             : }
    6406             : 
    6407             : static dumped_desc_t *
    6408           3 : pop_one_mock(const char *dirname, const char *f)
    6409             : {
    6410           3 :   dumped_desc_t *ent = NULL;
    6411             : 
    6412           3 :   if (dirname != NULL && strcmp(dirname, "d") == 0) {
    6413           3 :     if (f != NULL && strcmp(f, "foo") == 0) {
    6414           1 :       ent = tor_malloc_zero(sizeof(*ent));
    6415           1 :       ent->filename = tor_strdup("d/foo");
    6416           1 :       ent->len = 123;
    6417           1 :       ent->digest_sha256[0] = 1;
    6418           1 :       ent->when = 1024;
    6419           2 :     } else if (f != NULL && strcmp(f, "bar") == 0) {
    6420           1 :       ent = tor_malloc_zero(sizeof(*ent));
    6421           1 :       ent->filename = tor_strdup("d/bar");
    6422           1 :       ent->len = 456;
    6423           1 :       ent->digest_sha256[0] = 2;
    6424             :       /*
    6425             :        * Note that the timestamps are in a different order than
    6426             :        * listdir_mock() returns; we're testing the sort order.
    6427             :        */
    6428           1 :       ent->when = 512;
    6429           1 :     } else if (f != NULL && strcmp(f, "baz") == 0) {
    6430           1 :       ent = tor_malloc_zero(sizeof(*ent));
    6431           1 :       ent->filename = tor_strdup("d/baz");
    6432           1 :       ent->len = 789;
    6433           1 :       ent->digest_sha256[0] = 3;
    6434           1 :       ent->when = 768;
    6435             :     }
    6436             :   }
    6437             : 
    6438           3 :   return ent;
    6439             : }
    6440             : 
    6441             : /* This one tests dump_desc_populate_fifo_from_directory() */
    6442             : static void
    6443           1 : test_dir_populate_dump_desc_fifo_2(void *data)
    6444             : {
    6445           1 :   dumped_desc_t *ent = NULL;
    6446             : 
    6447           1 :   (void)data;
    6448             : 
    6449             :   /* Set up the mocks */
    6450           1 :   MOCK(tor_listdir, listdir_mock);
    6451           1 :   MOCK(dump_desc_populate_one_file, pop_one_mock);
    6452             : 
    6453             :   /* Run dump_desc_populate_fifo_from_directory() */
    6454           1 :   descs_dumped = NULL;
    6455           1 :   len_descs_dumped = 0;
    6456           1 :   dump_desc_populate_fifo_from_directory("d");
    6457           1 :   tt_assert(descs_dumped != NULL);
    6458           1 :   tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
    6459           1 :   tt_u64_op(len_descs_dumped, OP_EQ, 1368);
    6460           1 :   ent = smartlist_get(descs_dumped, 0);
    6461           1 :   tt_str_op(ent->filename, OP_EQ, "d/bar");
    6462           1 :   tt_int_op(ent->len, OP_EQ, 456);
    6463           1 :   tt_int_op(ent->when, OP_EQ, 512);
    6464           1 :   ent = smartlist_get(descs_dumped, 1);
    6465           1 :   tt_str_op(ent->filename, OP_EQ, "d/baz");
    6466           1 :   tt_int_op(ent->len, OP_EQ, 789);
    6467           1 :   tt_int_op(ent->when, OP_EQ, 768);
    6468           1 :   ent = smartlist_get(descs_dumped, 2);
    6469           1 :   tt_str_op(ent->filename, OP_EQ, "d/foo");
    6470           1 :   tt_int_op(ent->len, OP_EQ, 123);
    6471           1 :   tt_int_op(ent->when, OP_EQ, 1024);
    6472             : 
    6473           1 :  done:
    6474           1 :   dump_desc_fifo_cleanup();
    6475             : 
    6476           1 :   UNMOCK(dump_desc_populate_one_file);
    6477           1 :   UNMOCK(tor_listdir);
    6478             : 
    6479           1 :   return;
    6480             : }
    6481             : 
    6482             : static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
    6483             : static int
    6484          28 : mock_networkstatus_consensus_is_bootstrapping(time_t now)
    6485             : {
    6486          28 :   (void)now;
    6487          28 :   return mock_networkstatus_consensus_is_bootstrapping_value;
    6488             : }
    6489             : 
    6490             : static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
    6491             : static int
    6492          16 : mock_networkstatus_consensus_can_use_extra_fallbacks(
    6493             :                                                   const or_options_t *options)
    6494             : {
    6495          16 :   (void)options;
    6496          16 :   return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
    6497             : }
    6498             : 
    6499             : static int mock_num_bridges_usable_value = 0;
    6500             : static int
    6501          16 : mock_num_bridges_usable(int use_maybe_reachable)
    6502             : {
    6503          16 :   (void)use_maybe_reachable;
    6504          16 :   return mock_num_bridges_usable_value;
    6505             : }
    6506             : 
    6507             : /* data is a 3 character nul-terminated string.
    6508             :  * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
    6509             :  * If data[1] is 'f', set extra fallbacks, anything else means no extra
    6510             :  * If data[2] is 'f', set running bridges, anything else means no extra
    6511             :  * fallbacks.
    6512             :  */
    6513             : static void
    6514           8 : test_dir_find_dl_min_delay(void* data)
    6515             : {
    6516           8 :   const char *str = (const char *)data;
    6517             : 
    6518           8 :   tt_assert(strlen(data) == 3);
    6519             : 
    6520           8 :   if (str[0] == 'b') {
    6521           4 :     mock_networkstatus_consensus_is_bootstrapping_value = 1;
    6522             :   } else {
    6523           4 :     mock_networkstatus_consensus_is_bootstrapping_value = 0;
    6524             :   }
    6525             : 
    6526           8 :   if (str[1] == 'f') {
    6527           4 :     mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
    6528             :   } else {
    6529           4 :     mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
    6530             :   }
    6531             : 
    6532           8 :   if (str[2] == 'r') {
    6533             :     /* Any positive, non-zero value should work */
    6534           4 :     mock_num_bridges_usable_value = 2;
    6535             :   } else {
    6536           4 :     mock_num_bridges_usable_value = 0;
    6537             :   }
    6538             : 
    6539           8 :   MOCK(networkstatus_consensus_is_bootstrapping,
    6540             :        mock_networkstatus_consensus_is_bootstrapping);
    6541           8 :   MOCK(networkstatus_consensus_can_use_extra_fallbacks,
    6542             :        mock_networkstatus_consensus_can_use_extra_fallbacks);
    6543           8 :   MOCK(num_bridges_usable,
    6544             :        mock_num_bridges_usable);
    6545             : 
    6546           8 :   download_status_t dls;
    6547             : 
    6548           8 :   const int server=10, client=20, server_cons=30, client_cons=40;
    6549           8 :   const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
    6550           8 :   const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
    6551             : 
    6552           8 :   mock_options = tor_malloc(sizeof(or_options_t));
    6553           8 :   reset_options(mock_options, &mock_get_options_calls);
    6554           8 :   MOCK(get_options, mock_get_options);
    6555             : 
    6556           8 :   mock_options->TestingServerDownloadInitialDelay = server;
    6557           8 :   mock_options->TestingClientDownloadInitialDelay = client;
    6558           8 :   mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
    6559           8 :   mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
    6560           8 :   mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
    6561             :     client_boot_auth_only_cons;
    6562           8 :   mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
    6563             :     client_boot_auth_cons;
    6564           8 :   mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
    6565             :     client_boot_fallback_cons;
    6566           8 :   mock_options->TestingBridgeDownloadInitialDelay = bridge;
    6567           8 :   mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
    6568             : 
    6569           8 :   dls.schedule = DL_SCHED_GENERIC;
    6570             :   /* client */
    6571           8 :   mock_options->ClientOnly = 1;
    6572           8 :   tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
    6573           8 :   mock_options->ClientOnly = 0;
    6574             : 
    6575             :   /* dir mode */
    6576           8 :   mock_options->DirPort_set = 1;
    6577           8 :   mock_options->DirCache = 1;
    6578           8 :   tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
    6579           8 :   mock_options->DirPort_set = 0;
    6580           8 :   mock_options->DirCache = 0;
    6581             : 
    6582           8 :   dls.schedule = DL_SCHED_CONSENSUS;
    6583             :   /* public server mode */
    6584           8 :   mock_options->ORPort_set = 1;
    6585           8 :   tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
    6586           8 :   mock_options->ORPort_set = 0;
    6587             : 
    6588             :   /* client and bridge modes */
    6589           8 :   if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
    6590           4 :     if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
    6591           2 :       dls.want_authority = 1;
    6592             :       /* client */
    6593           2 :       mock_options->ClientOnly = 1;
    6594           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6595             :                 client_boot_auth_cons);
    6596           2 :       mock_options->ClientOnly = 0;
    6597             : 
    6598             :       /* bridge relay */
    6599           2 :       mock_options->ORPort_set = 1;
    6600           2 :       mock_options->BridgeRelay = 1;
    6601           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6602             :                 client_boot_auth_cons);
    6603           2 :       mock_options->ORPort_set = 0;
    6604           2 :       mock_options->BridgeRelay = 0;
    6605             : 
    6606           2 :       dls.want_authority = 0;
    6607             :       /* client */
    6608           2 :       mock_options->ClientOnly = 1;
    6609           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6610             :                 client_boot_fallback_cons);
    6611           2 :       mock_options->ClientOnly = 0;
    6612             : 
    6613             :       /* bridge relay */
    6614           2 :       mock_options->ORPort_set = 1;
    6615           2 :       mock_options->BridgeRelay = 1;
    6616           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6617             :                 client_boot_fallback_cons);
    6618           2 :       mock_options->ORPort_set = 0;
    6619           2 :       mock_options->BridgeRelay = 0;
    6620             : 
    6621             :     } else {
    6622             :       /* dls.want_authority is ignored */
    6623             :       /* client */
    6624           2 :       mock_options->ClientOnly = 1;
    6625           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6626             :                 client_boot_auth_only_cons);
    6627           2 :       mock_options->ClientOnly = 0;
    6628             : 
    6629             :       /* bridge relay */
    6630           2 :       mock_options->ORPort_set = 1;
    6631           2 :       mock_options->BridgeRelay = 1;
    6632           2 :       tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6633             :                 client_boot_auth_only_cons);
    6634           2 :       mock_options->ORPort_set = 0;
    6635           2 :       mock_options->BridgeRelay = 0;
    6636             :     }
    6637             :   } else {
    6638             :     /* client */
    6639           4 :     mock_options->ClientOnly = 1;
    6640           4 :     tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6641             :               client_cons);
    6642           4 :     mock_options->ClientOnly = 0;
    6643             : 
    6644             :     /* bridge relay */
    6645           4 :     mock_options->ORPort_set = 1;
    6646           4 :     mock_options->BridgeRelay = 1;
    6647           4 :     tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
    6648             :               client_cons);
    6649           4 :     mock_options->ORPort_set = 0;
    6650           4 :     mock_options->BridgeRelay = 0;
    6651             :   }
    6652             : 
    6653           8 :   dls.schedule = DL_SCHED_BRIDGE;
    6654             :   /* client */
    6655           8 :   mock_options->ClientOnly = 1;
    6656           8 :   mock_options->UseBridges = 1;
    6657           8 :   if (num_bridges_usable(0) > 0) {
    6658           4 :     tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
    6659             :   } else {
    6660           4 :     tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
    6661             :   }
    6662             : 
    6663           4 :  done:
    6664           8 :   UNMOCK(networkstatus_consensus_is_bootstrapping);
    6665           8 :   UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
    6666           8 :   UNMOCK(num_bridges_usable);
    6667           8 :   UNMOCK(get_options);
    6668           8 :   tor_free(mock_options);
    6669           8 :   mock_options = NULL;
    6670           8 : }
    6671             : 
    6672             : static void
    6673           1 : test_dir_matching_flags(void *arg)
    6674             : {
    6675           1 :   (void) arg;
    6676           1 :   routerstatus_t *rs_noflags = NULL;
    6677           1 :   routerstatus_t *rs = NULL;
    6678           1 :   char *s = NULL;
    6679             : 
    6680           1 :   smartlist_t *tokens = smartlist_new();
    6681           1 :   memarea_t *area = memarea_new();
    6682             : 
    6683           1 :   int expected_val_when_unused = 0;
    6684             : 
    6685           1 :   const char *ex_noflags =
    6686             :     "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
    6687             :        "192.168.0.1 9001 0\n"
    6688             :     "m thisoneislongerbecauseitisa256bitmddigest33\n"
    6689             :     "s\n"
    6690             :     "pr Link=4\n";
    6691           1 :   const char *cp = ex_noflags;
    6692           1 :   rs_noflags = routerstatus_parse_entry_from_string(
    6693             :          area, &cp,
    6694             :          cp + strlen(cp),
    6695             :          tokens, NULL, NULL,
    6696             :          MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);
    6697           1 :   tt_assert(rs_noflags);
    6698             : 
    6699             : #define FLAG(string, field) STMT_BEGIN {        \
    6700             :     tor_asprintf(&s,\
    6701             :                  "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " \
    6702             :                  "192.168.0.1 9001 0\n"                                 \
    6703             :                  "m thisoneislongerbecauseitisa256bitmddigest33\n"      \
    6704             :                  "pr Link=4\n"                                          \
    6705             :                  "s %s\n", string);                                     \
    6706             :     cp = s;                                                             \
    6707             :     rs =  routerstatus_parse_entry_from_string(                         \
    6708             :       area, &cp,                                                        \
    6709             :       cp + strlen(cp),                                                  \
    6710             :       tokens, NULL, NULL,                                               \
    6711             :       MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);                  \
    6712             :     /* the field should usually be 0 when no flags are listed */        \
    6713             :     tt_int_op(rs_noflags->field, OP_EQ, expected_val_when_unused);      \
    6714             :     /* the field should be 1 when this flags islisted */                \
    6715             :     tt_int_op(rs->field, OP_EQ, 1);                                     \
    6716             :     tor_free(s);                                                        \
    6717             :     routerstatus_free(rs);                                              \
    6718             : } STMT_END
    6719             : 
    6720           1 :   FLAG("Authority", is_authority);
    6721           1 :   FLAG("BadExit", is_bad_exit);
    6722           1 :   FLAG("Exit", is_exit);
    6723           1 :   FLAG("Fast", is_fast);
    6724           1 :   FLAG("Guard", is_possible_guard);
    6725           1 :   FLAG("HSDir", is_hs_dir);
    6726           1 :   FLAG("Stable", is_stable);
    6727           1 :   FLAG("StaleDesc", is_staledesc);
    6728           1 :   FLAG("V2Dir", is_v2_dir);
    6729             : 
    6730             :   // These flags are assumed to be set whether they're declared or not.
    6731           1 :   expected_val_when_unused = 1;
    6732           1 :   FLAG("Running", is_flagged_running);
    6733           1 :   FLAG("Valid", is_valid);
    6734           1 :   expected_val_when_unused = 0;
    6735             : 
    6736             :   // These flags are no longer used, but still parsed.
    6737           1 :   FLAG("Named", is_named);
    6738           1 :   FLAG("Unnamed", is_unnamed);
    6739             : 
    6740           1 :  done:
    6741           1 :   tor_free(s);
    6742           1 :   routerstatus_free(rs);
    6743           1 :   routerstatus_free(rs_noflags);
    6744           1 :   memarea_drop_all(area);
    6745           1 :   smartlist_free(tokens);
    6746           1 : }
    6747             : 
    6748             : static void
    6749           1 : test_dir_assumed_flags(void *arg)
    6750             : {
    6751           1 :   (void)arg;
    6752           1 :   smartlist_t *tokens = smartlist_new();
    6753           1 :   memarea_t *area = memarea_new();
    6754           1 :   routerstatus_t *rs = NULL;
    6755             : 
    6756             :   /* We can assume that consensus method is higher than 24, so Running and
    6757             :    * Valid are always implicitly set */
    6758           1 :   const char *str1 =
    6759             :     "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
    6760             :        "192.168.0.1 9001 0\n"
    6761             :     "m thisoneislongerbecauseitisa256bitmddigest33\n"
    6762             :     "s Fast Guard Stable\n"
    6763             :     "pr Link=4\n";
    6764           1 :   const char *eos = str1 + strlen(str1);
    6765             : 
    6766           1 :   const char *cp = str1;
    6767           1 :   rs = routerstatus_parse_entry_from_string(area, &cp, eos, tokens, NULL, NULL,
    6768             :                                             24, FLAV_MICRODESC);
    6769           1 :   tt_assert(rs);
    6770           1 :   tt_assert(rs->is_flagged_running);
    6771           1 :   tt_assert(rs->is_valid);
    6772           1 :   tt_assert(! rs->is_exit);
    6773           1 :   tt_assert(rs->is_fast);
    6774             : 
    6775           1 :  done:
    6776           1 :   smartlist_free(tokens);
    6777           1 :   memarea_drop_all(area);
    6778           1 :   routerstatus_free(rs);
    6779           1 : }
    6780             : 
    6781             : static void
    6782           1 : test_dir_post_parsing(void *arg)
    6783             : {
    6784           1 :   (void) arg;
    6785             : 
    6786             :   /* Test the version parsing from an HS descriptor publish request. */
    6787             :   {
    6788           1 :     const char *end;
    6789           1 :     const char *prefix = "/tor/hs/";
    6790           1 :     int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
    6791           1 :     tt_int_op(version, OP_EQ, -1);
    6792           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6793           1 :     version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
    6794           1 :     tt_int_op(version, OP_EQ, -1);
    6795           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6796           1 :     version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
    6797           1 :     tt_int_op(version, OP_EQ, 3);
    6798           1 :     tt_str_op(end, OP_EQ, "/publish");
    6799           1 :     version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
    6800           1 :     tt_int_op(version, OP_EQ, 42);
    6801           1 :     tt_str_op(end, OP_EQ, "/publish");
    6802           1 :     version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
    6803           1 :     tt_int_op(version, OP_EQ, 18163);
    6804           1 :     tt_str_op(end, OP_EQ, "/publish");
    6805           1 :     version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
    6806           1 :     tt_int_op(version, OP_EQ, -1);
    6807           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6808           1 :     version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
    6809           1 :     tt_int_op(version, OP_EQ, -1);
    6810           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6811             :     /* Missing the '/' at the end of the prefix. */
    6812           1 :     version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
    6813           1 :     tt_int_op(version, OP_EQ, -1);
    6814           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6815           1 :     version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
    6816             :                                          prefix, &end);
    6817           1 :     tt_int_op(version, OP_EQ, -1);
    6818           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6819           1 :     version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
    6820             :                                          prefix, &end);
    6821           1 :     tt_int_op(version, OP_EQ, 3);
    6822           1 :     tt_str_op(end, OP_EQ, "/publish/random/junk");
    6823           1 :     version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
    6824           1 :     tt_int_op(version, OP_EQ, -1);
    6825           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6826             :     /* INT_MAX */
    6827           1 :     version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
    6828             :                                          prefix, &end);
    6829           1 :     tt_int_op(version, OP_EQ, INT_MAX);
    6830           1 :     tt_str_op(end, OP_EQ, "/publish");
    6831             :     /* INT_MAX + 1*/
    6832           1 :     version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
    6833             :                                          prefix, &end);
    6834           1 :     tt_int_op(version, OP_EQ, -1);
    6835           1 :     tt_ptr_op(end, OP_EQ, NULL);
    6836             :   }
    6837             : 
    6838           1 :  done:
    6839           1 :   ;
    6840           1 : }
    6841             : 
    6842             : static void
    6843           1 : test_dir_platform_str(void *arg)
    6844             : {
    6845           1 :   char platform[256];
    6846           1 :   (void)arg;
    6847           1 :   platform[0] = 0;
    6848           1 :   get_platform_str(platform, sizeof(platform));
    6849           1 :   tt_int_op((int)strlen(platform), OP_GT, 0);
    6850           1 :   tt_assert(!strcmpstart(platform, "Tor "));
    6851             : 
    6852           1 :   tor_version_t ver;
    6853             :   // make sure this is a tor version, a real actual tor version.
    6854           1 :   tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
    6855             : 
    6856           1 :   TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
    6857             : 
    6858             :   // Handle an example version.
    6859           1 :   tt_int_op(tor_version_parse_platform(
    6860             :         "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
    6861           1 :  done:
    6862           1 :   ;
    6863           1 : }
    6864             : 
    6865             : static void
    6866           1 : test_dir_format_versions_list(void *arg)
    6867             : {
    6868           1 :   (void)arg;
    6869           1 :   char *s = NULL;
    6870           1 :   config_line_t *lines = NULL;
    6871             : 
    6872           1 :   setup_capture_of_logs(LOG_WARN);
    6873           1 :   s = format_recommended_version_list(lines, 1);
    6874           1 :   tt_str_op(s, OP_EQ, "");
    6875             : 
    6876           1 :   tor_free(s);
    6877           1 :   config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
    6878           1 :   s = format_recommended_version_list(lines, 1);
    6879           1 :   tt_str_op(s, OP_EQ,  "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
    6880             : 
    6881           1 :   tor_free(s);
    6882           1 :   config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10   ");
    6883           1 :   s = format_recommended_version_list(lines, 1);
    6884           1 :   tt_str_op(s, OP_EQ,  "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
    6885             : 
    6886             :   /* There should be no warnings so far. */
    6887           1 :   expect_no_log_entry();
    6888             : 
    6889             :   /* Now try a line with a space in it. */
    6890           1 :   tor_free(s);
    6891           1 :   config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
    6892           1 :   s = format_recommended_version_list(lines, 1);
    6893           1 :   tt_str_op(s, OP_EQ,  "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
    6894             :             "1.3.3.7,1.3.3.8,4.4.4-rc");
    6895             : 
    6896           1 :   expect_single_log_msg_containing(
    6897             :           "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
    6898             : 
    6899             :   /* Start over, with a line containing a bogus version */
    6900           1 :   config_free_lines(lines);
    6901           1 :   lines = NULL;
    6902           1 :   tor_free(s);
    6903           1 :   mock_clean_saved_logs();
    6904           1 :   config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
    6905           1 :   s = format_recommended_version_list(lines,1);
    6906           1 :   tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
    6907           1 :   expect_single_log_msg_containing(
    6908             :         "Recommended version \"alpha-complex\" does not look valid.");
    6909             : 
    6910           1 :  done:
    6911           1 :   tor_free(s);
    6912           1 :   config_free_lines(lines);
    6913           1 :   teardown_capture_of_logs();
    6914           1 : }
    6915             : 
    6916             : static void
    6917           1 : test_dir_add_fingerprint(void *arg)
    6918             : {
    6919           1 :   (void)arg;
    6920           1 :   authdir_config_t *list;
    6921           1 :   int ret;
    6922           1 :   ed25519_secret_key_t seckey;
    6923           1 :   ed25519_public_key_t pubkey_good, pubkey_bad;
    6924             : 
    6925           1 :   authdir_init_fingerprint_list();
    6926           1 :   list = authdir_return_fingerprint_list();
    6927             : 
    6928           1 :   setup_capture_of_logs(LOG_WARN);
    6929             : 
    6930             :   /* RSA test - successful */
    6931           1 :   ret = add_rsa_fingerprint_to_dir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    6932             :                                    list, 0);
    6933           1 :   tt_int_op(ret, OP_EQ, 0);
    6934             : 
    6935             :   /* RSA test - failure */
    6936           1 :   ret = add_rsa_fingerprint_to_dir("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
    6937             :                                    list, 0);
    6938           1 :   tt_int_op(ret, OP_EQ, -1);
    6939             : 
    6940             :   /* ed25519 test - successful */
    6941           1 :   ed25519_secret_key_generate(&seckey, 0);
    6942           1 :   ed25519_public_key_generate(&pubkey_good, &seckey);
    6943             : 
    6944           1 :   ret = add_ed25519_to_dir(&pubkey_good, list, 0);
    6945           1 :   tt_int_op(ret, OP_EQ, 0);
    6946             : 
    6947             :   /* ed25519 test - failure */
    6948           1 :   digest256_from_base64((char *) pubkey_bad.pubkey, "gibberish");
    6949             : 
    6950           1 :   ret = add_ed25519_to_dir(&pubkey_bad, list, 0);
    6951           1 :   tt_int_op(ret, OP_EQ, -1);
    6952             : 
    6953           1 :  done:
    6954           1 :   teardown_capture_of_logs();
    6955           1 :   dirserv_free_fingerprint_list();
    6956           1 : }
    6957             : 
    6958             : static void
    6959           1 : test_dir_dirserv_load_fingerprint_file(void *arg)
    6960             : {
    6961           1 :   (void)arg;
    6962           1 :   char *fname = tor_strdup(get_fname("approved-routers"));
    6963             : 
    6964             :   // Neither RSA nor ed25519
    6965           1 :   const char *router_lines_invalid =
    6966             :     "!badexit notafingerprint";
    6967           1 :   const char *router_lines_too_long =
    6968             :     "!badexit thisisareallylongstringthatislongerthanafingerprint\n";
    6969           1 :   const char *router_lines_bad_fmt_str =
    6970             :     "!badexit ABCDEFGH|%1$p|%2$p|%3$p|%4$p|%5$p|%6$p\n";
    6971           1 :   const char *router_lines_valid_rsa =
    6972             :     "!badexit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
    6973           1 :   const char *router_lines_invalid_rsa =
    6974             :     "!badexit ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n";
    6975           1 :   const char *router_lines_valid_ed25519 =
    6976             :     "!badexit wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
    6977           1 :   const char *router_lines_invalid_ed25519 =
    6978             :     "!badexit --fLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx--\n";
    6979             : 
    6980             :   // Test: Invalid Fingerprint (not RSA or ed25519)
    6981           1 :   setup_capture_of_logs(LOG_NOTICE);
    6982           1 :   write_str_to_file(fname, router_lines_invalid, 0);
    6983           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    6984           1 :   expect_log_msg_containing("Invalid fingerprint");
    6985           1 :   teardown_capture_of_logs();
    6986             : 
    6987             :   // Test: Very long string (longer than RSA or ed25519 key)
    6988           1 :   setup_capture_of_logs(LOG_NOTICE);
    6989           1 :   write_str_to_file(fname, router_lines_too_long, 0);
    6990           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    6991           1 :   expect_log_msg_containing("Invalid fingerprint");
    6992           1 :   teardown_capture_of_logs();
    6993             : 
    6994             :   // Test: Format string exploit
    6995           1 :   setup_capture_of_logs(LOG_NOTICE);
    6996           1 :   write_str_to_file(fname, router_lines_bad_fmt_str, 0);
    6997           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    6998           1 :   expect_log_msg_containing("Invalid fingerprint");
    6999           1 :   teardown_capture_of_logs();
    7000             : 
    7001             :   // Test: Valid RSA
    7002           1 :   setup_capture_of_logs(LOG_NOTICE);
    7003           1 :   write_str_to_file(fname, router_lines_valid_rsa, 0);
    7004           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    7005           1 :   teardown_capture_of_logs();
    7006             : 
    7007             :   // Test: Invalid RSA
    7008           1 :   setup_capture_of_logs(LOG_NOTICE);
    7009           1 :   write_str_to_file(fname, router_lines_invalid_rsa, 0);
    7010           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    7011           1 :   expect_log_msg_containing("Invalid fingerprint");
    7012           1 :   teardown_capture_of_logs();
    7013             : 
    7014             :   // Test: Valid ed25519
    7015           1 :   setup_capture_of_logs(LOG_NOTICE);
    7016           1 :   write_str_to_file(fname, router_lines_valid_ed25519, 0);
    7017           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    7018           1 :   teardown_capture_of_logs();
    7019             : 
    7020             :   // Test: Invalid ed25519
    7021           1 :   setup_capture_of_logs(LOG_NOTICE);
    7022           1 :   write_str_to_file(fname, router_lines_invalid_ed25519, 0);
    7023           1 :   tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
    7024           1 :   expect_log_msg_containing("Invalid fingerprint");
    7025           1 :   teardown_capture_of_logs();
    7026             : 
    7027           1 :  done:
    7028           1 :   tor_free(fname);
    7029           1 :   dirserv_free_fingerprint_list();
    7030           1 : }
    7031             : 
    7032             : #define RESET_FP_LIST(list) STMT_BEGIN \
    7033             :     dirserv_free_fingerprint_list(); \
    7034             :     authdir_init_fingerprint_list(); \
    7035             :     list = authdir_return_fingerprint_list(); \
    7036             :   STMT_END
    7037             : 
    7038             : static void
    7039           1 : test_dir_dirserv_router_get_status(void *arg)
    7040             : {
    7041           1 :   authdir_config_t *list;
    7042           1 :   routerinfo_t *ri = NULL;
    7043           1 :   ed25519_keypair_t kp1, kp2;
    7044           1 :   char d[DIGEST_LEN];
    7045           1 :   char fp[HEX_DIGEST_LEN+1];
    7046           1 :   int ret;
    7047           1 :   const char *msg;
    7048           1 :   time_t now = time(NULL);
    7049             : 
    7050           1 :   (void)arg;
    7051             : 
    7052           1 :   crypto_pk_t *pk = pk_generate(0);
    7053             : 
    7054           1 :   authdir_init_fingerprint_list();
    7055           1 :   list = authdir_return_fingerprint_list();
    7056             : 
    7057             :   /* Set up the routerinfo */
    7058           1 :   ri = tor_malloc_zero(sizeof(routerinfo_t));
    7059           1 :   tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
    7060           1 :   ri->ipv4_orport = 9001;
    7061           1 :   ri->platform = tor_strdup("0.4.0.1-alpha");
    7062           1 :   ri->nickname = tor_strdup("Jessica");
    7063           1 :   ri->identity_pkey = crypto_pk_dup_key(pk);
    7064             : 
    7065           1 :   curve25519_keypair_t ri_onion_keypair;
    7066           1 :   curve25519_keypair_generate(&ri_onion_keypair, 0);
    7067           1 :   ri->onion_curve25519_pkey = tor_memdup(&ri_onion_keypair.pubkey,
    7068             :                                          sizeof(curve25519_public_key_t));
    7069             : 
    7070           1 :   ed25519_secret_key_from_seed(&kp1.seckey,
    7071             :                           (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
    7072           1 :   ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
    7073           1 :   ed25519_secret_key_from_seed(&kp2.seckey,
    7074             :                           (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    7075           1 :   ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
    7076           1 :   ri->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
    7077             :                                          CERT_TYPE_ID_SIGNING,
    7078             :                                          &kp2.pubkey,
    7079             :                                          now, 86400,
    7080             :                                          CERT_FLAG_INCLUDE_SIGNING_KEY);
    7081             : 
    7082           1 :   crypto_pk_get_digest(ri->identity_pkey, d);
    7083           1 :   base16_encode(fp, HEX_DIGEST_LEN + 1, d, DIGEST_LEN);
    7084             : 
    7085             :   /* Try on an empty fingerprint list */
    7086           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7087           1 :   tt_int_op(ret, OP_EQ, 0);
    7088           1 :   RESET_FP_LIST(list);
    7089             : 
    7090           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7091           1 :   tt_int_op(ret, OP_EQ, 0);
    7092           1 :   RESET_FP_LIST(list);
    7093             : 
    7094             :   /* Try an accepted router */
    7095           1 :   add_rsa_fingerprint_to_dir(fp, list, 0);
    7096           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7097           1 :   tt_int_op(ret, OP_EQ, 0);
    7098           1 :   RESET_FP_LIST(list);
    7099             : 
    7100           1 :   add_ed25519_to_dir(&kp1.pubkey, list, 0);
    7101           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7102           1 :   tt_int_op(ret, OP_EQ, 0);
    7103           1 :   RESET_FP_LIST(list);
    7104             : 
    7105             :   /* Try a rejected router */
    7106           1 :   add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
    7107           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7108           1 :   tt_int_op(ret, OP_EQ, RTR_REJECT);
    7109           1 :   RESET_FP_LIST(list);
    7110             : 
    7111           1 :   add_ed25519_to_dir(&kp1.pubkey, list, RTR_REJECT);
    7112           1 :   ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
    7113           1 :   tt_int_op(ret, OP_EQ, RTR_REJECT);
    7114           1 :   RESET_FP_LIST(list);
    7115             : 
    7116           1 :  done:
    7117           1 :   dirserv_free_fingerprint_list();
    7118           1 :   routerinfo_free(ri);
    7119           1 :   crypto_pk_free(pk);
    7120           1 : }
    7121             : 
    7122             : static void
    7123           1 : test_dir_dirserv_would_reject_router(void *arg)
    7124             : {
    7125           1 :   authdir_config_t *list;
    7126           1 :   routerstatus_t rs;
    7127           1 :   vote_routerstatus_t vrs;
    7128           1 :   ed25519_keypair_t kp;
    7129           1 :   char fp[HEX_DIGEST_LEN+1];
    7130             : 
    7131           1 :   (void)arg;
    7132             : 
    7133           1 :   authdir_init_fingerprint_list();
    7134           1 :   list = authdir_return_fingerprint_list();
    7135             : 
    7136             :   /* Set up the routerstatus */
    7137           1 :   memset(&rs, 0, sizeof(rs));
    7138           1 :   tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
    7139           1 :   rs.ipv4_orport = 9001;
    7140           1 :   strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
    7141           1 :   memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
    7142             : 
    7143           1 :   ed25519_secret_key_from_seed(&kp.seckey,
    7144             :                           (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
    7145           1 :   ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
    7146             : 
    7147           1 :   base16_encode(fp, HEX_DIGEST_LEN + 1, rs.identity_digest, DIGEST_LEN);
    7148             : 
    7149             :   /* Setup the vote_routerstatus_t. */
    7150           1 :   memcpy(vrs.ed25519_id, &kp.pubkey, ED25519_PUBKEY_LEN);
    7151             : 
    7152             :   /* Try an empty fingerprint list */
    7153           1 :   tt_assert(!dirserv_would_reject_router(&rs, &vrs));
    7154           1 :   RESET_FP_LIST(list);
    7155             : 
    7156           1 :   tt_assert(!dirserv_would_reject_router(&rs, &vrs));
    7157           1 :   RESET_FP_LIST(list);
    7158             : 
    7159             :   /* Try an accepted router */
    7160           1 :   add_rsa_fingerprint_to_dir(fp, list, 0);
    7161           1 :   tt_assert(!dirserv_would_reject_router(&rs, &vrs));
    7162           1 :   RESET_FP_LIST(list);
    7163             : 
    7164           1 :   add_ed25519_to_dir(&kp.pubkey, list, 0);
    7165           1 :   tt_assert(!dirserv_would_reject_router(&rs, &vrs));
    7166           1 :   RESET_FP_LIST(list);
    7167             : 
    7168             :   /* Try a rejected router */
    7169           1 :   add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
    7170           1 :   tt_assert(dirserv_would_reject_router(&rs, &vrs));
    7171           1 :   RESET_FP_LIST(list);
    7172             : 
    7173           1 :   add_ed25519_to_dir(&kp.pubkey, list, RTR_REJECT);
    7174           1 :   tt_assert(dirserv_would_reject_router(&rs, &vrs));
    7175           1 :   RESET_FP_LIST(list);
    7176             : 
    7177           1 :  done:
    7178           1 :   dirserv_free_fingerprint_list();
    7179           1 : }
    7180             : 
    7181             : static void
    7182           1 : test_dir_dirserv_add_own_fingerprint(void *arg)
    7183             : {
    7184           1 :   authdir_config_t *list;
    7185           1 :   char digest[DIGEST_LEN];
    7186           1 :   crypto_pk_t *pk = pk_generate(0);
    7187             : 
    7188           1 :   (void)arg;
    7189             : 
    7190           1 :   init_mock_ed_keys(pk);
    7191           1 :   authdir_init_fingerprint_list();
    7192           1 :   list = authdir_return_fingerprint_list();
    7193           1 :   dirserv_add_own_fingerprint(pk, get_master_identity_key());
    7194             : 
    7195             :   /* Check if we have a RSA key. */
    7196           1 :   crypto_pk_get_digest(pk, digest);
    7197           1 :   tt_assert(digestmap_get(list->status_by_digest, digest));
    7198             : 
    7199             :   /* Check if we have a ed25519 key. */
    7200           1 :   tt_assert(digest256map_get(list->status_by_digest256,
    7201             :                              get_master_identity_key()->pubkey));
    7202             : 
    7203           1 :   RESET_FP_LIST(list);
    7204             : 
    7205           1 :  done:
    7206           1 :   dirserv_free_fingerprint_list();
    7207           1 :   crypto_pk_free(pk);
    7208           1 : }
    7209             : 
    7210             : #ifndef COCCI
    7211             : #define DIR_LEGACY(name)                             \
    7212             :   { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
    7213             : 
    7214             : #define DIR(name,flags)                              \
    7215             :   { #name, test_dir_##name, (flags), NULL, NULL }
    7216             : 
    7217             : /* where arg is a string constant */
    7218             : #define DIR_ARG(name,flags,arg)                      \
    7219             :   { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
    7220             : #endif /* !defined(COCCI) */
    7221             : 
    7222             : struct testcase_t dir_tests[] = {
    7223             :   DIR_LEGACY(nicknames),
    7224             :   /* extrainfo without any stats */
    7225             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, ""),
    7226             :   /* on a bridge */
    7227             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, "b"),
    7228             :   /* extrainfo with basic stats */
    7229             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, "e"),
    7230             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, "be"),
    7231             :   /* extrainfo with all stats */
    7232             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, "es"),
    7233             :   DIR_ARG(formats_rsa_ed25519, TT_FORK, "bes"),
    7234             :   DIR(routerinfo_parsing, 0),
    7235             :   DIR(extrainfo_parsing, 0),
    7236             :   DIR(parse_router_list, TT_FORK),
    7237             :   DIR(load_routers, TT_FORK),
    7238             :   DIR(load_extrainfo, TT_FORK),
    7239             :   DIR(getinfo_extra, 0),
    7240             :   DIR_LEGACY(versions),
    7241             :   DIR_LEGACY(fp_pairs),
    7242             :   DIR(split_fps, 0),
    7243             :   DIR_LEGACY(measured_bw_kb),
    7244             :   DIR_LEGACY(measured_bw_kb_line_is_after_headers),
    7245             :   DIR_LEGACY(measured_bw_kb_cache),
    7246             :   DIR_LEGACY(dirserv_read_measured_bandwidths),
    7247             :   DIR(bwauth_bw_file_digest256, 0),
    7248             :   DIR_LEGACY(param_voting),
    7249             :   DIR(param_voting_lookup, 0),
    7250             :   DIR_LEGACY(v3_networkstatus),
    7251             :   DIR(random_weighted, 0),
    7252             :   DIR(scale_bw, 0),
    7253             :   DIR_LEGACY(clip_unmeasured_bw_kb),
    7254             :   DIR_LEGACY(clip_unmeasured_bw_kb_alt),
    7255             :   DIR(fmt_control_ns, 0),
    7256             :   DIR(dirserv_set_routerstatus_testing, TT_FORK),
    7257             :   DIR(http_handling, 0),
    7258             :   DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
    7259             :   DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
    7260             :   DIR(purpose_needs_anonymity_returns_true_by_default, 0),
    7261             :   DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
    7262             :   DIR(post_parsing, 0),
    7263             :   DIR(fetch_type, 0),
    7264             :   DIR(packages, 0),
    7265             :   DIR(download_status_random_backoff, 0),
    7266             :   DIR(download_status_random_backoff_ranges, 0),
    7267             :   DIR(download_status_increment, TT_FORK),
    7268             :   DIR(authdir_type_to_string, 0),
    7269             :   DIR(conn_purpose_to_string, 0),
    7270             :   DIR(should_use_directory_guards, 0),
    7271             :   DIR(should_not_init_request_to_ourselves, TT_FORK),
    7272             :   DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
    7273             :   DIR(should_init_request_to_dir_auths, 0),
    7274             :   DIR(dump_unparseable_descriptors, 0),
    7275             :   DIR(populate_dump_desc_fifo, 0),
    7276             :   DIR(populate_dump_desc_fifo_2, 0),
    7277             :   DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
    7278             :   DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
    7279             :   DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
    7280             :   DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
    7281             :   DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
    7282             :   DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
    7283             :   DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
    7284             :   DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
    7285             :   DIR(assumed_flags, 0),
    7286             :   DIR(matching_flags, 0),
    7287             :   DIR(networkstatus_compute_bw_weights_v10, 0),
    7288             :   DIR(platform_str, 0),
    7289             :   DIR(format_versions_list, TT_FORK),
    7290             :   DIR(add_fingerprint, TT_FORK),
    7291             :   DIR(dirserv_load_fingerprint_file, TT_FORK),
    7292             :   DIR(dirserv_router_get_status, TT_FORK),
    7293             :   DIR(dirserv_would_reject_router, TT_FORK),
    7294             :   DIR(dirserv_add_own_fingerprint, TT_FORK),
    7295             :   END_OF_TESTCASES
    7296             : };

Generated by: LCOV version 1.14