tor

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

test_nodelist.c (46750B)


      1 /* Copyright (c) 2007-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file test_nodelist.c
      6 * \brief Unit tests for nodelist related functions.
      7 **/
      8 
      9 #define NODELIST_PRIVATE
     10 #define NETWORKSTATUS_PRIVATE
     11 
     12 #include "core/or/or.h"
     13 #include "lib/crypt_ops/crypto_rand.h"
     14 #include "lib/crypt_ops/crypto_format.h"
     15 #include "feature/nodelist/describe.h"
     16 #include "feature/nodelist/networkstatus.h"
     17 #include "feature/nodelist/nodefamily.h"
     18 #include "feature/nodelist/nodelist.h"
     19 #include "feature/nodelist/torcert.h"
     20 
     21 #include "core/or/extend_info_st.h"
     22 #include "feature/dirauth/dirvote.h"
     23 #include "feature/nodelist/fmt_routerstatus.h"
     24 #include "feature/nodelist/microdesc_st.h"
     25 #include "feature/nodelist/networkstatus_st.h"
     26 #include "feature/nodelist/node_st.h"
     27 #include "feature/nodelist/nodefamily_st.h"
     28 #include "feature/nodelist/routerinfo_st.h"
     29 #include "feature/nodelist/routerstatus_st.h"
     30 
     31 #include "test/test.h"
     32 #include "test/log_test_helpers.h"
     33 
     34 /** Test the case when node_get_by_id() returns NULL,
     35 * node_get_verbose_nickname_by_id should return the base 16 encoding
     36 * of the id.
     37 */
     38 static void
     39 test_nodelist_node_get_verbose_nickname_by_id_null_node(void *arg)
     40 {
     41  char vname[MAX_VERBOSE_NICKNAME_LEN+1];
     42  const char ID[] = "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     43                    "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
     44  (void) arg;
     45 
     46  /* make sure node_get_by_id returns NULL */
     47  tt_assert(!node_get_by_id(ID));
     48  node_get_verbose_nickname_by_id(ID, vname);
     49  tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
     50 done:
     51  return;
     52 }
     53 
     54 /** For routers without named flag, get_verbose_nickname should return
     55 * "Fingerprint~Nickname"
     56 */
     57 static void
     58 test_nodelist_node_get_verbose_nickname_not_named(void *arg)
     59 {
     60  node_t mock_node;
     61  routerstatus_t mock_rs;
     62 
     63  char vname[MAX_VERBOSE_NICKNAME_LEN+1];
     64 
     65  (void) arg;
     66 
     67  memset(&mock_node, 0, sizeof(node_t));
     68  memset(&mock_rs, 0, sizeof(routerstatus_t));
     69 
     70  /* verbose nickname should use ~ instead of = for unnamed routers */
     71  strlcpy(mock_rs.nickname, "TestOR", sizeof(mock_rs.nickname));
     72  mock_node.rs = &mock_rs;
     73  memcpy(mock_node.identity,
     74          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     75          "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
     76          DIGEST_LEN);
     77  node_get_verbose_nickname(&mock_node, vname);
     78  tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
     79 
     80 done:
     81  return;
     82 }
     83 
     84 /** A node should be considered a directory server if it has an open dirport
     85 * or it accepts tunnelled directory requests.
     86 */
     87 static void
     88 test_nodelist_node_is_dir(void *arg)
     89 {
     90  (void)arg;
     91 
     92  routerstatus_t rs;
     93  routerinfo_t ri;
     94  node_t node;
     95  memset(&node, 0, sizeof(node_t));
     96  memset(&rs, 0, sizeof(routerstatus_t));
     97  memset(&ri, 0, sizeof(routerinfo_t));
     98 
     99  tt_assert(!node_is_dir(&node));
    100 
    101  node.rs = &rs;
    102  tt_assert(!node_is_dir(&node));
    103 
    104  rs.is_v2_dir = 1;
    105  tt_assert(node_is_dir(&node));
    106 
    107  rs.is_v2_dir = 0;
    108  rs.ipv4_dirport = 1;
    109  tt_assert(! node_is_dir(&node));
    110 
    111  node.rs = NULL;
    112  tt_assert(!node_is_dir(&node));
    113  node.ri = &ri;
    114  ri.supports_tunnelled_dir_requests = 1;
    115  tt_assert(node_is_dir(&node));
    116  ri.supports_tunnelled_dir_requests = 0;
    117  ri.ipv4_dirport = 1;
    118  tt_assert(! node_is_dir(&node));
    119 
    120 done:
    121  return;
    122 }
    123 
    124 static networkstatus_t *dummy_ns = NULL;
    125 static networkstatus_t *
    126 mock_networkstatus_get_latest_consensus(void)
    127 {
    128  return dummy_ns;
    129 }
    130 static networkstatus_t *
    131 mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
    132 {
    133  tor_assert(f == FLAV_MICRODESC);
    134  return dummy_ns;
    135 }
    136 
    137 static void
    138 test_nodelist_ed_id(void *arg)
    139 {
    140 #define N_NODES 5
    141  routerstatus_t *rs[N_NODES];
    142  microdesc_t *md[N_NODES];
    143  routerinfo_t *ri[N_NODES];
    144  networkstatus_t *ns;
    145  int i;
    146  (void)arg;
    147 
    148  ns = tor_malloc_zero(sizeof(networkstatus_t));
    149  ns->flavor = FLAV_MICRODESC;
    150  ns->routerstatus_list = smartlist_new();
    151  dummy_ns = ns;
    152  MOCK(networkstatus_get_latest_consensus,
    153       mock_networkstatus_get_latest_consensus);
    154  MOCK(networkstatus_get_latest_consensus_by_flavor,
    155       mock_networkstatus_get_latest_consensus_by_flavor);
    156 
    157  /* Make a bunch of dummy objects that we can play around with.  Only set the
    158     necessary fields */
    159 
    160  for (i = 0; i < N_NODES; ++i) {
    161    rs[i] = tor_malloc_zero(sizeof(*rs[i]));
    162    md[i] = tor_malloc_zero(sizeof(*md[i]));
    163    ri[i] = tor_malloc_zero(sizeof(*ri[i]));
    164 
    165    crypto_rand(md[i]->digest, sizeof(md[i]->digest));
    166    md[i]->ed25519_identity_pkey = tor_malloc(sizeof(ed25519_public_key_t));
    167    crypto_rand((char*)md[i]->ed25519_identity_pkey,
    168                sizeof(ed25519_public_key_t));
    169    crypto_rand(rs[i]->identity_digest, sizeof(rs[i]->identity_digest));
    170    memcpy(ri[i]->cache_info.identity_digest, rs[i]->identity_digest,
    171           DIGEST_LEN);
    172    memcpy(rs[i]->descriptor_digest, md[i]->digest, DIGEST256_LEN);
    173    ri[i]->cache_info.signing_key_cert = tor_malloc_zero(sizeof(tor_cert_t));
    174    memcpy(&ri[i]->cache_info.signing_key_cert->signing_key,
    175           md[i]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
    176 
    177    if (i < 3)
    178      smartlist_add(ns->routerstatus_list, rs[i]);
    179  }
    180 
    181  tt_int_op(0, OP_EQ, smartlist_len(nodelist_get_list()));
    182 
    183  nodelist_set_consensus(ns);
    184 
    185  tt_int_op(3, OP_EQ, smartlist_len(nodelist_get_list()));
    186 
    187  /* No Ed25519 info yet, so nothing has an ED id. */
    188  tt_ptr_op(NULL, OP_EQ, node_get_by_ed25519_id(md[0]->ed25519_identity_pkey));
    189 
    190  /* Register the first one by md, then look it up. */
    191  node_t *n = nodelist_add_microdesc(md[0]);
    192  tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[0]->ed25519_identity_pkey));
    193 
    194  /* Register the second by ri, then look it up. */
    195  routerinfo_t *ri_old = NULL;
    196  n = nodelist_set_routerinfo(ri[1], &ri_old);
    197  tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[1]->ed25519_identity_pkey));
    198  tt_ptr_op(ri_old, OP_EQ, NULL);
    199 
    200  /* Register it by md too. */
    201  node_t *n2 = nodelist_add_microdesc(md[1]);
    202  tt_ptr_op(n2, OP_EQ, n);
    203  tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[1]->ed25519_identity_pkey));
    204 
    205  /* Register the 4th by ri only -- we never put it into the networkstatus,
    206   * so it has to be independent */
    207  node_t *n3 = nodelist_set_routerinfo(ri[3], &ri_old);
    208  tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
    209  tt_ptr_op(ri_old, OP_EQ, NULL);
    210  tt_int_op(4, OP_EQ, smartlist_len(nodelist_get_list()));
    211 
    212  /* Register the 5th by ri only, and rewrite its ed25519 pubkey to be
    213   * the same as the 4th, to test the duplicate ed25519 key logging in
    214   * nodelist.c */
    215  memcpy(md[4]->ed25519_identity_pkey, md[3]->ed25519_identity_pkey,
    216         sizeof(ed25519_public_key_t));
    217  memcpy(&ri[4]->cache_info.signing_key_cert->signing_key,
    218         md[3]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
    219 
    220  setup_capture_of_logs(LOG_NOTICE);
    221  node_t *n4 = nodelist_set_routerinfo(ri[4], &ri_old);
    222  tt_ptr_op(ri_old, OP_EQ, NULL);
    223  tt_int_op(5, OP_EQ, smartlist_len(nodelist_get_list()));
    224  tt_ptr_op(n4, OP_NE, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
    225  tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
    226  expect_log_msg_containing("Reused ed25519_id");
    227 
    228 done:
    229  teardown_capture_of_logs();
    230  for (i = 0; i < N_NODES; ++i) {
    231    tor_free(rs[i]);
    232    tor_free(md[i]->ed25519_identity_pkey);
    233    tor_free(md[i]);
    234    tor_free(ri[i]->cache_info.signing_key_cert);
    235    tor_free(ri[i]);
    236  }
    237  smartlist_clear(ns->routerstatus_list);
    238  networkstatus_vote_free(ns);
    239  UNMOCK(networkstatus_get_latest_consensus);
    240  UNMOCK(networkstatus_get_latest_consensus_by_flavor);
    241 #undef N_NODES
    242 }
    243 
    244 static void
    245 test_nodelist_nodefamily(void *arg)
    246 {
    247  (void)arg;
    248  /* hex ID digests */
    249  const char h1[] = "5B435D6869206861206C65207363617270652070";
    250  const char h2[] = "75C3B220616E6461726520696E206769726F2061";
    251  const char h3[] = "2074726F766172206461206D616E67696172652C";
    252  const char h4[] = "206D656E747265206E6F6E2076616C65206C2769";
    253  const char h5[] = "6E766572736F2E202D2D5072696D6F204C657669";
    254 
    255  /* binary ID digests */
    256  uint8_t d1[DIGEST_LEN], d2[DIGEST_LEN], d3[DIGEST_LEN], d4[DIGEST_LEN],
    257    d5[DIGEST_LEN];
    258  base16_decode((char*)d1, sizeof(d1), h1, strlen(h1));
    259  base16_decode((char*)d2, sizeof(d2), h2, strlen(h2));
    260  base16_decode((char*)d3, sizeof(d3), h3, strlen(h3));
    261  base16_decode((char*)d4, sizeof(d4), h4, strlen(h4));
    262  base16_decode((char*)d5, sizeof(d5), h5, strlen(h5));
    263 
    264  char *enc=NULL, *enc2=NULL;
    265 
    266  nodefamily_t *nf1 = NULL;
    267  nodefamily_t *nf2 = NULL;
    268  nodefamily_t *nf3 = NULL;
    269 
    270  enc = nodefamily_format(NULL);
    271  tt_str_op(enc, OP_EQ, "");
    272  tor_free(enc);
    273 
    274  /* Make sure that sorting and de-duplication work. */
    275  tor_asprintf(&enc, "$%s hello", h1);
    276  nf1 = nodefamily_parse(enc, NULL, 0);
    277  tt_assert(nf1);
    278  tor_free(enc);
    279 
    280  tor_asprintf(&enc, "hello hello $%s hello", h1);
    281  nf2 = nodefamily_parse(enc, NULL, 0);
    282  tt_assert(nf2);
    283  tt_ptr_op(nf1, OP_EQ, nf2);
    284  tor_free(enc);
    285 
    286  tor_asprintf(&enc, "%s $%s hello", h1, h1);
    287  nf3 = nodefamily_parse(enc, NULL, 0);
    288  tt_assert(nf3);
    289  tt_ptr_op(nf1, OP_EQ, nf3);
    290  tor_free(enc);
    291 
    292  tt_assert(nodefamily_contains_rsa_id(nf1, d1));
    293  tt_assert(! nodefamily_contains_rsa_id(nf1, d2));
    294  tt_assert(nodefamily_contains_nickname(nf1, "hello"));
    295  tt_assert(nodefamily_contains_nickname(nf1, "HELLO"));
    296  tt_assert(! nodefamily_contains_nickname(nf1, "goodbye"));
    297 
    298  tt_int_op(nf1->refcnt, OP_EQ, 3);
    299  nodefamily_free(nf3);
    300  tt_int_op(nf1->refcnt, OP_EQ, 2);
    301 
    302  /* Try parsing with a provided self RSA digest. */
    303  nf3 = nodefamily_parse("hello ", d1, 0);
    304  tt_assert(nf3);
    305  tt_ptr_op(nf1, OP_EQ, nf3);
    306 
    307  /* Do we get the expected result when we re-encode? */
    308  tor_asprintf(&enc, "$%s hello", h1);
    309  enc2 = nodefamily_format(nf1);
    310  tt_str_op(enc2, OP_EQ, enc);
    311  tor_free(enc2);
    312  tor_free(enc);
    313 
    314  /* Make sure that we get a different result if we give a different digest. */
    315  nodefamily_free(nf3);
    316  tor_asprintf(&enc, "hello $%s hello", h3);
    317  nf3 = nodefamily_parse(enc, NULL, 0);
    318  tt_assert(nf3);
    319  tt_ptr_op(nf1, OP_NE, nf3);
    320  tor_free(enc);
    321 
    322  tt_assert(nodefamily_contains_rsa_id(nf3, d3));
    323  tt_assert(! nodefamily_contains_rsa_id(nf3, d2));
    324  tt_assert(! nodefamily_contains_rsa_id(nf3, d1));
    325  tt_assert(nodefamily_contains_nickname(nf3, "hello"));
    326  tt_assert(! nodefamily_contains_nickname(nf3, "goodbye"));
    327 
    328  nodefamily_free(nf1);
    329  nodefamily_free(nf2);
    330  nodefamily_free(nf3);
    331 
    332  /* Try one with several digests, all with nicknames appended, in different
    333     formats. */
    334  tor_asprintf(&enc, "%s $%s $%s=res $%s~ist", h1, h2, h3, h4);
    335  nf1 = nodefamily_parse(enc, d5, 0);
    336  tt_assert(nf1);
    337  tt_assert(nodefamily_contains_rsa_id(nf1, d1));
    338  tt_assert(nodefamily_contains_rsa_id(nf1, d2));
    339  tt_assert(nodefamily_contains_rsa_id(nf1, d3));
    340  tt_assert(nodefamily_contains_rsa_id(nf1, d4));
    341  tt_assert(nodefamily_contains_rsa_id(nf1, d5));
    342  /* Nicknames aren't preserved when ids are present, since node naming is
    343   * deprecated */
    344  tt_assert(! nodefamily_contains_nickname(nf3, "res"));
    345  tor_free(enc);
    346  tor_asprintf(&enc, "$%s $%s $%s $%s $%s", h4, h3, h1, h5, h2);
    347  enc2 = nodefamily_format(nf1);
    348  tt_str_op(enc, OP_EQ, enc2);
    349  tor_free(enc);
    350  tor_free(enc2);
    351 
    352  /* Try ones where we parse the empty string. */
    353  nf2 = nodefamily_parse("", NULL, 0);
    354  nf3 = nodefamily_parse("", d4, 0);
    355  tt_assert(nf2);
    356  tt_assert(nf3);
    357  tt_ptr_op(nf2, OP_NE, nf3);
    358 
    359  tt_assert(! nodefamily_contains_rsa_id(nf2, d4));
    360  tt_assert(nodefamily_contains_rsa_id(nf3, d4));
    361  tt_assert(! nodefamily_contains_rsa_id(nf2, d5));
    362  tt_assert(! nodefamily_contains_rsa_id(nf3, d5));
    363  tt_assert(! nodefamily_contains_nickname(nf2, "fred"));
    364  tt_assert(! nodefamily_contains_nickname(nf3, "bosco"));
    365 
    366  /* The NULL family should contain nothing. */
    367  tt_assert(! nodefamily_contains_rsa_id(NULL, d4));
    368  tt_assert(! nodefamily_contains_rsa_id(NULL, d5));
    369 
    370 done:
    371  tor_free(enc);
    372  tor_free(enc2);
    373  nodefamily_free(nf1);
    374  nodefamily_free(nf2);
    375  nodefamily_free(nf3);
    376  nodefamily_free_all();
    377 }
    378 
    379 static void
    380 test_nodelist_nodefamily_parse_err(void *arg)
    381 {
    382  (void)arg;
    383  nodefamily_t *nf1 = NULL;
    384  char *enc = NULL;
    385  const char *semibogus =
    386    "sdakljfdslkfjdsaklfjdkl9sdf " // too long for nickname
    387    "$jkASDFLkjsadfjhkl " // not hex
    388    "$7468696e67732d696e2d7468656d73656c766573 " // ok
    389    "reticulatogranulate "// ok
    390    "$73656d69616e7468726f706f6c6f676963616c6c79 " // too long for hex
    391    "$616273656e746d696e6465646e6573736573" // too short for hex
    392    ;
    393 
    394  setup_capture_of_logs(LOG_WARN);
    395 
    396  // We only get two items when we parse this.
    397  for (int reject = 0; reject <= 1; ++reject) {
    398    for (int log_at_warn = 0; log_at_warn <= 1; ++log_at_warn) {
    399      unsigned flags = log_at_warn ? NF_WARN_MALFORMED : 0;
    400      flags |= reject ? NF_REJECT_MALFORMED : 0;
    401      nf1 = nodefamily_parse(semibogus, NULL, flags);
    402      if (reject) {
    403        tt_assert(nf1 == NULL);
    404      } else {
    405        tt_assert(nf1);
    406        enc = nodefamily_format(nf1);
    407        tt_str_op(enc, OP_EQ,
    408                  "$7468696E67732D696E2D7468656D73656C766573 "
    409                  "reticulatogranulate");
    410        tor_free(enc);
    411      }
    412 
    413      if (log_at_warn) {
    414        expect_log_msg_containing("$616273656e746d696e6465646e6573736573");
    415        expect_log_msg_containing("sdakljfdslkfjdsaklfjdkl9sdf");
    416      } else {
    417        tt_int_op(mock_saved_log_n_entries(), OP_EQ, 0);
    418      }
    419      mock_clean_saved_logs();
    420    }
    421  }
    422 
    423 done:
    424  tor_free(enc);
    425  nodefamily_free(nf1);
    426  teardown_capture_of_logs();
    427 }
    428 
    429 static const node_t *
    430 mock_node_get_by_id(const char *id)
    431 {
    432  if (fast_memeq(id, "!!!!!!!!!!!!!!!!!!!!", DIGEST_LEN))
    433    return NULL;
    434 
    435  // use tor_free, not node_free.
    436  node_t *fake_node = tor_malloc_zero(sizeof(node_t));
    437  memcpy(fake_node->identity, id, DIGEST_LEN);
    438  return fake_node;
    439 }
    440 
    441 static const node_t *
    442 mock_node_get_by_nickname(const char *nn, unsigned flags)
    443 {
    444  (void)flags;
    445  if (!strcmp(nn, "nonesuch"))
    446    return NULL;
    447 
    448  // use tor_free, not node_free.
    449  node_t *fake_node = tor_malloc_zero(sizeof(node_t));
    450  strlcpy(fake_node->identity, nn, DIGEST_LEN);
    451  return fake_node;
    452 }
    453 
    454 static void
    455 test_nodelist_nodefamily_lookup(void *arg)
    456 {
    457  (void)arg;
    458  MOCK(node_get_by_nickname, mock_node_get_by_nickname);
    459  MOCK(node_get_by_id, mock_node_get_by_id);
    460  smartlist_t *sl = smartlist_new();
    461  nodefamily_t *nf1 = NULL;
    462  char *mem_op_hex_tmp = NULL;
    463 
    464  // 'null' is allowed.
    465  nodefamily_add_nodes_to_smartlist(NULL, sl);
    466  tt_int_op(smartlist_len(sl), OP_EQ, 0);
    467 
    468  // Try a real family
    469  nf1 = nodefamily_parse("$EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE "
    470                         "$2121212121212121212121212121212121212121 "
    471                         "$3333333333333333333333333333333333333333 "
    472                         "erewhon nonesuch", NULL, 0);
    473  tt_assert(nf1);
    474  nodefamily_add_nodes_to_smartlist(nf1, sl);
    475  // There were 5 elements; 2 were dropped because the mocked lookup failed.
    476  tt_int_op(smartlist_len(sl), OP_EQ, 3);
    477 
    478  const node_t *n = smartlist_get(sl, 0);
    479  test_memeq_hex(n->identity, "3333333333333333333333333333333333333333");
    480  n = smartlist_get(sl, 1);
    481  test_memeq_hex(n->identity, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
    482  n = smartlist_get(sl, 2);
    483  tt_str_op(n->identity, OP_EQ, "erewhon");
    484 
    485 done:
    486  UNMOCK(node_get_by_nickname);
    487  UNMOCK(node_get_by_id);
    488  SMARTLIST_FOREACH(sl, node_t *, fake_node, tor_free(fake_node));
    489  smartlist_free(sl);
    490  nodefamily_free(nf1);
    491  tor_free(mem_op_hex_tmp);
    492 }
    493 
    494 static void
    495 test_nodelist_nickname_matches(void *arg)
    496 {
    497  (void)arg;
    498  node_t mock_node;
    499  routerstatus_t mock_rs;
    500  memset(&mock_node, 0, sizeof(mock_node));
    501  memset(&mock_rs, 0, sizeof(mock_rs));
    502 
    503  strlcpy(mock_rs.nickname, "evilgeniuses", sizeof(mock_rs.nickname));
    504  mock_node.rs = &mock_rs;
    505  memcpy(mock_node.identity, ".forabettertomorrow.", DIGEST_LEN);
    506 
    507 #define match(x) tt_assert(node_nickname_matches(&mock_node, (x)))
    508 #define no_match(x) tt_assert(! node_nickname_matches(&mock_node, (x)))
    509 
    510  match("evilgeniuses");
    511  match("EvilGeniuses");
    512  match("EvilGeniuses");
    513  match("2e666f7261626574746572746f6d6f72726f772e");
    514  match("2E666F7261626574746572746F6D6F72726F772E");
    515  match("$2e666f7261626574746572746f6d6f72726f772e");
    516  match("$2E666F7261626574746572746F6D6F72726F772E");
    517  match("$2E666F7261626574746572746F6D6F72726F772E~evilgeniuses");
    518  match("$2E666F7261626574746572746F6D6F72726F772E~EVILGENIUSES");
    519 
    520  no_match("evilgenius");
    521  no_match("evilgeniuseses");
    522  no_match("evil.genius");
    523  no_match("$2E666F7261626574746572746F6D6F72726FFFFF");
    524  no_match("2E666F7261626574746572746F6D6F72726FFFFF");
    525  no_match("$2E666F7261626574746572746F6D6F72726F772E~fred");
    526  no_match("$2E666F7261626574746572746F6D6F72726F772E=EVILGENIUSES");
    527 done:
    528  ;
    529 }
    530 
    531 static void
    532 test_nodelist_node_nodefamily(void *arg)
    533 {
    534  (void)arg;
    535  node_t mock_node1;
    536  routerstatus_t mock_rs;
    537  microdesc_t mock_md;
    538 
    539  node_t mock_node2;
    540  routerinfo_t mock_ri;
    541 
    542  smartlist_t *nodes=smartlist_new();
    543 
    544  memset(&mock_node1, 0, sizeof(mock_node1));
    545  memset(&mock_node2, 0, sizeof(mock_node2));
    546  memset(&mock_rs, 0, sizeof(mock_rs));
    547  memset(&mock_md, 0, sizeof(mock_md));
    548  memset(&mock_ri, 0, sizeof(mock_ri));
    549 
    550  mock_node1.rs = &mock_rs;
    551  mock_node1.md = &mock_md;
    552 
    553  mock_node2.ri = &mock_ri;
    554 
    555  strlcpy(mock_rs.nickname, "nodeone", sizeof(mock_rs.nickname));
    556  mock_ri.nickname = tor_strdup("nodetwo");
    557 
    558  memcpy(mock_node1.identity, "NodeOneNode1NodeOne1", DIGEST_LEN);
    559  memcpy(mock_node2.identity, "SecondNodeWe'reTestn", DIGEST_LEN);
    560 
    561  // empty families.
    562  tt_assert(! node_family_list_contains(&mock_node1, &mock_node2));
    563  tt_assert(! node_family_list_contains(&mock_node2, &mock_node1));
    564 
    565  // Families contain nodes, but not these nodes
    566  mock_ri.declared_family = smartlist_new();
    567  smartlist_add(mock_ri.declared_family, (char*)"NodeThree");
    568  mock_md.family = nodefamily_parse("NodeFour", NULL, 0);
    569  tt_assert(! node_family_list_contains(&mock_node1, &mock_node2));
    570  tt_assert(! node_family_list_contains(&mock_node2, &mock_node1));
    571 
    572  // Families contain one another.
    573  smartlist_add(mock_ri.declared_family, (char*)
    574                "4e6f64654f6e654e6f6465314e6f64654f6e6531");
    575  tt_assert(! node_family_list_contains(&mock_node1, &mock_node2));
    576  tt_assert(node_family_list_contains(&mock_node2, &mock_node1));
    577 
    578  nodefamily_free(mock_md.family);
    579  mock_md.family = nodefamily_parse(
    580            "NodeFour "
    581            "5365636f6e644e6f64655765277265546573746e", NULL, 0);
    582  tt_assert(node_family_list_contains(&mock_node1, &mock_node2));
    583  tt_assert(node_family_list_contains(&mock_node2, &mock_node1));
    584 
    585  // Try looking up families now.
    586  MOCK(node_get_by_nickname, mock_node_get_by_nickname);
    587  MOCK(node_get_by_id, mock_node_get_by_id);
    588 
    589  node_lookup_declared_family_list(nodes, &mock_node1);
    590  tt_int_op(smartlist_len(nodes), OP_EQ, 2);
    591  const node_t *n = smartlist_get(nodes, 0);
    592  tt_mem_op(n->identity, OP_EQ, "SecondNodeWe'reTestn", DIGEST_LEN);
    593  n = smartlist_get(nodes, 1);
    594  tt_str_op(n->identity, OP_EQ, "nodefour");
    595 
    596  // free, try the other one.
    597  SMARTLIST_FOREACH(nodes, node_t *, x, tor_free(x));
    598  smartlist_clear(nodes);
    599 
    600  node_lookup_declared_family_list(nodes, &mock_node2);
    601  tt_int_op(smartlist_len(nodes), OP_EQ, 2);
    602  n = smartlist_get(nodes, 0);
    603  // This gets a truncated hex hex ID since it was looked up by name
    604  tt_str_op(n->identity, OP_EQ, "NodeThree");
    605  n = smartlist_get(nodes, 1);
    606  tt_str_op(n->identity, OP_EQ, "4e6f64654f6e654e6f6");
    607 
    608 done:
    609  UNMOCK(node_get_by_nickname);
    610  UNMOCK(node_get_by_id);
    611  smartlist_free(mock_ri.declared_family);
    612  nodefamily_free(mock_md.family);
    613  tor_free(mock_ri.nickname);
    614  // use tor_free, these aren't real nodes
    615  SMARTLIST_FOREACH(nodes, node_t *, x, tor_free(x));
    616  smartlist_free(nodes);
    617 }
    618 
    619 static void
    620 test_nodelist_nodefamily_canonicalize(void *arg)
    621 {
    622  (void)arg;
    623  char *c = NULL;
    624 
    625  c = nodefamily_canonicalize("", NULL, 0);
    626  tt_str_op(c, OP_EQ, "");
    627  tor_free(c);
    628 
    629  uint8_t own_id[20];
    630  memset(own_id, 0, sizeof(own_id));
    631  c = nodefamily_canonicalize(
    632           "alice BOB caroL %potrzebie !!!@#@# "
    633           "$bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=fred "
    634           "ffffffffffffffffffffffffffffffffffffffff "
    635           "$cccccccccccccccccccccccccccccccccccccccc ", own_id, 0);
    636  tt_str_op(c, OP_EQ,
    637           "!!!@#@# "
    638           "$0000000000000000000000000000000000000000 "
    639           "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB "
    640           "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC "
    641           "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF "
    642           "%potrzebie "
    643           "alice bob carol");
    644 
    645 done:
    646  tor_free(c);
    647 }
    648 
    649 /** format_node_description() should return
    650 * "Fingerprint~Nickname at IPv4 and [IPv6]".
    651 * The nickname and addresses are optional.
    652 */
    653 static void
    654 test_nodelist_format_node_description(void *arg)
    655 {
    656  char mock_digest[DIGEST_LEN];
    657  char mock_nickname[MAX_NICKNAME_LEN+1];
    658  tor_addr_t mock_null_ip;
    659  tor_addr_t mock_ipv4;
    660  tor_addr_t mock_ipv6;
    661  ed25519_public_key_t ed_id;
    662 
    663  char ndesc[NODE_DESC_BUF_LEN];
    664  const char *rv = NULL;
    665 
    666  (void) arg;
    667 
    668  /* Clear variables */
    669  memset(ndesc, 0, sizeof(ndesc));
    670  memset(mock_digest, 0, sizeof(mock_digest));
    671  memset(mock_nickname, 0, sizeof(mock_nickname));
    672  memset(&mock_null_ip, 0, sizeof(mock_null_ip));
    673  memset(&mock_ipv4, 0, sizeof(mock_ipv4));
    674  memset(&mock_ipv6, 0, sizeof(mock_ipv6));
    675 
    676  /* Set variables */
    677  memcpy(mock_digest,
    678         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    679         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    680         sizeof(mock_digest));
    681  strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
    682  tor_addr_parse(&mock_ipv4, "111.222.233.244");
    683  tor_addr_parse(&mock_ipv6, "[1111:2222:3333:4444:5555:6666:7777:8888]");
    684 
    685  /* Test function with variables */
    686  rv = format_node_description(ndesc,
    687                               mock_digest,
    688                               NULL,
    689                               NULL,
    690                               NULL,
    691                               NULL);
    692  tt_ptr_op(rv, OP_EQ, ndesc);
    693  tt_str_op(ndesc, OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    694 
    695  /* format node description should use ~ because named is deprecated */
    696  rv = format_node_description(ndesc,
    697                               mock_digest,
    698                               NULL,
    699                               mock_nickname,
    700                               NULL,
    701                               NULL);
    702  tt_ptr_op(rv, OP_EQ, ndesc);
    703  tt_str_op(ndesc, OP_EQ,
    704            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~""TestOR7890123456789");
    705 
    706  /* Try a null IP address, rather than NULL */
    707  rv = format_node_description(ndesc,
    708                               mock_digest,
    709                               NULL,
    710                               mock_nickname,
    711                               NULL,
    712                               &mock_null_ip);
    713  tt_ptr_op(rv, OP_EQ, ndesc);
    714  tt_str_op(ndesc, OP_EQ,
    715            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789");
    716 
    717  /* Try some real IP addresses */
    718  rv = format_node_description(ndesc,
    719                               mock_digest,
    720                               NULL,
    721                               NULL,
    722                               &mock_ipv4,
    723                               NULL);
    724  tt_ptr_op(rv, OP_EQ, ndesc);
    725  tt_str_op(ndesc, OP_EQ,
    726            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA at 111.222.233.244");
    727 
    728  rv = format_node_description(ndesc,
    729                               mock_digest,
    730                               NULL,
    731                               mock_nickname,
    732                               NULL,
    733                               &mock_ipv6);
    734  tt_ptr_op(rv, OP_EQ, ndesc);
    735  tt_str_op(ndesc, OP_EQ,
    736            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    737            "[1111:2222:3333:4444:5555:6666:7777:8888]");
    738 
    739  rv = format_node_description(ndesc,
    740                               mock_digest,
    741                               NULL,
    742                               mock_nickname,
    743                               &mock_ipv4,
    744                               &mock_ipv6);
    745  tt_ptr_op(rv, OP_EQ, ndesc);
    746  tt_str_op(ndesc, OP_EQ,
    747            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    748            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    749 
    750  /* Try some ed25519 keys. */
    751  int n = ed25519_public_from_base64(&ed_id,
    752              "+wBP6WVZzqKK+eTdwU7Hhb80xEm40FSZDBMNozTJpDE");
    753  tt_int_op(n,OP_EQ,0);
    754  rv = format_node_description(ndesc,
    755                               mock_digest,
    756                               &ed_id,
    757                               mock_nickname,
    758                               &mock_ipv4,
    759                               &mock_ipv6);
    760  tt_str_op(ndesc, OP_EQ,
    761            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 "
    762            "[+wBP6WVZzqKK+eTdwU7Hhb80xEm40FSZDBMNozTJpDE] at "
    763            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    764 
    765  /* test NULL handling */
    766  rv = format_node_description(NULL, NULL, NULL, NULL, NULL, NULL);
    767  tt_str_op(rv, OP_EQ, "<NULL BUFFER>");
    768 
    769  rv = format_node_description(ndesc, NULL, NULL, NULL, NULL, NULL);
    770  tt_ptr_op(rv, OP_EQ, ndesc);
    771  tt_str_op(rv, OP_EQ, "<NULL ID DIGEST>");
    772 
    773 done:
    774  return;
    775 }
    776 
    777 /** router_describe() is a wrapper for format_node_description(), see that
    778 * test for details.
    779 *
    780 * The routerinfo-only node_describe() tests are in this function,
    781 * so we can re-use the same mocked variables.
    782 */
    783 static void
    784 test_nodelist_router_describe(void *arg)
    785 {
    786  char mock_nickname[MAX_NICKNAME_LEN+1];
    787  routerinfo_t mock_ri_ipv4;
    788  routerinfo_t mock_ri_ipv6;
    789  routerinfo_t mock_ri_dual;
    790 
    791  const char *rv = NULL;
    792 
    793  (void) arg;
    794 
    795  /* Clear variables */
    796  memset(mock_nickname, 0, sizeof(mock_nickname));
    797  memset(&mock_ri_ipv4, 0, sizeof(mock_ri_ipv4));
    798  memset(&mock_ri_ipv6, 0, sizeof(mock_ri_ipv6));
    799  memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
    800 
    801  /* Set up the dual-stack routerinfo */
    802  memcpy(mock_ri_dual.cache_info.identity_digest,
    803         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    804         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    805         sizeof(mock_ri_dual.cache_info.identity_digest));
    806  strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
    807  mock_ri_dual.nickname = mock_nickname;
    808  tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
    809  tor_addr_parse(&mock_ri_dual.ipv6_addr,
    810                 "[1111:2222:3333:4444:5555:6666:7777:8888]");
    811 
    812  /* Create and modify the other routerinfos.
    813   * mock_nickname is referenced from all 3 routerinfos.
    814   * That's ok, all their memory is static. */
    815  memcpy(&mock_ri_ipv4, &mock_ri_dual, sizeof(mock_ri_ipv4));
    816  memcpy(&mock_ri_ipv6, &mock_ri_dual, sizeof(mock_ri_ipv6));
    817  /* Clear the unnecessary addresses */
    818  memset(&mock_ri_ipv4.ipv6_addr, 0, sizeof(mock_ri_ipv4.ipv6_addr));
    819  tor_addr_make_unspec(&mock_ri_ipv6.ipv4_addr);
    820 
    821  /* We don't test the no-nickname and no-IP cases, because they're covered by
    822   * format_node_description(), and we don't expect to see them in Tor code. */
    823 
    824  /* Try some real IP addresses */
    825  rv = router_describe(&mock_ri_ipv4);
    826  tt_str_op(rv, OP_EQ,
    827            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    828            "111.222.233.244");
    829 
    830  rv = router_describe(&mock_ri_ipv6);
    831  tt_str_op(rv, OP_EQ,
    832            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    833            "[1111:2222:3333:4444:5555:6666:7777:8888]");
    834 
    835  rv = router_describe(&mock_ri_dual);
    836  tt_str_op(rv, OP_EQ,
    837            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    838            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    839 
    840  /* test NULL handling */
    841  rv = router_describe(NULL);
    842  tt_str_op(rv, OP_EQ, "<null>");
    843 
    844  /* Now test a node with only these routerinfos */
    845  node_t mock_node;
    846  memset(&mock_node, 0, sizeof(mock_node));
    847  memcpy(mock_node.identity,
    848         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    849         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    850         sizeof(mock_node.identity));
    851 
    852  /* Try some real IP addresses */
    853  mock_node.ri = &mock_ri_ipv4;
    854  rv = node_describe(&mock_node);
    855  tt_str_op(rv, OP_EQ,
    856            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    857            "111.222.233.244");
    858 
    859  mock_node.ri = &mock_ri_ipv6;
    860  rv = node_describe(&mock_node);
    861  tt_str_op(rv, OP_EQ,
    862            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    863            "[1111:2222:3333:4444:5555:6666:7777:8888]");
    864 
    865  mock_node.ri = &mock_ri_dual;
    866  rv = node_describe(&mock_node);
    867  tt_str_op(rv, OP_EQ,
    868            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
    869            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    870 
    871 done:
    872  return;
    873 }
    874 
    875 /** node_describe() is a wrapper for format_node_description(), see that
    876 * test for details.
    877 *
    878 * The routerinfo-only and routerstatus-only node_describe() tests are in
    879 * test_nodelist_router_describe() and test_nodelist_routerstatus_describe(),
    880 * so we can re-use their mocked variables.
    881 */
    882 static void
    883 test_nodelist_node_describe(void *arg)
    884 {
    885  char mock_nickname[MAX_NICKNAME_LEN+1];
    886 
    887  const char *rv = NULL;
    888 
    889  (void) arg;
    890 
    891  /* Routerinfos */
    892  routerinfo_t mock_ri_dual;
    893 
    894  /* Clear variables */
    895  memset(mock_nickname, 0, sizeof(mock_nickname));
    896  memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
    897 
    898  /* Set up the dual-stack routerinfo */
    899  memcpy(mock_ri_dual.cache_info.identity_digest,
    900         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    901         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    902         sizeof(mock_ri_dual.cache_info.identity_digest));
    903  strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
    904  mock_ri_dual.nickname = mock_nickname;
    905  tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
    906  tor_addr_parse(&mock_ri_dual.ipv6_addr,
    907                 "[1111:2222:3333:4444:5555:6666:7777:8888]");
    908 
    909  /* Routerstatuses */
    910  routerstatus_t mock_rs_ipv4;
    911  routerstatus_t mock_rs_dual;
    912 
    913  /* Clear variables */
    914  memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
    915  memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
    916 
    917  /* Set up the dual-stack routerstatus */
    918  memcpy(mock_rs_dual.identity_digest,
    919         "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
    920         "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB",
    921         sizeof(mock_rs_dual.identity_digest));
    922  strlcpy(mock_rs_dual.nickname, "Bbb",
    923          sizeof(mock_rs_dual.nickname));
    924  tor_addr_parse(&mock_rs_dual.ipv4_addr, "2.2.2.2");
    925  tor_addr_parse(&mock_rs_dual.ipv6_addr,
    926                 "[bbbb::bbbb]");
    927 
    928  /* Create and modify the other routerstatus. */
    929  memcpy(&mock_rs_ipv4, &mock_rs_dual, sizeof(mock_rs_ipv4));
    930  /* Clear the unnecessary IPv6 address */
    931  memset(&mock_rs_ipv4.ipv6_addr, 0, sizeof(mock_rs_ipv4.ipv6_addr));
    932 
    933  /* Microdescs */
    934  microdesc_t mock_md_null;
    935  microdesc_t mock_md_ipv6;
    936 
    937  /* Clear variables */
    938  memset(&mock_md_null, 0, sizeof(mock_md_null));
    939  memset(&mock_md_ipv6, 0, sizeof(mock_md_ipv6));
    940 
    941  /* Set up the microdesc */
    942  tor_addr_parse(&mock_md_ipv6.ipv6_addr,
    943                 "[eeee::6000:6000]");
    944 
    945  /* Set up the node */
    946  node_t mock_node;
    947  memset(&mock_node, 0, sizeof(mock_node));
    948  memcpy(mock_node.identity,
    949         "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
    950         "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC",
    951         sizeof(mock_node.identity));
    952 
    953  /* Test that the routerinfo and routerstatus work separately, but the
    954   * identity comes from the node */
    955  mock_node.ri = &mock_ri_dual;
    956  mock_node.rs = NULL;
    957  mock_node.md = NULL;
    958  rv = node_describe(&mock_node);
    959  tt_str_op(rv, OP_EQ,
    960            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~TestOR7890123456789 at "
    961            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
    962 
    963  mock_node.ri = NULL;
    964  mock_node.rs = &mock_rs_ipv4;
    965  mock_node.md = NULL;
    966  rv = node_describe(&mock_node);
    967  tt_str_op(rv, OP_EQ,
    968            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    969            "2.2.2.2");
    970 
    971  mock_node.ri = NULL;
    972  mock_node.rs = &mock_rs_dual;
    973  mock_node.md = NULL;
    974  rv = node_describe(&mock_node);
    975  tt_str_op(rv, OP_EQ,
    976            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    977            "2.2.2.2 and [bbbb::bbbb]");
    978 
    979  /* Test that the routerstatus overrides the routerinfo */
    980  mock_node.ri = &mock_ri_dual;
    981  mock_node.rs = &mock_rs_ipv4;
    982  mock_node.md = NULL;
    983  rv = node_describe(&mock_node);
    984  tt_str_op(rv, OP_EQ,
    985            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    986            "2.2.2.2");
    987 
    988  mock_node.ri = &mock_ri_dual;
    989  mock_node.rs = &mock_rs_dual;
    990  mock_node.md = NULL;
    991  rv = node_describe(&mock_node);
    992  tt_str_op(rv, OP_EQ,
    993            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
    994            "2.2.2.2 and [bbbb::bbbb]");
    995 
    996  /* Test that the microdesc IPv6 is used if the routerinfo doesn't have IPv6
    997   */
    998  mock_node.ri = NULL;
    999  mock_node.rs = &mock_rs_ipv4;
   1000  mock_node.md = &mock_md_ipv6;
   1001  rv = node_describe(&mock_node);
   1002  tt_str_op(rv, OP_EQ,
   1003            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1004            "2.2.2.2 and [eeee::6000:6000]");
   1005 
   1006  mock_node.ri = NULL;
   1007  mock_node.rs = &mock_rs_ipv4;
   1008  mock_node.md = &mock_md_null;
   1009  rv = node_describe(&mock_node);
   1010  tt_str_op(rv, OP_EQ,
   1011            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1012            "2.2.2.2");
   1013 
   1014  mock_node.ri = NULL;
   1015  mock_node.rs = &mock_rs_dual;
   1016  mock_node.md = &mock_md_ipv6;
   1017  rv = node_describe(&mock_node);
   1018  tt_str_op(rv, OP_EQ,
   1019            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1020            "2.2.2.2 and [bbbb::bbbb]");
   1021 
   1022  mock_node.ri = NULL;
   1023  mock_node.rs = &mock_rs_dual;
   1024  mock_node.md = &mock_md_null;
   1025  rv = node_describe(&mock_node);
   1026  tt_str_op(rv, OP_EQ,
   1027            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1028            "2.2.2.2 and [bbbb::bbbb]");
   1029 
   1030  /* Test that the routerinfo doesn't change the results above
   1031   */
   1032  mock_node.ri = &mock_ri_dual;
   1033  mock_node.rs = &mock_rs_ipv4;
   1034  mock_node.md = &mock_md_ipv6;
   1035  rv = node_describe(&mock_node);
   1036  tt_str_op(rv, OP_EQ,
   1037            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1038            "2.2.2.2 and [eeee::6000:6000]");
   1039 
   1040  mock_node.ri = &mock_ri_dual;
   1041  mock_node.rs = &mock_rs_ipv4;
   1042  mock_node.md = &mock_md_null;
   1043  rv = node_describe(&mock_node);
   1044  tt_str_op(rv, OP_EQ,
   1045            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1046            "2.2.2.2");
   1047 
   1048  mock_node.ri = &mock_ri_dual;
   1049  mock_node.rs = &mock_rs_dual;
   1050  mock_node.md = &mock_md_ipv6;
   1051  rv = node_describe(&mock_node);
   1052  tt_str_op(rv, OP_EQ,
   1053            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1054            "2.2.2.2 and [bbbb::bbbb]");
   1055 
   1056  mock_node.ri = &mock_ri_dual;
   1057  mock_node.rs = &mock_rs_dual;
   1058  mock_node.md = &mock_md_null;
   1059  rv = node_describe(&mock_node);
   1060  tt_str_op(rv, OP_EQ,
   1061            "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC~Bbb at "
   1062            "2.2.2.2 and [bbbb::bbbb]");
   1063 
   1064  /* test NULL handling */
   1065  rv = node_describe(NULL);
   1066  tt_str_op(rv, OP_EQ, "<null>");
   1067 
   1068  mock_node.ri = NULL;
   1069  mock_node.rs = NULL;
   1070  mock_node.md = NULL;
   1071  rv = node_describe(&mock_node);
   1072  tt_str_op(rv, OP_EQ,
   1073            "<null rs and ri>");
   1074 
   1075 done:
   1076  return;
   1077 }
   1078 
   1079 /** routerstatus_describe() is a wrapper for format_node_description(), see
   1080 * that test for details.
   1081 *
   1082 * The routerstatus-only node_describe() tests are in this function,
   1083 * so we can re-use the same mocked variables.
   1084 */
   1085 static void
   1086 test_nodelist_routerstatus_describe(void *arg)
   1087 {
   1088  routerstatus_t mock_rs_ipv4;
   1089  routerstatus_t mock_rs_ipv6;
   1090  routerstatus_t mock_rs_dual;
   1091 
   1092  const char *rv = NULL;
   1093 
   1094  (void) arg;
   1095 
   1096  /* Clear variables */
   1097  memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
   1098  memset(&mock_rs_ipv6, 0, sizeof(mock_rs_ipv6));
   1099  memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
   1100 
   1101  /* Set up the dual-stack routerstatus */
   1102  memcpy(mock_rs_dual.identity_digest,
   1103         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
   1104         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
   1105         sizeof(mock_rs_dual.identity_digest));
   1106  strlcpy(mock_rs_dual.nickname, "TestOR7890123456789",
   1107          sizeof(mock_rs_dual.nickname));
   1108  tor_addr_parse(&mock_rs_dual.ipv4_addr, "111.222.233.244");
   1109  tor_addr_parse(&mock_rs_dual.ipv6_addr,
   1110                 "[1111:2222:3333:4444:5555:6666:7777:8888]");
   1111 
   1112  /* Create and modify the other routerstatuses. */
   1113  memcpy(&mock_rs_ipv4, &mock_rs_dual, sizeof(mock_rs_ipv4));
   1114  memcpy(&mock_rs_ipv6, &mock_rs_dual, sizeof(mock_rs_ipv6));
   1115  /* Clear the unnecessary addresses */
   1116  memset(&mock_rs_ipv4.ipv6_addr, 0, sizeof(mock_rs_ipv4.ipv6_addr));
   1117  tor_addr_make_unspec(&mock_rs_ipv6.ipv4_addr);
   1118 
   1119  /* We don't test the no-nickname and no-IP cases, because they're covered by
   1120   * format_node_description(), and we don't expect to see them in Tor code. */
   1121 
   1122  /* Try some real IP addresses */
   1123  rv = routerstatus_describe(&mock_rs_ipv4);
   1124  tt_str_op(rv, OP_EQ,
   1125            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1126            "111.222.233.244");
   1127 
   1128  rv = routerstatus_describe(&mock_rs_ipv6);
   1129  tt_str_op(rv, OP_EQ,
   1130            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1131            "[1111:2222:3333:4444:5555:6666:7777:8888]");
   1132 
   1133  rv = routerstatus_describe(&mock_rs_dual);
   1134  tt_str_op(rv, OP_EQ,
   1135            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1136            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
   1137 
   1138  /* test NULL handling */
   1139  rv = routerstatus_describe(NULL);
   1140  tt_str_op(rv, OP_EQ, "<null>");
   1141 
   1142  /* Now test a node with only these routerstatuses */
   1143  node_t mock_node;
   1144  memset(&mock_node, 0, sizeof(mock_node));
   1145  memcpy(mock_node.identity,
   1146         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
   1147         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
   1148         sizeof(mock_node.identity));
   1149 
   1150  /* Try some real IP addresses */
   1151  mock_node.rs = &mock_rs_ipv4;
   1152  rv = node_describe(&mock_node);
   1153  tt_str_op(rv, OP_EQ,
   1154            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1155            "111.222.233.244");
   1156 
   1157  mock_node.rs = &mock_rs_ipv6;
   1158  rv = node_describe(&mock_node);
   1159  tt_str_op(rv, OP_EQ,
   1160            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1161            "[1111:2222:3333:4444:5555:6666:7777:8888]");
   1162 
   1163  mock_node.rs = &mock_rs_dual;
   1164  rv = node_describe(&mock_node);
   1165  tt_str_op(rv, OP_EQ,
   1166            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1167            "111.222.233.244 and [1111:2222:3333:4444:5555:6666:7777:8888]");
   1168 
   1169 done:
   1170  return;
   1171 }
   1172 
   1173 /** extend_info_describe() is a wrapper for format_node_description(), see
   1174 * that test for details.
   1175 */
   1176 static void
   1177 test_nodelist_extend_info_describe(void *arg)
   1178 {
   1179  extend_info_t mock_ei_ipv4;
   1180  extend_info_t mock_ei_ipv6;
   1181 
   1182  const char *rv = NULL;
   1183 
   1184  (void) arg;
   1185 
   1186  /* Clear variables */
   1187  memset(&mock_ei_ipv4, 0, sizeof(mock_ei_ipv4));
   1188  memset(&mock_ei_ipv6, 0, sizeof(mock_ei_ipv6));
   1189 
   1190  /* Set up the IPv4 extend info */
   1191  memcpy(mock_ei_ipv4.identity_digest,
   1192         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
   1193         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
   1194         sizeof(mock_ei_ipv4.identity_digest));
   1195  strlcpy(mock_ei_ipv4.nickname, "TestOR7890123456789",
   1196          sizeof(mock_ei_ipv4.nickname));
   1197  tor_addr_parse(&mock_ei_ipv4.orports[0].addr, "111.222.233.244");
   1198 
   1199  /* Create and modify the other extend info. */
   1200  memcpy(&mock_ei_ipv6, &mock_ei_ipv4, sizeof(mock_ei_ipv6));
   1201  tor_addr_parse(&mock_ei_ipv6.orports[0].addr,
   1202                 "[1111:2222:3333:4444:5555:6666:7777:8888]");
   1203 
   1204  /* We don't test the no-nickname and no-IP cases, because they're covered by
   1205   * format_node_description(), and we don't expect to see them in Tor code. */
   1206 
   1207  /* Try some real IP addresses */
   1208  rv = extend_info_describe(&mock_ei_ipv4);
   1209  tt_str_op(rv, OP_EQ,
   1210            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1211            "111.222.233.244");
   1212 
   1213  rv = extend_info_describe(&mock_ei_ipv6);
   1214  tt_str_op(rv, OP_EQ,
   1215            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
   1216            "[1111:2222:3333:4444:5555:6666:7777:8888]");
   1217 
   1218  /* Extend infos only have one IP address, so there is no dual case */
   1219 
   1220  /* test NULL handling */
   1221  rv = extend_info_describe(NULL);
   1222  tt_str_op(rv, OP_EQ, "<null>");
   1223 
   1224 done:
   1225  return;
   1226 }
   1227 
   1228 /** router_get_verbose_nickname() should return "Fingerprint~Nickname"
   1229 */
   1230 static void
   1231 test_nodelist_router_get_verbose_nickname(void *arg)
   1232 {
   1233  routerinfo_t mock_ri;
   1234  char mock_nickname[MAX_NICKNAME_LEN+1];
   1235 
   1236  char vname[MAX_VERBOSE_NICKNAME_LEN+1];
   1237 
   1238  (void) arg;
   1239 
   1240  memset(&mock_ri, 0, sizeof(routerinfo_t));
   1241  memset(mock_nickname, 0, sizeof(mock_nickname));
   1242  mock_ri.nickname = mock_nickname;
   1243 
   1244  /* verbose nickname should use ~ because named is deprecated */
   1245  strlcpy(mock_nickname, "TestOR", sizeof(mock_nickname));
   1246  memcpy(mock_ri.cache_info.identity_digest,
   1247         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
   1248         "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
   1249         DIGEST_LEN);
   1250  router_get_verbose_nickname(vname, &mock_ri);
   1251  tt_str_op(vname, OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
   1252 
   1253  /* test NULL router handling */
   1254  router_get_verbose_nickname(vname, NULL);
   1255  tt_str_op(vname, OP_EQ, "<null>");
   1256 
   1257  router_get_verbose_nickname(NULL, &mock_ri);
   1258  router_get_verbose_nickname(NULL, NULL);
   1259 
   1260 done:
   1261  return;
   1262 }
   1263 
   1264 static void
   1265 test_nodelist_routerstatus_has_visibly_changed(void *arg)
   1266 {
   1267  (void)arg;
   1268  routerstatus_t rs_orig, rs;
   1269  char *fmt_orig = NULL, *fmt = NULL;
   1270  memset(&rs_orig, 0, sizeof(rs_orig));
   1271  strlcpy(rs_orig.nickname, "friendly", sizeof(rs_orig.nickname));
   1272  memcpy(rs_orig.identity_digest, "abcdefghijklmnopqrst", 20);
   1273  memcpy(rs_orig.descriptor_digest, "abcdefghijklmnopqrst", 20);
   1274  tor_addr_from_ipv4h(&rs_orig.ipv4_addr, 0x7f000001);
   1275  rs_orig.ipv4_orport = 3;
   1276  rs_orig.has_bandwidth = 1;
   1277  rs_orig.bandwidth_kb = 20;
   1278 
   1279 #define COPY() memcpy(&rs, &rs_orig, sizeof(rs))
   1280 #define FORMAT() \
   1281  STMT_BEGIN \
   1282    tor_free(fmt_orig);                                                   \
   1283    tor_free(fmt);                                                        \
   1284    fmt_orig = routerstatus_format_entry(&rs_orig, NULL, NULL,            \
   1285                          NS_CONTROL_PORT,                                \
   1286                          NULL, -1);                                      \
   1287    fmt = routerstatus_format_entry(&rs, NULL, NULL, NS_CONTROL_PORT,     \
   1288                          NULL, -1);                                      \
   1289    tt_assert(fmt_orig);                                                  \
   1290    tt_assert(fmt);                                                       \
   1291  STMT_END
   1292 #define ASSERT_SAME() \
   1293  STMT_BEGIN                                                    \
   1294    tt_assert(! routerstatus_has_visibly_changed(&rs_orig, &rs));       \
   1295    FORMAT();                                                   \
   1296    tt_str_op(fmt_orig, OP_EQ, fmt);                            \
   1297    COPY();                                                     \
   1298  STMT_END
   1299 #define ASSERT_CHANGED() \
   1300  STMT_BEGIN                                                    \
   1301    tt_assert(routerstatus_has_visibly_changed(&rs_orig, &rs));         \
   1302    FORMAT();                                                   \
   1303    tt_str_op(fmt_orig, OP_NE, fmt);                            \
   1304    COPY();                                                     \
   1305  STMT_END
   1306 #define ASSERT_CHANGED_NO_FORMAT() \
   1307  STMT_BEGIN                                                    \
   1308    tt_assert(routerstatus_has_visibly_changed(&rs_orig, &rs));         \
   1309    COPY();                                                     \
   1310  STMT_END
   1311 
   1312  COPY();
   1313  ASSERT_SAME();
   1314 
   1315  tor_addr_from_ipv4h(&rs.ipv4_addr, 0x7f000002);
   1316  ASSERT_CHANGED();
   1317 
   1318  strlcpy(rs.descriptor_digest, "hello world", sizeof(rs.descriptor_digest));
   1319  ASSERT_CHANGED();
   1320 
   1321  strlcpy(rs.nickname, "fr1end1y", sizeof(rs.nickname));
   1322  ASSERT_CHANGED();
   1323 
   1324  rs.ipv4_orport = 55;
   1325  ASSERT_CHANGED();
   1326 
   1327  rs.ipv4_dirport = 9999;
   1328  ASSERT_CHANGED();
   1329 
   1330  tor_addr_parse(&rs.ipv6_addr, "1234::56");
   1331  ASSERT_CHANGED();
   1332 
   1333  tor_addr_parse(&rs_orig.ipv6_addr, "1234::56");
   1334  rs_orig.ipv6_orport = 99;
   1335  COPY();
   1336  rs.ipv6_orport = 22;
   1337  ASSERT_CHANGED();
   1338 
   1339  rs.is_authority = 1;
   1340  ASSERT_CHANGED();
   1341 
   1342  rs.is_exit = 1;
   1343  ASSERT_CHANGED();
   1344 
   1345  rs.is_stable = 1;
   1346  ASSERT_CHANGED();
   1347 
   1348  rs.is_fast = 1;
   1349  ASSERT_CHANGED();
   1350 
   1351  rs.is_flagged_running = 1;
   1352  ASSERT_CHANGED();
   1353 
   1354  // This option is obsolete and not actually formatted.
   1355  rs.is_named = 1;
   1356  ASSERT_CHANGED_NO_FORMAT();
   1357 
   1358  // This option is obsolete and not actually formatted.
   1359  rs.is_unnamed = 1;
   1360  ASSERT_CHANGED_NO_FORMAT();
   1361 
   1362  rs.is_valid = 1;
   1363  ASSERT_CHANGED();
   1364 
   1365  rs.is_possible_guard = 1;
   1366  ASSERT_CHANGED();
   1367 
   1368  rs.is_bad_exit = 1;
   1369  ASSERT_CHANGED();
   1370 
   1371  rs.is_hs_dir = 1;
   1372  ASSERT_CHANGED();
   1373 
   1374  rs.is_v2_dir = 1;
   1375  ASSERT_CHANGED();
   1376 
   1377  rs.is_staledesc = 1;
   1378  ASSERT_CHANGED();
   1379 
   1380  // Setting this to zero crashes us with an assertion failure in
   1381  // routerstatus_format_entry() if we don't have a descriptor.
   1382  rs.has_bandwidth = 0;
   1383  ASSERT_CHANGED_NO_FORMAT();
   1384 
   1385  // Does not actually matter; not visible to controller.
   1386  rs.has_exitsummary = 1;
   1387  ASSERT_SAME();
   1388 
   1389  // Does not actually matter; not visible to the controller.
   1390  rs.bw_is_unmeasured = 1;
   1391  ASSERT_SAME();
   1392 
   1393  rs.bandwidth_kb = 2000;
   1394  ASSERT_CHANGED();
   1395 
   1396  // not visible to the controller.
   1397  rs.has_guardfraction = 1;
   1398  rs.guardfraction_percentage = 22;
   1399  ASSERT_SAME();
   1400 
   1401  // not visible to the controller.
   1402  rs_orig.has_guardfraction = 1;
   1403  rs_orig.guardfraction_percentage = 20;
   1404  COPY();
   1405  rs.guardfraction_percentage = 25;
   1406  ASSERT_SAME();
   1407 
   1408  // not visible to the controller.
   1409  rs.exitsummary = (char*)"accept 1-2";
   1410  ASSERT_SAME();
   1411 
   1412 done:
   1413 #undef COPY
   1414 #undef ASSERT_SAME
   1415 #undef ASSERT_CHANGED
   1416  tor_free(fmt_orig);
   1417  tor_free(fmt);
   1418  return;
   1419 }
   1420 
   1421 #define NODE(name, flags) \
   1422  { #name, test_nodelist_##name, (flags), NULL, NULL }
   1423 
   1424 struct testcase_t nodelist_tests[] = {
   1425  NODE(node_get_verbose_nickname_by_id_null_node, TT_FORK),
   1426  NODE(node_get_verbose_nickname_not_named, TT_FORK),
   1427  NODE(node_is_dir, TT_FORK),
   1428  NODE(ed_id, TT_FORK),
   1429  NODE(nodefamily, TT_FORK),
   1430  NODE(nodefamily_parse_err, TT_FORK),
   1431  NODE(nodefamily_lookup, TT_FORK),
   1432  NODE(nickname_matches, 0),
   1433  NODE(node_nodefamily, TT_FORK),
   1434  NODE(nodefamily_canonicalize, 0),
   1435  NODE(format_node_description, 0),
   1436  NODE(router_describe, 0),
   1437  NODE(node_describe, 0),
   1438  NODE(routerstatus_describe, 0),
   1439  NODE(extend_info_describe, 0),
   1440  NODE(router_get_verbose_nickname, 0),
   1441  NODE(routerstatus_has_visibly_changed, 0),
   1442  END_OF_TESTCASES
   1443 };