LCOV - code coverage report
Current view: top level - test - test_address_set.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 142 142 100.0 %
Date: 2021-11-24 03:28:48 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2017-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #include "core/or/or.h"
       5             : #include "lib/crypt_ops/crypto_rand.h"
       6             : #include "core/or/address_set.h"
       7             : #include "feature/nodelist/dirlist.h"
       8             : #include "feature/nodelist/microdesc.h"
       9             : #include "feature/nodelist/networkstatus.h"
      10             : #include "feature/nodelist/nodelist.h"
      11             : #include "feature/nodelist/routerlist.h"
      12             : #include "feature/nodelist/torcert.h"
      13             : 
      14             : #include "feature/nodelist/microdesc_st.h"
      15             : #include "feature/nodelist/networkstatus_st.h"
      16             : #include "feature/nodelist/routerinfo_st.h"
      17             : #include "feature/nodelist/routerstatus_st.h"
      18             : 
      19             : #include "test/test.h"
      20             : 
      21             : static networkstatus_t *dummy_ns = NULL;
      22             : static networkstatus_t *
      23           4 : mock_networkstatus_get_latest_consensus(void)
      24             : {
      25           4 :   return dummy_ns;
      26             : }
      27             : 
      28             : static networkstatus_t *
      29           2 : mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
      30             : {
      31           2 :   tor_assert(f == FLAV_MICRODESC);
      32           2 :   return dummy_ns;
      33             : }
      34             : 
      35             : static void
      36           4 : mock_dirlist_add_trusted_dir_addresses(void)
      37             : {
      38           4 :   return;
      39             : }
      40             : 
      41             : /* Number of address a single node_t can have. Default to the production
      42             :  * value. This is to control the size of the bloom filter. */
      43             : static int addr_per_node = 2;
      44             : static int
      45           8 : mock_get_estimated_address_per_node(void)
      46             : {
      47           8 :   return addr_per_node;
      48             : }
      49             : 
      50             : static void
      51           1 : test_contains(void *arg)
      52             : {
      53           1 :   int ret;
      54           1 :   address_set_t *set = NULL;
      55             : 
      56           1 :   (void) arg;
      57             : 
      58             :   /* Setup an IPv4 and IPv6 addresses. */
      59           1 :   tor_addr_t addr_v6;
      60           1 :   tor_addr_parse(&addr_v6, "1:2:3:4::");
      61           1 :   tor_addr_t addr_v4;
      62           1 :   tor_addr_parse(&addr_v4, "42.42.42.42");
      63           1 :   uint32_t ipv4h = tor_addr_to_ipv4h(&addr_v4);
      64             : 
      65             :   /* Make it very big so the chance of failing the contain test will be
      66             :    * extremely rare. */
      67           1 :   set = address_set_new(1024);
      68           1 :   tt_assert(set);
      69             : 
      70             :   /* Add and lookup IPv6. */
      71           1 :   address_set_add(set, &addr_v6);
      72           1 :   ret = address_set_probably_contains(set, &addr_v6);
      73           1 :   tt_int_op(ret, OP_EQ, 1);
      74             : 
      75             :   /* Add and lookup IPv4. */
      76           1 :   address_set_add_ipv4h(set, ipv4h);
      77           1 :   ret = address_set_probably_contains(set, &addr_v4);
      78           1 :   tt_int_op(ret, OP_EQ, 1);
      79             : 
      80             :   /* Try a lookup of rubbish. */
      81           1 :   tor_addr_t dummy_addr;
      82           1 :   memset(&dummy_addr, 'A', sizeof(dummy_addr));
      83           1 :   dummy_addr.family = AF_INET;
      84           1 :   ret = address_set_probably_contains(set, &dummy_addr);
      85           1 :   tt_int_op(ret, OP_EQ, 0);
      86           1 :   dummy_addr.family = AF_INET6;
      87           1 :   ret = address_set_probably_contains(set, &dummy_addr);
      88           1 :   tt_int_op(ret, OP_EQ, 0);
      89             : 
      90           1 :  done:
      91           1 :   address_set_free(set);
      92           1 : }
      93             : 
      94             : static void
      95           1 : test_nodelist(void *arg)
      96             : {
      97           1 :   int ret;
      98           1 :   routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
      99             : 
     100           1 :   (void) arg;
     101             : 
     102           1 :   MOCK(networkstatus_get_latest_consensus,
     103             :        mock_networkstatus_get_latest_consensus);
     104           1 :   MOCK(networkstatus_get_latest_consensus_by_flavor,
     105             :        mock_networkstatus_get_latest_consensus_by_flavor);
     106           1 :   MOCK(get_estimated_address_per_node,
     107             :        mock_get_estimated_address_per_node);
     108           1 :   MOCK(dirlist_add_trusted_dir_addresses,
     109             :        mock_dirlist_add_trusted_dir_addresses);
     110             : 
     111           1 :   dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
     112           1 :   dummy_ns->flavor = FLAV_MICRODESC;
     113           1 :   dummy_ns->routerstatus_list = smartlist_new();
     114             : 
     115           1 :   tor_addr_t addr_v4, addr_v6, dummy_addr;
     116           1 :   tor_addr_parse(&addr_v4, "42.42.42.42");
     117           1 :   tor_addr_parse(&addr_v6, "1:2:3:4::");
     118           1 :   memset(&dummy_addr, 'A', sizeof(dummy_addr));
     119             : 
     120             :   /* This will make the nodelist bloom filter very large
     121             :    * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
     122           1 :   addr_per_node = 1024;
     123             : 
     124             :   /* No node no nothing. The lookups should be empty. We've mocked the
     125             :    * dirlist_add_trusted_dir_addresses in order for _no_ authorities to be
     126             :    * added to the filter else it makes this test to trigger many false
     127             :    * positive. */
     128           1 :   nodelist_set_consensus(dummy_ns);
     129             : 
     130             :   /* The address set should be empty. */
     131           1 :   ret = nodelist_probably_contains_address(&addr_v4);
     132           1 :   tt_int_op(ret, OP_EQ, 0);
     133           1 :   ret = nodelist_probably_contains_address(&addr_v6);
     134           1 :   tt_int_op(ret, OP_EQ, 0);
     135           1 :   dummy_addr.family = AF_INET;
     136           1 :   ret = nodelist_probably_contains_address(&dummy_addr);
     137           1 :   tt_int_op(ret, OP_EQ, 0);
     138           1 :   dummy_addr.family = AF_INET6;
     139           1 :   ret = nodelist_probably_contains_address(&dummy_addr);
     140           1 :   tt_int_op(ret, OP_EQ, 0);
     141             : 
     142           1 :   md = tor_malloc_zero(sizeof(*md));
     143           1 :   ri = tor_malloc_zero(sizeof(*ri));
     144           1 :   rs = tor_malloc_zero(sizeof(*rs));
     145           1 :   crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
     146           1 :   crypto_rand(md->digest, sizeof(md->digest));
     147           1 :   memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
     148             : 
     149             :   /* Setup the rs, ri and md addresses. */
     150           1 :   tor_addr_copy(&rs->ipv4_addr, &addr_v4);
     151           1 :   tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
     152           1 :   tor_addr_copy(&ri->ipv4_addr, &addr_v4);
     153           1 :   tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
     154           1 :   tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
     155             : 
     156             :   /* Add the rs to the consensus becoming a node_t. */
     157           1 :   smartlist_add(dummy_ns->routerstatus_list, rs);
     158           1 :   nodelist_set_consensus(dummy_ns);
     159             : 
     160             :   /* At this point, the address set should be initialized in the nodelist and
     161             :    * we should be able to lookup. */
     162           1 :   ret = nodelist_probably_contains_address(&addr_v4);
     163           1 :   tt_int_op(ret, OP_EQ, 1);
     164           1 :   ret = nodelist_probably_contains_address(&addr_v6);
     165           1 :   tt_int_op(ret, OP_EQ, 1);
     166             :   /* Lookup unknown address. */
     167           1 :   dummy_addr.family = AF_INET;
     168           1 :   ret = nodelist_probably_contains_address(&dummy_addr);
     169           1 :   tt_int_op(ret, OP_EQ, 0);
     170           1 :   dummy_addr.family = AF_INET6;
     171           1 :   ret = nodelist_probably_contains_address(&dummy_addr);
     172           1 :   tt_int_op(ret, OP_EQ, 0);
     173             : 
     174           1 :  done:
     175           1 :   routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
     176           1 :   smartlist_clear(dummy_ns->routerstatus_list);
     177           1 :   networkstatus_vote_free(dummy_ns);
     178           1 :   UNMOCK(networkstatus_get_latest_consensus);
     179           1 :   UNMOCK(networkstatus_get_latest_consensus_by_flavor);
     180           1 :   UNMOCK(get_estimated_address_per_node);
     181           1 :   UNMOCK(dirlist_add_trusted_dir_addresses);
     182           1 : }
     183             : 
     184             : /** Test that the no-reentry exit filter works as intended */
     185             : static void
     186           1 : test_exit_no_reentry(void *arg)
     187             : {
     188           1 :   routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
     189           1 :   (void) arg;
     190             : 
     191           1 :   MOCK(networkstatus_get_latest_consensus,
     192             :        mock_networkstatus_get_latest_consensus);
     193           1 :   MOCK(networkstatus_get_latest_consensus_by_flavor,
     194             :        mock_networkstatus_get_latest_consensus_by_flavor);
     195           1 :   MOCK(get_estimated_address_per_node,
     196             :        mock_get_estimated_address_per_node);
     197           1 :   MOCK(dirlist_add_trusted_dir_addresses,
     198             :        mock_dirlist_add_trusted_dir_addresses);
     199             : 
     200           1 :   dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
     201           1 :   dummy_ns->flavor = FLAV_MICRODESC;
     202           1 :   dummy_ns->routerstatus_list = smartlist_new();
     203             : 
     204           1 :   tor_addr_t addr_v4, addr_v6, dummy_addr;
     205           1 :   tor_addr_parse(&addr_v4, "42.42.42.42");
     206           1 :   tor_addr_parse(&addr_v6, "1:2:3:4::");
     207           1 :   memset(&dummy_addr, 'A', sizeof(dummy_addr));
     208             : 
     209             :   /* This will make the nodelist bloom filter very large
     210             :    * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
     211           1 :   addr_per_node = 1024;
     212             : 
     213             :   /* After this point the nodelist is populated with the directory authorities
     214             :    * address and ports */
     215           1 :   nodelist_set_consensus(dummy_ns);
     216             : 
     217             :   /* The address set is empty. Try it anyway */
     218           1 :   tt_assert(!nodelist_reentry_contains(&addr_v4, 244));
     219           1 :   tt_assert(!nodelist_reentry_contains(&addr_v6, 244));
     220             : 
     221             :   /* Now let's populate the network */
     222           1 :   md = tor_malloc_zero(sizeof(*md));
     223           1 :   ri = tor_malloc_zero(sizeof(*ri));
     224           1 :   rs = tor_malloc_zero(sizeof(*rs));
     225           1 :   crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
     226           1 :   crypto_rand(md->digest, sizeof(md->digest));
     227           1 :   memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
     228             : 
     229             :   /* Setup the rs, ri and md addresses. */
     230           1 :   tor_addr_copy(&rs->ipv4_addr, &addr_v4);
     231           1 :   rs->ipv4_orport = 444;
     232           1 :   tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
     233           1 :   rs->ipv6_orport = 666;
     234           1 :   tor_addr_copy(&ri->ipv4_addr, &addr_v4);
     235           1 :   tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
     236           1 :   tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
     237             : 
     238             :   /* Add the rs to the consensus becoming a node_t. */
     239           1 :   smartlist_add(dummy_ns->routerstatus_list, rs);
     240           1 :   nodelist_set_consensus(dummy_ns);
     241             : 
     242             :   /* Now that the nodelist is populated let's do some retry attempts */
     243             : 
     244             :   /* First let's try an address that is on the no-reentry list, but with a
     245             :      different port */
     246           1 :   tt_assert(!nodelist_reentry_contains(&addr_v4, 666));
     247           1 :   tt_assert(!nodelist_reentry_contains(&addr_v6, 444));
     248             : 
     249             :   /* OK now let's try with the right address and right port */
     250           1 :   tt_assert(nodelist_reentry_contains(&addr_v4, 444));
     251           1 :   tt_assert(nodelist_reentry_contains(&addr_v6, 666));
     252             : 
     253           1 :  done:
     254           1 :   routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
     255           1 :   smartlist_clear(dummy_ns->routerstatus_list);
     256           1 :   networkstatus_vote_free(dummy_ns);
     257           1 :   UNMOCK(networkstatus_get_latest_consensus);
     258           1 :   UNMOCK(networkstatus_get_latest_consensus_by_flavor);
     259           1 :   UNMOCK(get_estimated_address_per_node);
     260           1 :   UNMOCK(dirlist_add_trusted_dir_addresses);
     261           1 : }
     262             : 
     263             : struct testcase_t address_set_tests[] = {
     264             :   { "contains", test_contains, TT_FORK,
     265             :     NULL, NULL },
     266             :   { "nodelist", test_nodelist, TT_FORK,
     267             :     NULL, NULL },
     268             :   { "exit_no_reentry", test_exit_no_reentry, TT_FORK, NULL, NULL },
     269             : 
     270             :   END_OF_TESTCASES
     271             : };
     272             : 

Generated by: LCOV version 1.14