tor

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

test_relay.c (12475B)


      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 mock_server_mode_true(const or_options_t *options)
     40 {
     41  (void) options;
     42  return 1;
     43 }
     44 
     45 static void
     46 assert_circuit_ok_mock(const circuit_t *c)
     47 {
     48  (void) c;
     49  return;
     50 }
     51 
     52 static void
     53 test_relay_close_circuit(void *arg)
     54 {
     55  channel_t *nchan = NULL, *pchan = NULL;
     56  or_circuit_t *orcirc = NULL;
     57  cell_t *cell = NULL;
     58  int old_count, new_count;
     59 
     60  (void)arg;
     61 
     62  /* Make fake channels to be nchan and pchan for the circuit */
     63  nchan = new_fake_channel();
     64  tt_assert(nchan);
     65 
     66  pchan = new_fake_channel();
     67  tt_assert(pchan);
     68 
     69  /* Make a fake orcirc */
     70  orcirc = new_fake_orcirc(nchan, pchan);
     71  tt_assert(orcirc);
     72  circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
     73                            CELL_DIRECTION_OUT);
     74  circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
     75                            CELL_DIRECTION_IN);
     76 
     77  /* Make a cell */
     78  cell = tor_malloc_zero(sizeof(cell_t));
     79  make_fake_cell(cell);
     80 
     81  MOCK(scheduler_channel_has_waiting_cells,
     82       scheduler_channel_has_waiting_cells_mock);
     83  MOCK(assert_circuit_ok,
     84       assert_circuit_ok_mock);
     85 
     86  /* Append it */
     87  old_count = get_mock_scheduler_has_waiting_cells_count();
     88  append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
     89                               CELL_DIRECTION_OUT, 0);
     90  new_count = get_mock_scheduler_has_waiting_cells_count();
     91  tt_int_op(new_count, OP_EQ, old_count + 1);
     92 
     93  /* Now try the reverse direction */
     94  old_count = get_mock_scheduler_has_waiting_cells_count();
     95  append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
     96                               CELL_DIRECTION_IN, 0);
     97  new_count = get_mock_scheduler_has_waiting_cells_count();
     98  tt_int_op(new_count, OP_EQ, old_count + 1);
     99 
    100  /* Ensure our write totals are 0 */
    101  tt_u64_op(find_largest_max(write_array, 86400), OP_EQ, 0);
    102 
    103  /* Mark the circuit for close */
    104  circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
    105 
    106  /* Check our write totals. */
    107  advance_obs(write_array);
    108  commit_max(write_array);
    109  /* Check for two cells plus overhead */
    110  tt_u64_op(find_largest_max(write_array, 86400), OP_EQ,
    111                             2*(get_cell_network_size(nchan->wide_circ_ids)
    112                                +TLS_PER_CELL_OVERHEAD));
    113 
    114  UNMOCK(scheduler_channel_has_waiting_cells);
    115 
    116  /* Get rid of the fake channels */
    117  MOCK(scheduler_release_channel, scheduler_release_channel_mock);
    118  channel_mark_for_close(nchan);
    119  channel_mark_for_close(pchan);
    120  UNMOCK(scheduler_release_channel);
    121 
    122  /* Shut down channels */
    123  channel_free_all();
    124 
    125 done:
    126  tor_free(cell);
    127  if (orcirc) {
    128    circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
    129    circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
    130    cell_queue_clear(&orcirc->base_.n_chan_cells);
    131    cell_queue_clear(&orcirc->p_chan_cells);
    132  }
    133  free_fake_orcirc(orcirc);
    134  free_fake_channel(nchan);
    135  free_fake_channel(pchan);
    136  UNMOCK(assert_circuit_ok);
    137 
    138  return;
    139 }
    140 
    141 static void
    142 test_relay_append_cell_to_circuit_queue(void *arg)
    143 {
    144  channel_t *nchan = NULL, *pchan = NULL;
    145  or_circuit_t *orcirc = NULL;
    146  cell_t *cell = NULL;
    147  int old_count, new_count;
    148 
    149  (void)arg;
    150 
    151  /* Make fake channels to be nchan and pchan for the circuit */
    152  nchan = new_fake_channel();
    153  tt_assert(nchan);
    154 
    155  pchan = new_fake_channel();
    156  tt_assert(pchan);
    157 
    158  /* Make a fake orcirc */
    159  orcirc = new_fake_orcirc(nchan, pchan);
    160  tt_assert(orcirc);
    161  circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
    162                            CELL_DIRECTION_OUT);
    163  circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
    164                            CELL_DIRECTION_IN);
    165 
    166  /* Make a cell */
    167  cell = tor_malloc_zero(sizeof(cell_t));
    168  make_fake_cell(cell);
    169 
    170  MOCK(scheduler_channel_has_waiting_cells,
    171       scheduler_channel_has_waiting_cells_mock);
    172 
    173  /* Append it */
    174  old_count = get_mock_scheduler_has_waiting_cells_count();
    175  append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
    176                               CELL_DIRECTION_OUT, 0);
    177  new_count = get_mock_scheduler_has_waiting_cells_count();
    178  tt_int_op(new_count, OP_EQ, old_count + 1);
    179 
    180  /* Now try the reverse direction */
    181  old_count = get_mock_scheduler_has_waiting_cells_count();
    182  append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
    183                               CELL_DIRECTION_IN, 0);
    184  new_count = get_mock_scheduler_has_waiting_cells_count();
    185  tt_int_op(new_count, OP_EQ, old_count + 1);
    186 
    187  UNMOCK(scheduler_channel_has_waiting_cells);
    188 
    189  /* Get rid of the fake channels */
    190  MOCK(scheduler_release_channel, scheduler_release_channel_mock);
    191  channel_mark_for_close(nchan);
    192  channel_mark_for_close(pchan);
    193  UNMOCK(scheduler_release_channel);
    194 
    195  /* Shut down channels */
    196  channel_free_all();
    197 
    198 done:
    199  tor_free(cell);
    200  if (orcirc) {
    201    circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
    202    circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
    203    cell_queue_clear(&orcirc->base_.n_chan_cells);
    204    cell_queue_clear(&orcirc->p_chan_cells);
    205  }
    206  free_fake_orcirc(orcirc);
    207  free_fake_channel(nchan);
    208  free_fake_channel(pchan);
    209 
    210  return;
    211 }
    212 
    213 static void
    214 test_suggested_address(void *arg)
    215 {
    216  int ret;
    217  const char *untrusted_id = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    218  dir_server_t *ds = NULL;
    219  tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
    220  tor_addr_t trusted_addr, untrusted_addr;
    221  tor_addr_port_t trusted_ap_v6 = { .port = 443 };
    222 
    223  (void) arg;
    224 
    225  MOCK(server_mode, mock_server_mode_true);
    226 
    227  /* Unstrusted relay source. */
    228  ret = tor_addr_parse(&untrusted_addr, "8.8.8.8");
    229  tt_int_op(ret, OP_EQ, AF_INET);
    230 
    231  /* Add gabelmoo as a trusted directory authority. */
    232  ret = tor_addr_parse(&trusted_addr, "[2001:638:a000:4140::ffff:189]");
    233  tt_int_op(ret, OP_EQ, AF_INET6);
    234  tor_addr_copy(&trusted_ap_v6.addr, &trusted_addr);
    235 
    236  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  tt_assert(ds);
    242  dir_server_add(ds);
    243 
    244  /* 1. Valid IPv4 from a trusted authority (gabelmoo). */
    245  ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
    246  relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
    247  resolved_addr_get_suggested(AF_INET, &cache_addr);
    248  tt_assert(tor_addr_eq(&cache_addr, &ipv4_addr));
    249  resolve_addr_reset_suggested(AF_INET);
    250 
    251  /* 2. Valid IPv6 from a trusted authority (gabelmoo). */
    252  ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
    253  relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
    254  resolved_addr_get_suggested(AF_INET6, &cache_addr);
    255  tt_assert(tor_addr_eq(&cache_addr, &ipv6_addr));
    256  resolve_addr_reset_suggested(AF_INET6);
    257 
    258  /* 3. Valid IPv4 but untrusted source. */
    259  ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
    260  relay_address_new_suggestion(&ipv4_addr, &untrusted_addr, untrusted_id);
    261  resolved_addr_get_suggested(AF_INET, &cache_addr);
    262  tt_assert(tor_addr_is_unspec(&cache_addr));
    263 
    264  /* 4. Valid IPv6 but untrusted source. */
    265  ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
    266  relay_address_new_suggestion(&ipv6_addr, &untrusted_addr, untrusted_id);
    267  resolved_addr_get_suggested(AF_INET6, &cache_addr);
    268  tt_assert(tor_addr_is_unspec(&cache_addr));
    269 
    270  /* 5. Internal IPv4 from a trusted authority (gabelmoo). */
    271  ret = tor_addr_parse(&ipv4_addr, "127.0.0.1");
    272  relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
    273  resolved_addr_get_suggested(AF_INET, &cache_addr);
    274  tt_assert(tor_addr_is_unspec(&cache_addr));
    275 
    276  /* 6. Internal IPv6 from a trusted authority (gabelmoo). */
    277  ret = tor_addr_parse(&ipv6_addr, "[::1]");
    278  relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
    279  resolved_addr_get_suggested(AF_INET6, &cache_addr);
    280  tt_assert(tor_addr_is_unspec(&cache_addr));
    281 
    282  /* 7. IPv4 from a trusted authority (gabelmoo). */
    283  relay_address_new_suggestion(&ds->ipv4_addr, &ds->ipv4_addr, ds->digest);
    284  resolved_addr_get_suggested(AF_INET, &cache_addr);
    285  tt_assert(tor_addr_is_unspec(&cache_addr));
    286 
    287  /* 8. IPv6 from a trusted authority (gabelmoo). */
    288  relay_address_new_suggestion(&ds->ipv6_addr, &ds->ipv6_addr, ds->digest);
    289  resolved_addr_get_suggested(AF_INET6, &cache_addr);
    290  tt_assert(tor_addr_is_unspec(&cache_addr));
    291 
    292 done:
    293  dirlist_free_all();
    294 
    295  UNMOCK(server_mode);
    296 }
    297 
    298 static void
    299 test_find_addr_to_publish(void *arg)
    300 {
    301  int family;
    302  bool ret;
    303  tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
    304  or_options_t *options;
    305 
    306  (void) arg;
    307 
    308  options = options_new();
    309  options_init(options);
    310 
    311  /* Populate our resolved cache with a valid IPv4 and IPv6. */
    312  family = tor_addr_parse(&ipv4_addr, "1.2.3.4");
    313  tt_int_op(family, OP_EQ, AF_INET);
    314  resolved_addr_set_last(&ipv4_addr, RESOLVED_ADDR_CONFIGURED, NULL);
    315  resolved_addr_get_last(AF_INET, &cache_addr);
    316  tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
    317 
    318  family = tor_addr_parse(&ipv6_addr, "[4242::4242]");
    319  tt_int_op(family, OP_EQ, AF_INET6);
    320  resolved_addr_set_last(&ipv6_addr, RESOLVED_ADDR_CONFIGURED, NULL);
    321  resolved_addr_get_last(AF_INET6, &cache_addr);
    322  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
    323 
    324  /* Setup ORPort config. */
    325  {
    326    int n, w, r;
    327    char *msg = NULL;
    328 
    329    config_line_append(&options->ORPort_lines, "ORPort", "9001");
    330 
    331    r = parse_ports(options, 0, &msg, &n, &w);
    332    tt_int_op(r, OP_EQ, 0);
    333  }
    334 
    335  /* 1. Address located in the resolved cache. */
    336  ret = relay_find_addr_to_publish(options, AF_INET,
    337                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    338  tt_assert(ret);
    339  tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
    340 
    341  ret = relay_find_addr_to_publish(options, AF_INET6,
    342                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    343  tt_assert(ret);
    344  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
    345  resolved_addr_reset_last(AF_INET);
    346  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  resolved_addr_set_suggested(&ipv4_addr);
    352  ret = relay_find_addr_to_publish(options, AF_INET,
    353                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    354  tt_assert(ret);
    355  tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
    356 
    357  resolved_addr_set_suggested(&ipv6_addr);
    358  ret = relay_find_addr_to_publish(options, AF_INET6,
    359                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    360  tt_assert(ret);
    361  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
    362  resolve_addr_reset_suggested(AF_INET);
    363  resolve_addr_reset_suggested(AF_INET6);
    364 
    365  /* 3. No IP anywhere. */
    366  ret = relay_find_addr_to_publish(options, AF_INET,
    367                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    368  tt_assert(!ret);
    369  ret = relay_find_addr_to_publish(options, AF_INET6,
    370                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
    371  tt_assert(!ret);
    372 
    373 done:
    374  or_options_free(options);
    375 }
    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 };