tor

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

test_dirvote.c (24524B)


      1 /* Copyright (c) 2020-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file test_dirvote.c
      6 * \brief Unit tests for dirvote related functions
      7 */
      8 #define DIRVOTE_PRIVATE
      9 
     10 #include "core/or/or.h"
     11 #include "feature/dirauth/dirvote.h"
     12 #include "feature/nodelist/dirlist.h"
     13 #include "feature/nodelist/node_st.h"
     14 #include "feature/nodelist/nodelist.h"
     15 #include "feature/nodelist/routerinfo_st.h"
     16 #include "feature/nodelist/signed_descriptor_st.h"
     17 
     18 #include "test/test.h"
     19 
     20 /**
     21 * This struct holds the various information that are needed for router
     22 * comparison. Each router in the test function has one, and they are all
     23 * put in a global digestmap, router_properties
     24 */
     25 typedef struct router_values_t {
     26  int is_running;
     27  int is_auth;
     28  int bw_kb;
     29  char digest[DIGEST_LEN];
     30 } router_values_t;
     31 /**
     32 * This typedef makes declaring digests easier and less verbose
     33 */
     34 typedef char sha1_digest_t[DIGEST_LEN];
     35 
     36 // Use of global variable is justified because the functions that have to be
     37 // mocked take as arguments objects we have no control over
     38 static digestmap_t *router_properties = NULL;
     39 // Use of global variable is justified by its use in nodelist.c
     40 // and is necessary to avoid memory leaks when mocking the
     41 // function node_get_by_id
     42 static node_t *running_node;
     43 static node_t *non_running_node;
     44 
     45 /* Allocate memory to the global variables that represent a running
     46 * and non-running node
     47 */
     48 #define ALLOCATE_MOCK_NODES()                    \
     49  running_node = tor_malloc(sizeof(node_t));     \
     50  running_node->is_running = 1;                  \
     51  non_running_node = tor_malloc(sizeof(node_t)); \
     52  non_running_node->is_running = 0;
     53 
     54 /* Free the memory allocated to the mock nodes */
     55 #define FREE_MOCK_NODES() \
     56  tor_free(running_node); \
     57  tor_free(non_running_node);
     58 
     59 static int
     60 mock_router_digest_is_trusted(const char *digest, dirinfo_type_t type)
     61 {
     62  (void)type;
     63  router_values_t *mock_status;
     64  mock_status = digestmap_get(router_properties, digest);
     65  if (!mock_status) {
     66    return -1;
     67  }
     68  return mock_status->is_auth;
     69 }
     70 
     71 static const node_t *
     72 mock_node_get_by_id(const char *identity_digest)
     73 {
     74  router_values_t *status;
     75  status = digestmap_get(router_properties, identity_digest);
     76  if (!status) {
     77    return NULL;
     78  }
     79  if (status->is_running)
     80    return running_node;
     81  else
     82    return non_running_node;
     83 }
     84 
     85 static uint32_t
     86 mock_dirserv_get_bw(const routerinfo_t *ri)
     87 {
     88  const char *digest = ri->cache_info.identity_digest;
     89  router_values_t *status;
     90  status = digestmap_get(router_properties, digest);
     91  if (!status) {
     92    return -1;
     93  }
     94  return status->bw_kb;
     95 }
     96 
     97 /** Generate a pointer to a router_values_t struct with the arguments as
     98 * field values, and return it
     99 * The returned pointer has to be freed by the caller.
    100 */
    101 static router_values_t *
    102 router_values_new(int running, int auth, int bw, char *digest)
    103 {
    104  router_values_t *status = tor_malloc(sizeof(router_values_t));
    105  memcpy(status->digest, digest, sizeof(status->digest));
    106  status->is_running = running;
    107  status->bw_kb = bw;
    108  status->is_auth = auth;
    109  return status;
    110 }
    111 
    112 /** Given a router_values_t struct, generate a pointer to a routerinfo struct.
    113 * In the cache_info member, put the identity digest, and depending on
    114 * the family argument, fill the IPv4 or IPv6 address. Return the pointer.
    115 * The returned pointer has to be freed by the caller.
    116 */
    117 static routerinfo_t *
    118 routerinfo_new(router_values_t *status, int family, int addr)
    119 {
    120  routerinfo_t *ri = tor_malloc(sizeof(routerinfo_t));
    121  signed_descriptor_t cache_info;
    122  memcpy(cache_info.identity_digest, status->digest,
    123         sizeof(cache_info.identity_digest));
    124  ri->cache_info = cache_info;
    125  tor_addr_t ipv6, ipv4;
    126  ipv6.family = family;
    127  ipv4.family = family;
    128  // Set the address of the other IP version to 0
    129  if (family == AF_INET) {
    130    ipv4.addr.in_addr.s_addr = addr;
    131    for (size_t i = 0; i < 16; i++) {
    132      ipv6.addr.in6_addr.s6_addr[i] = 0;
    133    }
    134  } else {
    135    for (size_t i = 0; i < 16; i++) {
    136      ipv6.addr.in6_addr.s6_addr[i] = addr;
    137    }
    138    ipv4.addr.in_addr.s_addr = 0;
    139  }
    140  ri->ipv6_addr = ipv6;
    141  ri->ipv4_addr = ipv4;
    142  return ri;
    143 }
    144 
    145 static void
    146 test_dirvote_compare_routerinfo_usefulness(void *arg)
    147 {
    148  (void)arg;
    149  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    150  MOCK(node_get_by_id, mock_node_get_by_id);
    151  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    152  ALLOCATE_MOCK_NODES();
    153  router_properties = digestmap_new();
    154 
    155  // The router one is the "least useful" router, every router is compared to
    156  // it
    157  sha1_digest_t digest_one = "aaaa";
    158  router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
    159  digestmap_set(router_properties, status_one->digest, status_one);
    160  sha1_digest_t digest_two = "bbbb";
    161  router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
    162  digestmap_set(router_properties, status_two->digest, status_two);
    163  sha1_digest_t digest_three = "cccc";
    164  router_values_t *status_three = router_values_new(1, 0, 0, digest_three);
    165  digestmap_set(router_properties, status_three->digest, status_three);
    166  sha1_digest_t digest_four = "dddd";
    167  router_values_t *status_four = router_values_new(0, 0, 128, digest_four);
    168  digestmap_set(router_properties, status_four->digest, status_four);
    169  sha1_digest_t digest_five = "9999";
    170  router_values_t *status_five = router_values_new(0, 0, 0, digest_five);
    171  digestmap_set(router_properties, status_five->digest, status_five);
    172 
    173  // A router that has auth status is more useful than a non-auth one
    174  routerinfo_t *first = routerinfo_new(status_one, AF_INET, 0xf);
    175  routerinfo_t *second = routerinfo_new(status_two, AF_INET, 0xf);
    176  int a = compare_routerinfo_usefulness(first, second);
    177  tt_assert(a == 1);
    178  tor_free(second);
    179 
    180  // A running router is more useful than a non running one
    181  routerinfo_t *third = routerinfo_new(status_three, AF_INET, 0xf);
    182  a = compare_routerinfo_usefulness(first, third);
    183  tt_assert(a == 1);
    184  tor_free(third);
    185 
    186  // A higher bandwidth is more useful
    187  routerinfo_t *fourth = routerinfo_new(status_four, AF_INET, 0xf);
    188  a = compare_routerinfo_usefulness(first, fourth);
    189  tt_assert(a == 1);
    190  tor_free(fourth);
    191 
    192  // In case of tie, the digests are compared
    193  routerinfo_t *fifth = routerinfo_new(status_five, AF_INET, 0xf);
    194  a = compare_routerinfo_usefulness(first, fifth);
    195  tt_assert(a > 0);
    196  tor_free(fifth);
    197 
    198 done:
    199  UNMOCK(router_digest_is_trusted_dir_type);
    200  UNMOCK(node_get_by_id);
    201  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    202  FREE_MOCK_NODES();
    203  digestmap_free(router_properties, NULL);
    204  tor_free(status_one);
    205  tor_free(status_two);
    206  tor_free(status_three);
    207  tor_free(status_four);
    208  tor_free(status_five);
    209  tor_free(first);
    210 }
    211 
    212 static void
    213 test_dirvote_compare_routerinfo_by_ipv4(void *arg)
    214 {
    215  (void)arg;
    216  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    217  MOCK(node_get_by_id, mock_node_get_by_id);
    218  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    219 
    220  ALLOCATE_MOCK_NODES();
    221  router_properties = digestmap_new();
    222  sha1_digest_t digest_one = "aaaa";
    223  router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
    224  digestmap_set(router_properties, status_one->digest, status_one);
    225  sha1_digest_t digest_two = "bbbb";
    226  router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
    227  digestmap_set(router_properties, status_two->digest, status_two);
    228 
    229  // Both routers have an IPv4 address
    230  routerinfo_t *first = routerinfo_new(status_one, AF_INET, 1);
    231  routerinfo_t *second = routerinfo_new(status_two, AF_INET, 0xf);
    232 
    233  // The first argument's address precedes the seconds' one
    234  int a = compare_routerinfo_by_ipv4((const void **)&first,
    235                                     (const void **)&second);
    236  tt_assert(a < 0);
    237  // The second argument's address precedes the first' one
    238  a = compare_routerinfo_by_ipv4((const void **)&second,
    239                                 (const void **)&first);
    240  tt_assert(a > 0);
    241  tor_addr_copy(&(second->ipv4_addr), &(first->ipv6_addr));
    242  // The addresses are equal, they are compared by usefulness,
    243  // and first is less useful than second
    244  a = compare_routerinfo_by_ipv4((const void **)&first,
    245                                 (const void **)&second);
    246  tt_assert(a == 1);
    247 done:
    248  UNMOCK(router_digest_is_trusted_dir_type);
    249  UNMOCK(node_get_by_id);
    250  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    251  FREE_MOCK_NODES();
    252  digestmap_free(router_properties, NULL);
    253  tor_free(status_one);
    254  tor_free(status_two);
    255  tor_free(first);
    256  tor_free(second);
    257 }
    258 
    259 static void
    260 test_dirvote_compare_routerinfo_by_ipv6(void *arg)
    261 {
    262  (void)arg;
    263  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    264  MOCK(node_get_by_id, mock_node_get_by_id);
    265  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    266 
    267  ALLOCATE_MOCK_NODES();
    268  router_properties = digestmap_new();
    269  char digest_one[DIGEST_LEN] = "aaaa";
    270  router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
    271  digestmap_set(router_properties, status_one->digest, status_one);
    272  char digest_two[DIGEST_LEN] = "bbbb";
    273  router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
    274  digestmap_set(router_properties, status_two->digest, status_two);
    275 
    276  // Both routers have an IPv6 address
    277  routerinfo_t *first = routerinfo_new(status_one, AF_INET6, 1);
    278  routerinfo_t *second = routerinfo_new(status_two, AF_INET6, 0xf);
    279 
    280  // The first argument's address precedes the seconds' one
    281  int a = compare_routerinfo_by_ipv6((const void **)&first,
    282                                     (const void **)&second);
    283  tt_assert(a < 0);
    284  // The second argument's address precedes the first' one
    285  a = compare_routerinfo_by_ipv6((const void **)&second,
    286                                 (const void **)&first);
    287  tt_assert(a > 0);
    288  tor_addr_copy(&(first->ipv6_addr), &(second->ipv6_addr));
    289  // The addresses are equal, they are compared by usefulness,
    290  // and first is less useful than second
    291  a = compare_routerinfo_by_ipv6((const void **)&first,
    292                                 (const void **)&second);
    293  tt_assert(a == 1);
    294 done:
    295  UNMOCK(router_digest_is_trusted_dir_type);
    296  UNMOCK(node_get_by_id);
    297  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    298  FREE_MOCK_NODES();
    299  digestmap_free(router_properties, NULL);
    300  tor_free(status_one);
    301  tor_free(status_two);
    302  tor_free(first);
    303  tor_free(second);
    304 }
    305 
    306 /** Create routers values and routerinfos that always have the same
    307 * characteristics, and add them to the global digestmap. This macro is here to
    308 * avoid duplicated code fragments.
    309 * The created name##_val pointer should be freed by the caller (and cannot
    310 * be freed in the macro as it causes a heap-after-free error)
    311 */
    312 #define CREATE_ROUTER(digest, name, addr, ip_version)                    \
    313  sha1_digest_t name##_digest = digest;                                  \
    314  name##_val = router_values_new(1, 1, 1, name##_digest);               \
    315  digestmap_set(router_properties, name##_digest, name##_val);           \
    316  name##_ri = routerinfo_new(name##_val, ip_version, addr);
    317 
    318 #define ROUTER_FREE(name) \
    319  tor_free(name##_val);   \
    320  tor_free(name##_ri);
    321 
    322 /** Test to see if the returned routers are exactly the ones that should be
    323 * flagged as sybils : we test for inclusion then for number of elements
    324 */
    325 #define TEST_SYBIL(true_sybil, possible_sybil)               \
    326  DIGESTMAP_FOREACH (true_sybil, sybil_id, void *, ignore) { \
    327    (void)ignore;                                            \
    328    tt_assert(digestmap_get(possible_sybil, sybil_id));      \
    329  }                                                          \
    330  DIGESTMAP_FOREACH_END;                                     \
    331  tt_assert(digestmap_size(true_sybil) == digestmap_size(possible_sybil));
    332 
    333 static void
    334 test_dirvote_get_sybil_by_ip_version_ipv4(void *arg)
    335 {
    336  // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
    337  (void)arg;
    338  router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
    339    *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
    340    *hhhh_val=NULL;
    341  routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
    342    *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
    343    *hhhh_ri=NULL;
    344 
    345  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    346  MOCK(node_get_by_id, mock_node_get_by_id);
    347  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    348  ALLOCATE_MOCK_NODES();
    349  router_properties = digestmap_new();
    350  smartlist_t *routers_ipv4;
    351  routers_ipv4 = smartlist_new();
    352  digestmap_t *true_sybil_routers = NULL;
    353  true_sybil_routers = digestmap_new();
    354  digestmap_t *omit_as_sybil;
    355 
    356  CREATE_ROUTER("aaaa", aaaa, 123, AF_INET);
    357  smartlist_add(routers_ipv4, aaaa_ri);
    358  CREATE_ROUTER("bbbb", bbbb, 123, AF_INET);
    359  smartlist_add(routers_ipv4, bbbb_ri);
    360  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    361  tt_assert(digestmap_isempty(omit_as_sybil) == 1);
    362  digestmap_free(omit_as_sybil, NULL);
    363 
    364  CREATE_ROUTER("cccc", cccc, 123, AF_INET);
    365  smartlist_add(routers_ipv4, cccc_ri);
    366  digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
    367  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    368  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    369  digestmap_free(omit_as_sybil, NULL);
    370 
    371  CREATE_ROUTER("dddd", dddd, 123, AF_INET);
    372  smartlist_add(routers_ipv4, dddd_ri);
    373  digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
    374  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    375  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    376  digestmap_free(omit_as_sybil, NULL);
    377 
    378  CREATE_ROUTER("eeee", eeee, 456, AF_INET);
    379  smartlist_add(routers_ipv4, eeee_ri);
    380  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    381  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    382  digestmap_free(omit_as_sybil, NULL);
    383 
    384  CREATE_ROUTER("ffff", ffff, 456, AF_INET);
    385  smartlist_add(routers_ipv4, ffff_ri);
    386  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    387  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    388  digestmap_free(omit_as_sybil, NULL);
    389 
    390  CREATE_ROUTER("gggg", gggg, 456, AF_INET);
    391  smartlist_add(routers_ipv4, gggg_ri);
    392  digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
    393  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    394  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    395  digestmap_free(omit_as_sybil, NULL);
    396 
    397  CREATE_ROUTER("hhhh", hhhh, 456, AF_INET);
    398  smartlist_add(routers_ipv4, hhhh_ri);
    399  digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
    400  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
    401  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    402 
    403 done:
    404  UNMOCK(router_digest_is_trusted_dir_type);
    405  UNMOCK(node_get_by_id);
    406  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    407  FREE_MOCK_NODES();
    408  digestmap_free(router_properties, NULL);
    409  smartlist_free(routers_ipv4);
    410  digestmap_free(omit_as_sybil, NULL);
    411  digestmap_free(true_sybil_routers, NULL);
    412  ROUTER_FREE(aaaa);
    413  ROUTER_FREE(bbbb);
    414  ROUTER_FREE(cccc);
    415  ROUTER_FREE(dddd);
    416  ROUTER_FREE(eeee);
    417  ROUTER_FREE(ffff);
    418  ROUTER_FREE(gggg);
    419  ROUTER_FREE(hhhh);
    420 }
    421 
    422 static void
    423 test_dirvote_get_sybil_by_ip_version_ipv6(void *arg)
    424 {
    425  router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
    426    *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
    427    *hhhh_val=NULL;
    428  routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
    429    *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
    430    *hhhh_ri=NULL;
    431 
    432  // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
    433  (void)arg;
    434  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    435  MOCK(node_get_by_id, mock_node_get_by_id);
    436  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    437  ALLOCATE_MOCK_NODES();
    438  router_properties = digestmap_new();
    439  smartlist_t *routers_ipv6;
    440  routers_ipv6 = smartlist_new();
    441  digestmap_t *true_sybil_routers = NULL;
    442  true_sybil_routers = digestmap_new();
    443  digestmap_t *omit_as_sybil;
    444 
    445  CREATE_ROUTER("aaaa", aaaa, 123, AF_INET6);
    446  smartlist_add(routers_ipv6, aaaa_ri);
    447  CREATE_ROUTER("bbbb", bbbb, 123, AF_INET6);
    448  smartlist_add(routers_ipv6, bbbb_ri);
    449  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    450  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    451  digestmap_free(omit_as_sybil, NULL);
    452 
    453  CREATE_ROUTER("cccc", cccc, 123, AF_INET6);
    454  smartlist_add(routers_ipv6, cccc_ri);
    455  digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
    456  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    457  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    458  digestmap_free(omit_as_sybil, NULL);
    459 
    460  CREATE_ROUTER("dddd", dddd, 123, AF_INET6);
    461  smartlist_add(routers_ipv6, dddd_ri);
    462  digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
    463  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    464  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    465  digestmap_free(omit_as_sybil, NULL);
    466 
    467  CREATE_ROUTER("eeee", eeee, 456, AF_INET6);
    468  smartlist_add(routers_ipv6, eeee_ri);
    469  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    470  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    471  digestmap_free(omit_as_sybil, NULL);
    472 
    473  CREATE_ROUTER("ffff", ffff, 456, AF_INET6);
    474  smartlist_add(routers_ipv6, ffff_ri);
    475  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    476  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    477  digestmap_free(omit_as_sybil, NULL);
    478 
    479  CREATE_ROUTER("gggg", gggg, 456, AF_INET6);
    480  smartlist_add(routers_ipv6, gggg_ri);
    481  digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
    482  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    483  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    484  digestmap_free(omit_as_sybil, NULL);
    485 
    486  CREATE_ROUTER("hhhh", hhhh, 456, AF_INET6);
    487  smartlist_add(routers_ipv6, hhhh_ri);
    488  digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
    489  omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
    490  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    491 done:
    492  UNMOCK(router_digest_is_trusted_dir_type);
    493  UNMOCK(node_get_by_id);
    494  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    495  FREE_MOCK_NODES();
    496  digestmap_free(router_properties, NULL);
    497  digestmap_free(true_sybil_routers, NULL);
    498  smartlist_free(routers_ipv6);
    499  digestmap_free(omit_as_sybil, NULL);
    500  ROUTER_FREE(aaaa);
    501  ROUTER_FREE(bbbb);
    502  ROUTER_FREE(cccc);
    503  ROUTER_FREE(dddd);
    504  ROUTER_FREE(eeee);
    505  ROUTER_FREE(ffff);
    506  ROUTER_FREE(gggg);
    507  ROUTER_FREE(hhhh);
    508 }
    509 
    510 static void
    511 test_dirvote_get_all_possible_sybil(void *arg)
    512 {
    513  router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
    514    *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
    515    *hhhh_val=NULL, *iiii_val=NULL, *jjjj_val=NULL, *kkkk_val=NULL,
    516    *llll_val=NULL, *mmmm_val=NULL, *nnnn_val=NULL, *oooo_val=NULL,
    517    *pppp_val=NULL;
    518  routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
    519    *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
    520    *hhhh_ri=NULL, *iiii_ri=NULL, *jjjj_ri=NULL, *kkkk_ri=NULL,
    521    *llll_ri=NULL, *mmmm_ri=NULL, *nnnn_ri=NULL, *oooo_ri=NULL,
    522    *pppp_ri=NULL;
    523 
    524  // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
    525  (void)arg;
    526  MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
    527  MOCK(node_get_by_id, mock_node_get_by_id);
    528  MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
    529  ALLOCATE_MOCK_NODES();
    530  router_properties = digestmap_new();
    531  smartlist_t *routers;
    532  routers = smartlist_new();
    533  digestmap_t *true_sybil_routers = NULL;
    534  true_sybil_routers = digestmap_new();
    535  digestmap_t *omit_as_sybil;
    536 
    537  CREATE_ROUTER("aaaa", aaaa, 123, AF_INET);
    538  smartlist_add(routers, aaaa_ri);
    539  CREATE_ROUTER("bbbb", bbbb, 123, AF_INET);
    540  smartlist_add(routers, bbbb_ri);
    541  omit_as_sybil = get_all_possible_sybil(routers);
    542  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    543  digestmap_free(omit_as_sybil, NULL);
    544 
    545  CREATE_ROUTER("cccc", cccc, 123, AF_INET);
    546  smartlist_add(routers, cccc_ri);
    547  digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
    548  omit_as_sybil = get_all_possible_sybil(routers);
    549  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    550  digestmap_free(omit_as_sybil, NULL);
    551 
    552  CREATE_ROUTER("dddd", dddd, 123, AF_INET);
    553  smartlist_add(routers, dddd_ri);
    554  digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
    555  omit_as_sybil = get_all_possible_sybil(routers);
    556  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    557  digestmap_free(omit_as_sybil, NULL);
    558 
    559  CREATE_ROUTER("eeee", eeee, 456, AF_INET);
    560  smartlist_add(routers, eeee_ri);
    561  omit_as_sybil = get_all_possible_sybil(routers);
    562  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    563  digestmap_free(omit_as_sybil, NULL);
    564 
    565  CREATE_ROUTER("ffff", ffff, 456, AF_INET);
    566  smartlist_add(routers, ffff_ri);
    567  omit_as_sybil = get_all_possible_sybil(routers);
    568  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    569  digestmap_free(omit_as_sybil, NULL);
    570 
    571  CREATE_ROUTER("gggg", gggg, 456, AF_INET);
    572  smartlist_add(routers, gggg_ri);
    573  digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
    574  omit_as_sybil = get_all_possible_sybil(routers);
    575  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    576  digestmap_free(omit_as_sybil, NULL);
    577 
    578  CREATE_ROUTER("hhhh", hhhh, 456, AF_INET);
    579  smartlist_add(routers, hhhh_ri);
    580  digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
    581  omit_as_sybil = get_all_possible_sybil(routers);
    582  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    583  digestmap_free(omit_as_sybil, NULL);
    584 
    585  CREATE_ROUTER("iiii", iiii, 123, AF_INET6);
    586  smartlist_add(routers, iiii_ri);
    587  CREATE_ROUTER("jjjj", jjjj, 123, AF_INET6);
    588  smartlist_add(routers, jjjj_ri);
    589  omit_as_sybil = get_all_possible_sybil(routers);
    590  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    591  digestmap_free(omit_as_sybil, NULL);
    592 
    593  CREATE_ROUTER("kkkk", kkkk, 123, AF_INET6);
    594  smartlist_add(routers, kkkk_ri);
    595  digestmap_set(true_sybil_routers, kkkk_digest, kkkk_digest);
    596  omit_as_sybil = get_all_possible_sybil(routers);
    597  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    598  digestmap_free(omit_as_sybil,NULL);
    599 
    600  CREATE_ROUTER("llll", llll, 123, AF_INET6);
    601  smartlist_add(routers, llll_ri);
    602  digestmap_set(true_sybil_routers, llll_digest, llll_digest);
    603  omit_as_sybil = get_all_possible_sybil(routers);
    604  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    605  digestmap_free(omit_as_sybil,NULL);
    606 
    607  CREATE_ROUTER("mmmm", mmmm, 456, AF_INET6);
    608  smartlist_add(routers, mmmm_ri);
    609  omit_as_sybil = get_all_possible_sybil(routers);
    610  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    611  digestmap_free(omit_as_sybil, NULL);
    612 
    613  CREATE_ROUTER("nnnn", nnnn, 456, AF_INET6);
    614  smartlist_add(routers, nnnn_ri);
    615  omit_as_sybil = get_all_possible_sybil(routers);
    616  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    617  digestmap_free(omit_as_sybil, NULL);
    618 
    619  CREATE_ROUTER("oooo", oooo, 456, AF_INET6);
    620  smartlist_add(routers, oooo_ri);
    621  digestmap_set(true_sybil_routers, oooo_digest, oooo_digest);
    622  omit_as_sybil = get_all_possible_sybil(routers);
    623  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    624  digestmap_free(omit_as_sybil, NULL);
    625 
    626  CREATE_ROUTER("pppp", pppp, 456, AF_INET6);
    627  smartlist_add(routers, pppp_ri);
    628  digestmap_set(true_sybil_routers, pppp_digest, pppp_digest);
    629  omit_as_sybil = get_all_possible_sybil(routers);
    630  TEST_SYBIL(true_sybil_routers, omit_as_sybil);
    631 
    632 done:
    633  UNMOCK(router_digest_is_trusted_dir_type);
    634  UNMOCK(node_get_by_id);
    635  UNMOCK(dirserv_get_bandwidth_for_router_kb);
    636  FREE_MOCK_NODES();
    637  digestmap_free(router_properties, NULL);
    638  smartlist_free(routers);
    639  digestmap_free(omit_as_sybil, NULL);
    640  digestmap_free(true_sybil_routers, NULL);
    641  ROUTER_FREE(aaaa);
    642  ROUTER_FREE(bbbb);
    643  ROUTER_FREE(cccc);
    644  ROUTER_FREE(dddd);
    645  ROUTER_FREE(eeee);
    646  ROUTER_FREE(ffff);
    647  ROUTER_FREE(gggg);
    648  ROUTER_FREE(hhhh);
    649  ROUTER_FREE(iiii);
    650  ROUTER_FREE(jjjj);
    651  ROUTER_FREE(kkkk);
    652  ROUTER_FREE(llll);
    653  ROUTER_FREE(mmmm);
    654  ROUTER_FREE(nnnn);
    655  ROUTER_FREE(oooo);
    656  ROUTER_FREE(pppp);
    657 }
    658 
    659 #define NODE(name, flags)                           \
    660  {                                                 \
    661    #name, test_dirvote_##name, (flags), NULL, NULL \
    662  }
    663 
    664 struct testcase_t dirvote_tests[] = {
    665    NODE(compare_routerinfo_usefulness, TT_FORK),
    666    NODE(compare_routerinfo_by_ipv6, TT_FORK),
    667    NODE(compare_routerinfo_by_ipv4, TT_FORK),
    668    NODE(get_sybil_by_ip_version_ipv4, TT_FORK),
    669    NODE(get_sybil_by_ip_version_ipv6, TT_FORK),
    670    NODE(get_all_possible_sybil, TT_FORK),
    671    END_OF_TESTCASES};