tor

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

test_router.c (20286B)


      1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
      2 /* Copyright (c) 2017, isis agora lovecruft  */
      3 /* See LICENSE for licensing information     */
      4 
      5 /**
      6 * \file test_router.c
      7 * \brief Unittests for code in router.c
      8 **/
      9 
     10 #define CONFIG_PRIVATE
     11 #define CONNECTION_PRIVATE
     12 #define ROUTER_PRIVATE
     13 
     14 #include "core/or/or.h"
     15 #include "app/config/config.h"
     16 #include "core/mainloop/mainloop.h"
     17 #include "core/mainloop/connection.h"
     18 #include "feature/hibernate/hibernate.h"
     19 #include "feature/nodelist/networkstatus.h"
     20 #include "feature/nodelist/networkstatus_st.h"
     21 #include "feature/nodelist/node_st.h"
     22 #include "feature/nodelist/nodelist.h"
     23 #include "feature/nodelist/routerinfo_st.h"
     24 #include "feature/nodelist/routerlist.h"
     25 #include "feature/nodelist/routerstatus_st.h"
     26 #include "feature/nodelist/torcert.h"
     27 #include "feature/relay/router.h"
     28 #include "feature/stats/bwhist.h"
     29 #include "lib/crypt_ops/crypto_curve25519.h"
     30 #include "lib/crypt_ops/crypto_ed25519.h"
     31 #include "lib/encoding/confline.h"
     32 
     33 #include "core/or/listener_connection_st.h"
     34 
     35 /* Test suite stuff */
     36 #include "test/test.h"
     37 #include "test/log_test_helpers.h"
     38 
     39 static routerinfo_t *
     40 rtr_tests_gen_routerinfo(crypto_pk_t *ident_key, crypto_pk_t *tap_key)
     41 {
     42  time_t now;
     43 
     44  routerinfo_t *mock_routerinfo;
     45 
     46  /* Mock the published timestamp, otherwise router_dump_router_to_string()
     47   * will poop its pants. */
     48  time(&now);
     49 
     50  /* We'll need keys, or router_dump_router_to_string() would return NULL. */
     51  tor_assert(ident_key != NULL);
     52  tor_assert(tap_key != NULL);
     53 
     54  mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
     55  mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
     56  tor_addr_from_ipv4h(&mock_routerinfo->ipv4_addr, 123456789);
     57  mock_routerinfo->ipv4_orport = 443;
     58  mock_routerinfo->platform = tor_strdup("unittest");
     59  mock_routerinfo->cache_info.published_on = now;
     60  mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
     61  mock_routerinfo->protocol_list =
     62    tor_strdup("Cons=1-2 Desc=1-2 DirCache=1-2");
     63  router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->tap_onion_pkey,
     64                            &mock_routerinfo->tap_onion_pkey_len);
     65  mock_routerinfo->bandwidthrate = 9001;
     66  mock_routerinfo->bandwidthburst = 9002;
     67 
     68  return mock_routerinfo;
     69 }
     70 
     71 /* If no distribution option was set, then check_bridge_distribution_setting()
     72 * should have set it to "any". */
     73 static void
     74 test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
     75 {
     76  const char* needle = "bridge-distribution-request any";
     77  or_options_t* options = get_options_mutable();
     78  routerinfo_t* router = NULL;
     79  curve25519_keypair_t ntor_keypair;
     80  ed25519_keypair_t signing_keypair;
     81  ed25519_keypair_t identity_keypair;
     82  char* desc = NULL;
     83  char* found = NULL;
     84  (void)arg;
     85  crypto_pk_t *ident_key = pk_generate(0);
     86  crypto_pk_t *tap_key = pk_generate(0);
     87 
     88  options->ORPort_set = 1;
     89  options->BridgeRelay = 1;
     90 
     91  /* Generate keys which router_dump_router_to_string() expects to exist. */
     92  tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ntor_keypair, 0));
     93  tt_int_op(0, OP_EQ, ed25519_keypair_generate(&signing_keypair, 0));
     94  tt_int_op(0, OP_EQ, ed25519_keypair_generate(&identity_keypair, 0));
     95 
     96  /* Set up part of our routerinfo_t so that we don't trigger any other
     97   * assertions in router_dump_router_to_string(). */
     98  router = rtr_tests_gen_routerinfo(ident_key, tap_key);
     99  tt_ptr_op(router, OP_NE, NULL);
    100 
    101  router->cache_info.signing_key_cert =
    102    tor_cert_create_ed25519(&identity_keypair,
    103                            CERT_TYPE_ID_SIGNING,
    104                            &signing_keypair.pubkey,
    105                            time(NULL),
    106                            86400,
    107                            CERT_FLAG_INCLUDE_SIGNING_KEY);
    108 
    109  /* The real router_get_my_routerinfo() looks up onion_curve25519_pkey using
    110   * get_current_curve25519_keypair(), but we don't initialise static data in
    111   * this test. */
    112  router->onion_curve25519_pkey = &ntor_keypair.pubkey;
    113 
    114  /* Generate our server descriptor and ensure that the substring
    115   * "bridge-distribution-request any" occurs somewhere within it. */
    116  desc = router_dump_router_to_string(router,
    117                                      ident_key,
    118                                      tap_key,
    119                                      &ntor_keypair,
    120                                      &signing_keypair);
    121  tt_ptr_op(desc, OP_NE, NULL);
    122  found = strstr(desc, needle);
    123  tt_ptr_op(found, OP_NE, NULL);
    124 
    125 done:
    126  if (router)
    127    router->onion_curve25519_pkey = NULL; // avoid double-free
    128  routerinfo_free(router);
    129  tor_free(desc);
    130  crypto_pk_free(ident_key);
    131  crypto_pk_free(tap_key);
    132 }
    133 
    134 static routerinfo_t *mock_router_get_my_routerinfo_result = NULL;
    135 
    136 static const routerinfo_t *
    137 mock_router_get_my_routerinfo(void)
    138 {
    139  return mock_router_get_my_routerinfo_result;
    140 }
    141 
    142 static long
    143 mock_get_uptime_3h(void)
    144 {
    145  return 3*60*60;
    146 }
    147 
    148 static long
    149 mock_get_uptime_1d(void)
    150 {
    151  return 24*60*60;
    152 }
    153 
    154 static int
    155 mock_rep_hist_bandwidth_assess(void)
    156 {
    157  return 20001;
    158 }
    159 
    160 static int
    161 mock_we_are_not_hibernating(void)
    162 {
    163  return 0;
    164 }
    165 
    166 static int
    167 mock_we_are_hibernating(void)
    168 {
    169  return 0;
    170 }
    171 
    172 static void
    173 test_router_check_descriptor_bandwidth_changed(void *arg)
    174 {
    175  (void)arg;
    176  routerinfo_t routerinfo;
    177  memset(&routerinfo, 0, sizeof(routerinfo));
    178  mock_router_get_my_routerinfo_result = NULL;
    179 
    180  MOCK(we_are_hibernating, mock_we_are_not_hibernating);
    181  MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
    182  mock_router_get_my_routerinfo_result = &routerinfo;
    183 
    184  /* When uptime is less than 24h, no previous bandwidth, no last_changed
    185   * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
    186  routerinfo.bandwidthcapacity = 0;
    187  MOCK(get_uptime, mock_get_uptime_3h);
    188  setup_full_capture_of_logs(LOG_INFO);
    189  check_descriptor_bandwidth_changed(time(NULL));
    190  expect_log_msg_not_containing(
    191     "Measured bandwidth has changed; rebuilding descriptor.");
    192  teardown_capture_of_logs();
    193 
    194  /* When uptime is less than 24h, previous bandwidth,
    195   * last_changed more than 3h ago
    196   * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
    197  routerinfo.bandwidthcapacity = 10000;
    198  setup_full_capture_of_logs(LOG_INFO);
    199  check_descriptor_bandwidth_changed(time(NULL));
    200  expect_log_msg_containing(
    201     "Measured bandwidth has changed; rebuilding descriptor.");
    202  teardown_capture_of_logs();
    203 
    204  /* When uptime is less than 24h, previous bandwidth,
    205   * last_changed more than 3h ago, and hibernating
    206   * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
    207 
    208  UNMOCK(we_are_hibernating);
    209  MOCK(we_are_hibernating, mock_we_are_hibernating);
    210  routerinfo.bandwidthcapacity = 10000;
    211  setup_full_capture_of_logs(LOG_INFO);
    212  check_descriptor_bandwidth_changed(time(NULL));
    213  expect_log_msg_not_containing(
    214     "Measured bandwidth has changed; rebuilding descriptor.");
    215  teardown_capture_of_logs();
    216  UNMOCK(we_are_hibernating);
    217  MOCK(we_are_hibernating, mock_we_are_not_hibernating);
    218 
    219  /* When uptime is less than 24h, last_changed is not more than 3h ago
    220   * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
    221  setup_full_capture_of_logs(LOG_INFO);
    222  check_descriptor_bandwidth_changed(time(NULL));
    223  expect_log_msg_not_containing(
    224     "Measured bandwidth has changed; rebuilding descriptor.");
    225  teardown_capture_of_logs();
    226 
    227  /* When uptime is less than 24h and bandwidthcapacity does not change
    228   * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
    229  MOCK(bwhist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
    230  setup_full_capture_of_logs(LOG_INFO);
    231  check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
    232  expect_log_msg_containing(
    233     "Measured bandwidth has changed; rebuilding descriptor.");
    234  UNMOCK(get_uptime);
    235  UNMOCK(bwhist_bandwidth_assess);
    236  teardown_capture_of_logs();
    237 
    238  /* When uptime is more than 24h */
    239  MOCK(get_uptime, mock_get_uptime_1d);
    240  setup_full_capture_of_logs(LOG_INFO);
    241  check_descriptor_bandwidth_changed(time(NULL));
    242  expect_log_msg_not_containing(
    243     "Measured bandwidth has changed; rebuilding descriptor.");
    244  teardown_capture_of_logs();
    245 
    246 done:
    247  UNMOCK(get_uptime);
    248  UNMOCK(router_get_my_routerinfo);
    249  UNMOCK(we_are_hibernating);
    250 }
    251 
    252 static networkstatus_t *mock_ns = NULL;
    253 static networkstatus_t *
    254 mock_networkstatus_get_live_consensus(time_t now)
    255 {
    256  (void)now;
    257  return mock_ns;
    258 }
    259 
    260 static routerstatus_t *mock_rs = NULL;
    261 static const routerstatus_t *
    262 mock_networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
    263 {
    264  (void)ns;
    265  (void)digest;
    266  return mock_rs;
    267 }
    268 
    269 static void
    270 test_router_mark_if_too_old(void *arg)
    271 {
    272  (void)arg;
    273  time_t now = approx_time();
    274  MOCK(networkstatus_get_live_consensus,
    275       mock_networkstatus_get_live_consensus);
    276  MOCK(networkstatus_vote_find_entry, mock_networkstatus_vote_find_entry);
    277 
    278  routerstatus_t rs;
    279  networkstatus_t ns;
    280  memset(&rs, 0, sizeof(rs));
    281  memset(&ns, 0, sizeof(ns));
    282  mock_ns = &ns;
    283  mock_ns->valid_after = now-3600;
    284  mock_rs = &rs;
    285 
    286  // no reason to mark this time.
    287  desc_clean_since = now-10;
    288  desc_dirty_reason = NULL;
    289  mark_my_descriptor_dirty_if_too_old(now);
    290  tt_i64_op(desc_clean_since, OP_EQ, now-10);
    291 
    292  // Doesn't appear in consensus?  Still don't mark it.
    293  mock_ns = NULL;
    294  mark_my_descriptor_dirty_if_too_old(now);
    295  tt_i64_op(desc_clean_since, OP_EQ, now-10);
    296  mock_ns = &ns;
    297 
    298  // No new descriptor in a long time?  Mark it.
    299  desc_clean_since = now - 3600 * 96;
    300  mark_my_descriptor_dirty_if_too_old(now);
    301  tt_i64_op(desc_clean_since, OP_EQ, 0);
    302  tt_str_op(desc_dirty_reason, OP_EQ, "time for new descriptor");
    303 
    304  desc_clean_since = now - 10;
    305  desc_dirty_reason = NULL;
    306  mark_my_descriptor_dirty_if_too_old(now);
    307  tt_i64_op(desc_clean_since, OP_EQ, now - 10);
    308 
    309  // Version in consensus marked as stale?  We'll mark it.
    310  desc_clean_since = now - 2 * 3600;
    311  desc_dirty_reason = NULL;
    312  mock_rs->is_staledesc = 1;
    313  mark_my_descriptor_dirty_if_too_old(now);
    314  tt_i64_op(desc_clean_since, OP_EQ, 0);
    315  tt_str_op(desc_dirty_reason, OP_EQ,
    316            "listed as stale in consensus");
    317 
    318  // same deal if we're absent from the consensus.
    319  desc_clean_since = now - 2 * 3600;
    320  desc_dirty_reason = NULL;
    321  mock_rs = NULL;
    322  mark_my_descriptor_dirty_if_too_old(now);
    323  tt_i64_op(desc_clean_since, OP_EQ, 0);
    324  tt_str_op(desc_dirty_reason, OP_EQ,
    325            "not listed in consensus");
    326 
    327 done:
    328  UNMOCK(networkstatus_get_live_consensus);
    329  UNMOCK(networkstatus_vote_find_entry);
    330 }
    331 
    332 static node_t fake_node;
    333 static const node_t *
    334 mock_node_get_by_nickname(const char *name, unsigned flags)
    335 {
    336  (void)flags;
    337  if (!strcasecmp(name, "crumpet"))
    338    return &fake_node;
    339  else
    340    return NULL;
    341 }
    342 
    343 static void
    344 test_router_get_my_family(void *arg)
    345 {
    346  (void)arg;
    347  or_options_t *options = options_new();
    348  smartlist_t *sl = NULL;
    349  char *join = NULL;
    350  // Overwrite the result of router_get_my_identity_digest().  This
    351  // happens to be okay, but only for testing.
    352  set_server_identity_key_digest_testing(
    353                                   (const uint8_t*)"holeinthebottomofthe");
    354 
    355  setup_capture_of_logs(LOG_WARN);
    356 
    357  // No family listed -- so there's no list.
    358  sl = get_my_declared_family(options);
    359  tt_ptr_op(sl, OP_EQ, NULL);
    360  expect_no_log_entry();
    361 
    362 #define CLEAR() do {                                    \
    363    if (sl) {                                           \
    364      SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));  \
    365      smartlist_free(sl);                               \
    366    }                                                   \
    367    tor_free(join);                                     \
    368    mock_clean_saved_logs();                            \
    369  } while (0)
    370 
    371  // Add a single nice friendly hex member.  This should be enough
    372  // to have our own ID added.
    373  tt_ptr_op(options->MyFamily, OP_EQ, NULL);
    374  config_line_append(&options->MyFamily, "MyFamily",
    375                     "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    376 
    377  sl = get_my_declared_family(options);
    378  tt_ptr_op(sl, OP_NE, NULL);
    379  tt_int_op(smartlist_len(sl), OP_EQ, 2);
    380  join = smartlist_join_strings(sl, " ", 0, NULL);
    381  tt_str_op(join, OP_EQ,
    382            "$686F6C65696E746865626F74746F6D6F66746865 "
    383            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    384  expect_no_log_entry();
    385  CLEAR();
    386 
    387  // Add a hex member with a ~.  The ~ part should get removed.
    388  config_line_append(&options->MyFamily, "MyFamily",
    389                     "$0123456789abcdef0123456789abcdef01234567~Muffin");
    390  sl = get_my_declared_family(options);
    391  tt_ptr_op(sl, OP_NE, NULL);
    392  tt_int_op(smartlist_len(sl), OP_EQ, 3);
    393  join = smartlist_join_strings(sl, " ", 0, NULL);
    394  tt_str_op(join, OP_EQ,
    395            "$0123456789ABCDEF0123456789ABCDEF01234567 "
    396            "$686F6C65696E746865626F74746F6D6F66746865 "
    397            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    398  expect_no_log_entry();
    399  CLEAR();
    400 
    401  // Nickname lookup will fail, so a nickname will appear verbatim.
    402  config_line_append(&options->MyFamily, "MyFamily",
    403                     "BAGEL");
    404  sl = get_my_declared_family(options);
    405  tt_ptr_op(sl, OP_NE, NULL);
    406  tt_int_op(smartlist_len(sl), OP_EQ, 4);
    407  join = smartlist_join_strings(sl, " ", 0, NULL);
    408  tt_str_op(join, OP_EQ,
    409            "$0123456789ABCDEF0123456789ABCDEF01234567 "
    410            "$686F6C65696E746865626F74746F6D6F66746865 "
    411            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
    412            "bagel");
    413  expect_single_log_msg_containing(
    414           "There is a router named \"BAGEL\" in my declared family, but "
    415           "I have no descriptor for it.");
    416  CLEAR();
    417 
    418  // A bogus digest should fail entirely.
    419  config_line_append(&options->MyFamily, "MyFamily",
    420                     "$painauchocolat");
    421  sl = get_my_declared_family(options);
    422  tt_ptr_op(sl, OP_NE, NULL);
    423  tt_int_op(smartlist_len(sl), OP_EQ, 4);
    424  join = smartlist_join_strings(sl, " ", 0, NULL);
    425  tt_str_op(join, OP_EQ,
    426            "$0123456789ABCDEF0123456789ABCDEF01234567 "
    427            "$686F6C65696E746865626F74746F6D6F66746865 "
    428            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
    429            "bagel");
    430  // "BAGEL" is still there, but it won't make a warning, because we already
    431  // warned about it.
    432  expect_single_log_msg_containing(
    433           "There is a router named \"$painauchocolat\" in my declared "
    434           "family, but that isn't a legal digest or nickname. Skipping it.");
    435  CLEAR();
    436 
    437  // Let's introduce a node we can look up by nickname
    438  memset(&fake_node, 0, sizeof(fake_node));
    439  memcpy(fake_node.identity, "whydoyouasknonononon", DIGEST_LEN);
    440  MOCK(node_get_by_nickname, mock_node_get_by_nickname);
    441 
    442  config_line_append(&options->MyFamily, "MyFamily",
    443                     "CRUmpeT");
    444  sl = get_my_declared_family(options);
    445  tt_ptr_op(sl, OP_NE, NULL);
    446  tt_int_op(smartlist_len(sl), OP_EQ, 5);
    447  join = smartlist_join_strings(sl, " ", 0, NULL);
    448  tt_str_op(join, OP_EQ,
    449            "$0123456789ABCDEF0123456789ABCDEF01234567 "
    450            "$686F6C65696E746865626F74746F6D6F66746865 "
    451            "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
    452            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
    453            "bagel");
    454  // "BAGEL" is still there, but it won't make a warning, because we already
    455  // warned about it.  Some with "$painauchocolat".
    456  expect_single_log_msg_containing(
    457           "There is a router named \"CRUmpeT\" in my declared "
    458           "family, but it wasn't listed by digest. Please consider saying "
    459           "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
    460           "what you meant.");
    461  CLEAR();
    462  UNMOCK(node_get_by_nickname);
    463 
    464  // Try a singleton list containing only us: It should give us NULL.
    465  config_free_lines(options->MyFamily);
    466  config_line_append(&options->MyFamily, "MyFamily",
    467                     "$686F6C65696E746865626F74746F6D6F66746865");
    468  sl = get_my_declared_family(options);
    469  tt_ptr_op(sl, OP_EQ, NULL);
    470  expect_no_log_entry();
    471 
    472 done:
    473  or_options_free(options);
    474  teardown_capture_of_logs();
    475  CLEAR();
    476  UNMOCK(node_get_by_nickname);
    477 
    478 #undef CLEAR
    479 }
    480 
    481 static smartlist_t *fake_connection_array = NULL;
    482 static smartlist_t *
    483 mock_get_connection_array(void)
    484 {
    485  return fake_connection_array;
    486 }
    487 
    488 static void
    489 test_router_get_advertised_or_port(void *arg)
    490 {
    491  (void)arg;
    492  int r, w=0, n=0;
    493  char *msg=NULL;
    494  or_options_t *opts = options_new();
    495  listener_connection_t *listener = NULL;
    496  tor_addr_port_t ipv6;
    497 
    498  // Test one failing case of routerconf_find_ipv6_or_ap().
    499  routerconf_find_ipv6_or_ap(opts, &ipv6);
    500  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
    501 
    502  // And one failing case of routerconf_find_or_port().
    503  tt_int_op(0, OP_EQ, routerconf_find_or_port(opts, AF_INET));
    504 
    505  // Set up a couple of configured ports.
    506  config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:auto");
    507  config_line_append(&opts->ORPort_lines, "ORPort", "5.6.7.8:9999");
    508  r = parse_ports(opts, 0, &msg, &n, &w);
    509  tt_assert(r == 0);
    510 
    511  // There are no listeners, so the "auto" case will turn up no results.
    512  tt_int_op(0, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
    513  routerconf_find_ipv6_or_ap(opts, &ipv6);
    514  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
    515 
    516  // This will return the matching value from the configured port.
    517  tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET));
    518 
    519  // Now set up a dummy listener.
    520  MOCK(get_connection_array, mock_get_connection_array);
    521  fake_connection_array = smartlist_new();
    522  listener = listener_connection_new(CONN_TYPE_OR_LISTENER, AF_INET6);
    523  TO_CONN(listener)->port = 54321;
    524  smartlist_add(fake_connection_array, TO_CONN(listener));
    525 
    526  // We should get a port this time.
    527  tt_int_op(54321, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
    528 
    529  // Test one succeeding case of routerconf_find_ipv6_or_ap().
    530  routerconf_find_ipv6_or_ap(opts, &ipv6);
    531  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ,
    532            "[1234::5678]:54321");
    533 
    534  // This will return the matching value from the configured port.
    535  tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET));
    536 
    537 done:
    538  or_options_free(opts);
    539  config_free_all();
    540  smartlist_free(fake_connection_array);
    541  connection_free_minimal(TO_CONN(listener));
    542  UNMOCK(get_connection_array);
    543 }
    544 
    545 static void
    546 test_router_get_advertised_or_port_localhost(void *arg)
    547 {
    548  (void)arg;
    549  int r, w=0, n=0;
    550  char *msg=NULL;
    551  or_options_t *opts = options_new();
    552  tor_addr_port_t ipv6;
    553 
    554  // Set up a couple of configured ports on localhost.
    555  config_line_append(&opts->ORPort_lines, "ORPort", "[::1]:9999");
    556  config_line_append(&opts->ORPort_lines, "ORPort", "127.0.0.1:8888");
    557  r = parse_ports(opts, 0, &msg, &n, &w);
    558  tt_assert(r == 0);
    559 
    560  // We should refuse to advertise them, since we have default dirauths.
    561  routerconf_find_ipv6_or_ap(opts, &ipv6);
    562  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
    563  // But the lower-level function should still report the correct value
    564  tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
    565 
    566  // The IPv4 checks are done in resolve_my_address(), which doesn't use
    567  // ORPorts so we can't test them here. (See #33681.) Both these lower-level
    568  // functions should still report the correct value.
    569  tt_int_op(8888, OP_EQ, routerconf_find_or_port(opts, AF_INET));
    570 
    571  // Now try with a fake authority set up.
    572  config_line_append(&opts->DirAuthorities, "DirAuthority",
    573                     "127.0.0.1:1066 "
    574                     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    575 
    576  tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
    577  routerconf_find_ipv6_or_ap(opts, &ipv6);
    578  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::1]:9999");
    579 
    580  tt_int_op(8888, OP_EQ, routerconf_find_or_port(opts, AF_INET));
    581 
    582 done:
    583  or_options_free(opts);
    584  config_free_all();
    585 }
    586 
    587 #define ROUTER_TEST(name, flags)                          \
    588  { #name, test_router_ ## name, flags, NULL, NULL }
    589 
    590 struct testcase_t router_tests[] = {
    591  ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
    592  ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
    593  ROUTER_TEST(mark_if_too_old, TT_FORK),
    594  ROUTER_TEST(get_my_family, TT_FORK),
    595  ROUTER_TEST(get_advertised_or_port, TT_FORK),
    596  ROUTER_TEST(get_advertised_or_port_localhost, TT_FORK),
    597  END_OF_TESTCASES
    598 };