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

          Line data    Source code
       1             : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #define CIRCUITBUILD_PRIVATE
       5             : #define RELAY_PRIVATE
       6             : #define BWHIST_PRIVATE
       7             : #include "core/or/or.h"
       8             : #include "core/or/circuitbuild.h"
       9             : #include "core/or/circuitlist.h"
      10             : #include "core/or/channeltls.h"
      11             : #include "feature/stats/bwhist.h"
      12             : #include "core/or/relay.h"
      13             : #include "lib/container/order.h"
      14             : #include "lib/encoding/confline.h"
      15             : /* For init/free stuff */
      16             : #include "core/or/scheduler.h"
      17             : 
      18             : #include "core/or/cell_st.h"
      19             : #include "core/or/or_circuit_st.h"
      20             : 
      21             : #define RESOLVE_ADDR_PRIVATE
      22             : #include "feature/nodelist/dirlist.h"
      23             : #include "feature/relay/relay_find_addr.h"
      24             : #include "feature/relay/routermode.h"
      25             : #include "feature/dirclient/dir_server_st.h"
      26             : 
      27             : #define CONFIG_PRIVATE
      28             : #include "app/config/config.h"
      29             : #include "app/config/resolve_addr.h"
      30             : 
      31             : /* Test suite stuff */
      32             : #include "test/test.h"
      33             : #include "test/fakechans.h"
      34             : #include "test/fakecircs.h"
      35             : 
      36             : static void test_relay_append_cell_to_circuit_queue(void *arg);
      37             : 
      38             : static int
      39           8 : mock_server_mode_true(const or_options_t *options)
      40             : {
      41           8 :   (void) options;
      42           8 :   return 1;
      43             : }
      44             : 
      45             : static void
      46           1 : assert_circuit_ok_mock(const circuit_t *c)
      47             : {
      48           1 :   (void) c;
      49           1 :   return;
      50             : }
      51             : 
      52             : static void
      53           1 : test_relay_close_circuit(void *arg)
      54             : {
      55           1 :   channel_t *nchan = NULL, *pchan = NULL;
      56           1 :   or_circuit_t *orcirc = NULL;
      57           1 :   cell_t *cell = NULL;
      58           1 :   int old_count, new_count;
      59             : 
      60           1 :   (void)arg;
      61             : 
      62             :   /* Make fake channels to be nchan and pchan for the circuit */
      63           1 :   nchan = new_fake_channel();
      64           1 :   tt_assert(nchan);
      65             : 
      66           1 :   pchan = new_fake_channel();
      67           1 :   tt_assert(pchan);
      68             : 
      69             :   /* Make a fake orcirc */
      70           1 :   orcirc = new_fake_orcirc(nchan, pchan);
      71           1 :   tt_assert(orcirc);
      72           1 :   circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
      73             :                             CELL_DIRECTION_OUT);
      74           1 :   circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
      75             :                             CELL_DIRECTION_IN);
      76             : 
      77             :   /* Make a cell */
      78           1 :   cell = tor_malloc_zero(sizeof(cell_t));
      79           1 :   make_fake_cell(cell);
      80             : 
      81           1 :   MOCK(scheduler_channel_has_waiting_cells,
      82             :        scheduler_channel_has_waiting_cells_mock);
      83           1 :   MOCK(assert_circuit_ok,
      84             :        assert_circuit_ok_mock);
      85             : 
      86             :   /* Append it */
      87           1 :   old_count = get_mock_scheduler_has_waiting_cells_count();
      88           1 :   append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
      89             :                                CELL_DIRECTION_OUT, 0);
      90           1 :   new_count = get_mock_scheduler_has_waiting_cells_count();
      91           1 :   tt_int_op(new_count, OP_EQ, old_count + 1);
      92             : 
      93             :   /* Now try the reverse direction */
      94           1 :   old_count = get_mock_scheduler_has_waiting_cells_count();
      95           1 :   append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
      96             :                                CELL_DIRECTION_IN, 0);
      97           1 :   new_count = get_mock_scheduler_has_waiting_cells_count();
      98           1 :   tt_int_op(new_count, OP_EQ, old_count + 1);
      99             : 
     100             :   /* Ensure our write totals are 0 */
     101           1 :   tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
     102             : 
     103             :   /* Mark the circuit for close */
     104           1 :   circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
     105             : 
     106             :   /* Check our write totals. */
     107           1 :   advance_obs(write_array);
     108           1 :   commit_max(write_array);
     109             :   /* Check for two cells plus overhead */
     110           1 :   tt_u64_op(find_largest_max(write_array), OP_EQ,
     111             :                              2*(get_cell_network_size(nchan->wide_circ_ids)
     112             :                                 +TLS_PER_CELL_OVERHEAD));
     113             : 
     114           1 :   UNMOCK(scheduler_channel_has_waiting_cells);
     115             : 
     116             :   /* Get rid of the fake channels */
     117           1 :   MOCK(scheduler_release_channel, scheduler_release_channel_mock);
     118           1 :   channel_mark_for_close(nchan);
     119           1 :   channel_mark_for_close(pchan);
     120           1 :   UNMOCK(scheduler_release_channel);
     121             : 
     122             :   /* Shut down channels */
     123           1 :   channel_free_all();
     124             : 
     125           1 :  done:
     126           1 :   tor_free(cell);
     127           1 :   if (orcirc) {
     128           1 :     circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
     129           1 :     circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
     130           1 :     cell_queue_clear(&orcirc->base_.n_chan_cells);
     131           1 :     cell_queue_clear(&orcirc->p_chan_cells);
     132             :   }
     133           1 :   free_fake_orcirc(orcirc);
     134           1 :   free_fake_channel(nchan);
     135           1 :   free_fake_channel(pchan);
     136           1 :   UNMOCK(assert_circuit_ok);
     137             : 
     138           1 :   return;
     139             : }
     140             : 
     141             : static void
     142           1 : test_relay_append_cell_to_circuit_queue(void *arg)
     143             : {
     144           1 :   channel_t *nchan = NULL, *pchan = NULL;
     145           1 :   or_circuit_t *orcirc = NULL;
     146           1 :   cell_t *cell = NULL;
     147           1 :   int old_count, new_count;
     148             : 
     149           1 :   (void)arg;
     150             : 
     151             :   /* Make fake channels to be nchan and pchan for the circuit */
     152           1 :   nchan = new_fake_channel();
     153           1 :   tt_assert(nchan);
     154             : 
     155           1 :   pchan = new_fake_channel();
     156           1 :   tt_assert(pchan);
     157             : 
     158             :   /* Make a fake orcirc */
     159           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     160           1 :   tt_assert(orcirc);
     161           1 :   circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
     162             :                             CELL_DIRECTION_OUT);
     163           1 :   circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
     164             :                             CELL_DIRECTION_IN);
     165             : 
     166             :   /* Make a cell */
     167           1 :   cell = tor_malloc_zero(sizeof(cell_t));
     168           1 :   make_fake_cell(cell);
     169             : 
     170           1 :   MOCK(scheduler_channel_has_waiting_cells,
     171             :        scheduler_channel_has_waiting_cells_mock);
     172             : 
     173             :   /* Append it */
     174           1 :   old_count = get_mock_scheduler_has_waiting_cells_count();
     175           1 :   append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
     176             :                                CELL_DIRECTION_OUT, 0);
     177           1 :   new_count = get_mock_scheduler_has_waiting_cells_count();
     178           1 :   tt_int_op(new_count, OP_EQ, old_count + 1);
     179             : 
     180             :   /* Now try the reverse direction */
     181           1 :   old_count = get_mock_scheduler_has_waiting_cells_count();
     182           1 :   append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
     183             :                                CELL_DIRECTION_IN, 0);
     184           1 :   new_count = get_mock_scheduler_has_waiting_cells_count();
     185           1 :   tt_int_op(new_count, OP_EQ, old_count + 1);
     186             : 
     187           1 :   UNMOCK(scheduler_channel_has_waiting_cells);
     188             : 
     189             :   /* Get rid of the fake channels */
     190           1 :   MOCK(scheduler_release_channel, scheduler_release_channel_mock);
     191           1 :   channel_mark_for_close(nchan);
     192           1 :   channel_mark_for_close(pchan);
     193           1 :   UNMOCK(scheduler_release_channel);
     194             : 
     195             :   /* Shut down channels */
     196           1 :   channel_free_all();
     197             : 
     198           1 :  done:
     199           1 :   tor_free(cell);
     200           1 :   if (orcirc) {
     201           1 :     circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
     202           1 :     circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
     203           1 :     cell_queue_clear(&orcirc->base_.n_chan_cells);
     204           1 :     cell_queue_clear(&orcirc->p_chan_cells);
     205             :   }
     206           1 :   free_fake_orcirc(orcirc);
     207           1 :   free_fake_channel(nchan);
     208           1 :   free_fake_channel(pchan);
     209             : 
     210           1 :   return;
     211             : }
     212             : 
     213             : static void
     214           1 : test_suggested_address(void *arg)
     215             : {
     216           1 :   int ret;
     217           1 :   const char *untrusted_id = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
     218           1 :   dir_server_t *ds = NULL;
     219           1 :   tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
     220           1 :   tor_addr_t trusted_addr, untrusted_addr;
     221           1 :   tor_addr_port_t trusted_ap_v6 = { .port = 443 };
     222             : 
     223           1 :   (void) arg;
     224             : 
     225           1 :   MOCK(server_mode, mock_server_mode_true);
     226             : 
     227             :   /* Unstrusted relay source. */
     228           1 :   ret = tor_addr_parse(&untrusted_addr, "8.8.8.8");
     229           1 :   tt_int_op(ret, OP_EQ, AF_INET);
     230             : 
     231             :   /* Add gabelmoo as a trusted directory authority. */
     232           1 :   ret = tor_addr_parse(&trusted_addr, "[2001:638:a000:4140::ffff:189]");
     233           1 :   tt_int_op(ret, OP_EQ, AF_INET6);
     234           1 :   tor_addr_copy(&trusted_ap_v6.addr, &trusted_addr);
     235             : 
     236           1 :   ds = trusted_dir_server_new("gabelmoo", "131.188.40.189", 80, 443,
     237             :                               &trusted_ap_v6,
     238             :                               "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281",
     239             :                               "ED03BB616EB2F60BEC80151114BB25CEF515B226",
     240             :                               V3_DIRINFO, 1.0);
     241           1 :   tt_assert(ds);
     242           1 :   dir_server_add(ds);
     243             : 
     244             :   /* 1. Valid IPv4 from a trusted authority (gabelmoo). */
     245           1 :   ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
     246           1 :   relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
     247           1 :   resolved_addr_get_suggested(AF_INET, &cache_addr);
     248           1 :   tt_assert(tor_addr_eq(&cache_addr, &ipv4_addr));
     249           1 :   resolve_addr_reset_suggested(AF_INET);
     250             : 
     251             :   /* 2. Valid IPv6 from a trusted authority (gabelmoo). */
     252           1 :   ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
     253           1 :   relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
     254           1 :   resolved_addr_get_suggested(AF_INET6, &cache_addr);
     255           1 :   tt_assert(tor_addr_eq(&cache_addr, &ipv6_addr));
     256           1 :   resolve_addr_reset_suggested(AF_INET6);
     257             : 
     258             :   /* 3. Valid IPv4 but untrusted source. */
     259           1 :   ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
     260           1 :   relay_address_new_suggestion(&ipv4_addr, &untrusted_addr, untrusted_id);
     261           1 :   resolved_addr_get_suggested(AF_INET, &cache_addr);
     262           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     263             : 
     264             :   /* 4. Valid IPv6 but untrusted source. */
     265           1 :   ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
     266           1 :   relay_address_new_suggestion(&ipv6_addr, &untrusted_addr, untrusted_id);
     267           1 :   resolved_addr_get_suggested(AF_INET6, &cache_addr);
     268           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     269             : 
     270             :   /* 5. Internal IPv4 from a trusted authority (gabelmoo). */
     271           1 :   ret = tor_addr_parse(&ipv4_addr, "127.0.0.1");
     272           1 :   relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
     273           1 :   resolved_addr_get_suggested(AF_INET, &cache_addr);
     274           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     275             : 
     276             :   /* 6. Internal IPv6 from a trusted authority (gabelmoo). */
     277           1 :   ret = tor_addr_parse(&ipv6_addr, "[::1]");
     278           1 :   relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
     279           1 :   resolved_addr_get_suggested(AF_INET6, &cache_addr);
     280           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     281             : 
     282             :   /* 7. IPv4 from a trusted authority (gabelmoo). */
     283           1 :   relay_address_new_suggestion(&ds->ipv4_addr, &ds->ipv4_addr, ds->digest);
     284           1 :   resolved_addr_get_suggested(AF_INET, &cache_addr);
     285           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     286             : 
     287             :   /* 8. IPv6 from a trusted authority (gabelmoo). */
     288           1 :   relay_address_new_suggestion(&ds->ipv6_addr, &ds->ipv6_addr, ds->digest);
     289           1 :   resolved_addr_get_suggested(AF_INET6, &cache_addr);
     290           1 :   tt_assert(tor_addr_is_unspec(&cache_addr));
     291             : 
     292           1 :  done:
     293           1 :   dirlist_free_all();
     294             : 
     295           1 :   UNMOCK(server_mode);
     296           1 : }
     297             : 
     298             : static void
     299           1 : test_find_addr_to_publish(void *arg)
     300             : {
     301           1 :   int family;
     302           1 :   bool ret;
     303           1 :   tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
     304           1 :   or_options_t *options;
     305             : 
     306           1 :   (void) arg;
     307             : 
     308           1 :   options = options_new();
     309           1 :   options_init(options);
     310             : 
     311             :   /* Populate our resolved cache with a valid IPv4 and IPv6. */
     312           1 :   family = tor_addr_parse(&ipv4_addr, "1.2.3.4");
     313           1 :   tt_int_op(family, OP_EQ, AF_INET);
     314           1 :   resolved_addr_set_last(&ipv4_addr, RESOLVED_ADDR_CONFIGURED, NULL);
     315           1 :   resolved_addr_get_last(AF_INET, &cache_addr);
     316           1 :   tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
     317             : 
     318           1 :   family = tor_addr_parse(&ipv6_addr, "[4242::4242]");
     319           1 :   tt_int_op(family, OP_EQ, AF_INET6);
     320           1 :   resolved_addr_set_last(&ipv6_addr, RESOLVED_ADDR_CONFIGURED, NULL);
     321           1 :   resolved_addr_get_last(AF_INET6, &cache_addr);
     322           1 :   tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
     323             : 
     324             :   /* Setup ORPort config. */
     325             :   {
     326           1 :     int n, w, r;
     327           1 :     char *msg = NULL;
     328             : 
     329           1 :     config_line_append(&options->ORPort_lines, "ORPort", "9001");
     330             : 
     331           1 :     r = parse_ports(options, 0, &msg, &n, &w);
     332           1 :     tt_int_op(r, OP_EQ, 0);
     333             :   }
     334             : 
     335             :   /* 1. Address located in the resolved cache. */
     336           1 :   ret = relay_find_addr_to_publish(options, AF_INET,
     337             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     338           1 :   tt_assert(ret);
     339           1 :   tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
     340             : 
     341           1 :   ret = relay_find_addr_to_publish(options, AF_INET6,
     342             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     343           1 :   tt_assert(ret);
     344           1 :   tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
     345           1 :   resolved_addr_reset_last(AF_INET);
     346           1 :   resolved_addr_reset_last(AF_INET6);
     347             : 
     348             :   /* 2. No IP in the resolve cache, go to the suggested cache. We will ignore
     349             :    *    the find_my_address() code path because that is extensively tested in
     350             :    *    another unit tests. */
     351           1 :   resolved_addr_set_suggested(&ipv4_addr);
     352           1 :   ret = relay_find_addr_to_publish(options, AF_INET,
     353             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     354           1 :   tt_assert(ret);
     355           1 :   tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
     356             : 
     357           1 :   resolved_addr_set_suggested(&ipv6_addr);
     358           1 :   ret = relay_find_addr_to_publish(options, AF_INET6,
     359             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     360           1 :   tt_assert(ret);
     361           1 :   tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
     362           1 :   resolve_addr_reset_suggested(AF_INET);
     363           1 :   resolve_addr_reset_suggested(AF_INET6);
     364             : 
     365             :   /* 3. No IP anywhere. */
     366           1 :   ret = relay_find_addr_to_publish(options, AF_INET,
     367             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     368           1 :   tt_assert(!ret);
     369           1 :   ret = relay_find_addr_to_publish(options, AF_INET6,
     370             :                                    RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
     371           1 :   tt_assert(!ret);
     372             : 
     373           1 :  done:
     374           1 :   or_options_free(options);
     375           1 : }
     376             : 
     377             : struct testcase_t relay_tests[] = {
     378             :   { "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
     379             :     TT_FORK, NULL, NULL },
     380             :   { "close_circ_rephist", test_relay_close_circuit,
     381             :     TT_FORK, NULL, NULL },
     382             :   { "suggested_address", test_suggested_address,
     383             :     TT_FORK, NULL, NULL },
     384             :   { "find_addr_to_publish", test_find_addr_to_publish,
     385             :     TT_FORK, NULL, NULL },
     386             : 
     387             :   END_OF_TESTCASES
     388             : };

Generated by: LCOV version 1.14