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

          Line data    Source code
       1             : /* Copyright (c) 2001-2004, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : #define CIRCUITBUILD_PRIVATE
       7             : #define CIRCUITLIST_PRIVATE
       8             : #define ENTRYNODES_PRIVATE
       9             : 
      10             : #include "core/or/or.h"
      11             : 
      12             : #include "test/test.h"
      13             : #include "test/test_helpers.h"
      14             : #include "test/log_test_helpers.h"
      15             : 
      16             : #define CONFIG_PRIVATE
      17             : #include "app/config/config.h"
      18             : 
      19             : #include "core/or/channel.h"
      20             : #include "core/or/circuitbuild.h"
      21             : #include "core/or/circuitlist.h"
      22             : #include "core/or/circuituse.h"
      23             : #include "core/or/onion.h"
      24             : 
      25             : #include "core/or/cell_st.h"
      26             : #include "core/or/cpath_build_state_st.h"
      27             : #include "core/or/extend_info_st.h"
      28             : #include "core/or/origin_circuit_st.h"
      29             : #include "core/or/or_circuit_st.h"
      30             : 
      31             : #include "feature/client/entrynodes.h"
      32             : #include "feature/nodelist/nodelist.h"
      33             : #include "feature/nodelist/node_select.h"
      34             : #include "feature/relay/circuitbuild_relay.h"
      35             : #include "feature/relay/router.h"
      36             : #include "feature/relay/routermode.h"
      37             : 
      38             : #include "feature/nodelist/node_st.h"
      39             : #include "feature/nodelist/routerinfo_st.h"
      40             : 
      41             : /* Dummy nodes smartlist for testing */
      42             : static smartlist_t dummy_nodes;
      43             : /* Dummy exit extend_info for testing */
      44             : static extend_info_t dummy_ei;
      45             : 
      46             : static int
      47          18 : mock_count_acceptable_nodes(const smartlist_t *nodes, int direct)
      48             : {
      49          18 :   (void)nodes;
      50             : 
      51          18 :   return direct ? 1 : DEFAULT_ROUTE_LEN + 1;
      52             : }
      53             : 
      54             : /* Test route lengths when the caller of new_route_len() doesn't
      55             :  * specify exit_ei. */
      56             : static void
      57           1 : test_new_route_len_noexit(void *arg)
      58             : {
      59           1 :   int r;
      60             : 
      61           1 :   (void)arg;
      62           1 :   MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
      63             : 
      64           1 :   r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, NULL, &dummy_nodes);
      65           1 :   tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
      66             : 
      67           1 :   r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, NULL, &dummy_nodes);
      68           1 :   tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
      69             : 
      70           1 :   r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, NULL, &dummy_nodes);
      71           1 :   tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
      72             : 
      73           1 :  done:
      74           1 :   UNMOCK(count_acceptable_nodes);
      75           1 : }
      76             : 
      77             : /* Test route lengths where someone else chose the "exit" node, which
      78             :  * require an extra hop for safety. */
      79             : static void
      80           1 : test_new_route_len_unsafe_exit(void *arg)
      81             : {
      82           1 :   int r;
      83             : 
      84           1 :   (void)arg;
      85           1 :   MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
      86             : 
      87             :   /* connecting to hidden service directory */
      88           1 :   r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, &dummy_ei, &dummy_nodes);
      89           1 :   tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
      90             : 
      91             :   /* client connecting to introduction point */
      92           1 :   r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCING, &dummy_ei, &dummy_nodes);
      93           1 :   tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
      94             : 
      95             :   /* hidden service connecting to rendezvous point */
      96           1 :   r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, &dummy_ei, &dummy_nodes);
      97           1 :   tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
      98             : 
      99           1 :  done:
     100           1 :   UNMOCK(count_acceptable_nodes);
     101           1 : }
     102             : 
     103             : /* Test route lengths where we chose the "exit" node, which don't
     104             :  * require an extra hop for safety. */
     105             : static void
     106           1 : test_new_route_len_safe_exit(void *arg)
     107             : {
     108           1 :   int r;
     109             : 
     110           1 :   (void)arg;
     111           1 :   MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
     112             : 
     113             :   /* hidden service connecting to introduction point */
     114           1 :   r = new_route_len(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, &dummy_ei,
     115             :                     &dummy_nodes);
     116           1 :   tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
     117             : 
     118             :   /* router testing its own reachability */
     119           1 :   r = new_route_len(CIRCUIT_PURPOSE_TESTING, &dummy_ei, &dummy_nodes);
     120           1 :   tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
     121             : 
     122           1 :  done:
     123           1 :   UNMOCK(count_acceptable_nodes);
     124           1 : }
     125             : 
     126             : /* Make sure a non-fatal assertion fails when new_route_len() gets an
     127             :  * unexpected circuit purpose. */
     128             : static void
     129           1 : test_new_route_len_unhandled_exit(void *arg)
     130             : {
     131           1 :   int r;
     132             : 
     133           1 :   (void)arg;
     134             : #ifdef ALL_BUGS_ARE_FATAL
     135             :   /* Coverity (and maybe clang analyser) complain that the code following
     136             :    * tt_skip() is unconditionally unreachable. */
     137             : #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
     138             :   tt_skip();
     139             : #endif
     140             : #endif /* defined(ALL_BUGS_ARE_FATAL) */
     141             : 
     142           1 :   MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
     143             : 
     144           1 :   tor_capture_bugs_(1);
     145           1 :   setup_full_capture_of_logs(LOG_WARN);
     146           1 :   r = new_route_len(CIRCUIT_PURPOSE_CONTROLLER, &dummy_ei, &dummy_nodes);
     147           1 :   tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
     148           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     149           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     150             :             "!(exit_ei && !known_purpose)");
     151           1 :   expect_single_log_msg_containing("Unhandled purpose");
     152           1 :   expect_single_log_msg_containing("with a chosen exit; assuming routelen");
     153             : 
     154           1 :  done:
     155           1 :   teardown_capture_of_logs();
     156           1 :   tor_end_capture_bugs_();
     157           1 :   UNMOCK(count_acceptable_nodes);
     158           1 : }
     159             : 
     160             : static void
     161           1 : test_upgrade_from_guard_wait(void *arg)
     162             : {
     163           1 :   circuit_t *circ = NULL;
     164           1 :   origin_circuit_t *orig_circ = NULL;
     165           1 :   entry_guard_t *guard = NULL;
     166           1 :   smartlist_t *list = NULL;
     167             : 
     168           1 :   (void) arg;
     169             : 
     170           1 :   circ = dummy_origin_circuit_new(0);
     171           1 :   orig_circ = TO_ORIGIN_CIRCUIT(circ);
     172           1 :   tt_assert(orig_circ);
     173             : 
     174           1 :   orig_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
     175             : 
     176           1 :   circuit_set_state(circ, CIRCUIT_STATE_GUARD_WAIT);
     177             : 
     178             :   /* Put it in guard wait state. */
     179           1 :   guard = tor_malloc_zero(sizeof(*guard));
     180           1 :   guard->in_selection = get_guard_selection_info();
     181             : 
     182           2 :   orig_circ->guard_state =
     183           1 :     circuit_guard_state_new(guard, GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD,
     184             :                             NULL);
     185             : 
     186             :   /* Mark the circuit for close. */
     187           1 :   circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
     188           1 :   tt_int_op(circ->marked_for_close, OP_NE, 0);
     189             : 
     190             :   /* We shouldn't pick the mark for close circuit. */
     191           1 :   list = circuit_find_circuits_to_upgrade_from_guard_wait();
     192           1 :   tt_assert(!list);
     193             : 
     194           1 :  done:
     195           1 :   smartlist_free(list);
     196           1 :   circuit_free(circ);
     197           1 :   entry_guard_free_(guard);
     198           1 : }
     199             : 
     200             : static int server = 0;
     201             : static int
     202          21 : mock_server_mode(const or_options_t *options)
     203             : {
     204          21 :   (void)options;
     205          21 :   return server;
     206             : }
     207             : 
     208             : /* Test the different cases in circuit_extend_state_valid_helper(). */
     209             : static void
     210           1 : test_circuit_extend_state_valid(void *arg)
     211             : {
     212           1 :   (void)arg;
     213           1 :   circuit_t *circ = tor_malloc_zero(sizeof(circuit_t));
     214             : 
     215           1 :   server = 0;
     216           1 :   MOCK(server_mode, mock_server_mode);
     217             : 
     218           1 :   setup_full_capture_of_logs(LOG_INFO);
     219             : 
     220             :   /* Clients can't extend */
     221           1 :   server = 0;
     222           1 :   tt_int_op(circuit_extend_state_valid_helper(NULL), OP_EQ, -1);
     223           1 :   expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
     224           1 :   mock_clean_saved_logs();
     225             : 
     226             : #ifndef ALL_BUGS_ARE_FATAL
     227             :   /* Circuit must be non-NULL */
     228           1 :   tor_capture_bugs_(1);
     229           1 :   server = 1;
     230           1 :   tt_int_op(circuit_extend_state_valid_helper(NULL), OP_EQ, -1);
     231           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     232           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     233             :             "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
     234           1 :   tor_end_capture_bugs_();
     235           1 :   mock_clean_saved_logs();
     236             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
     237             : 
     238             :   /* n_chan and n_hop are NULL, this should succeed */
     239           1 :   server = 1;
     240           1 :   tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, 0);
     241           1 :   mock_clean_saved_logs();
     242             : 
     243             :   /* But clients still can't extend */
     244           1 :   server = 0;
     245           1 :   tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
     246           1 :   expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
     247           1 :   mock_clean_saved_logs();
     248             : 
     249             :   /* n_chan must be NULL */
     250           1 :   circ->n_chan = tor_malloc_zero(sizeof(channel_t));
     251           1 :   server = 1;
     252           1 :   tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
     253           1 :   expect_log_msg("n_chan already set. Bug/attack. Closing.\n");
     254           1 :   mock_clean_saved_logs();
     255           1 :   tor_free(circ->n_chan);
     256             : 
     257             :   /* n_hop must be NULL */
     258           1 :   circ->n_hop = tor_malloc_zero(sizeof(extend_info_t));
     259           1 :   server = 1;
     260           1 :   tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
     261           1 :   expect_log_msg("conn to next hop already launched. Bug/attack. Closing.\n");
     262           1 :   mock_clean_saved_logs();
     263           1 :   tor_free(circ->n_hop);
     264             : 
     265           1 :  done:
     266           1 :   tor_end_capture_bugs_();
     267           1 :   teardown_capture_of_logs();
     268             : 
     269           1 :   UNMOCK(server_mode);
     270           1 :   server = 0;
     271             : 
     272           1 :   tor_free(circ->n_chan);
     273           1 :   tor_free(circ->n_hop);
     274           1 :   tor_free(circ);
     275           1 : }
     276             : 
     277             : static node_t *mocked_node = NULL;
     278             : static const node_t *
     279           8 : mock_node_get_by_id(const char *identity_digest)
     280             : {
     281           8 :   (void)identity_digest;
     282           8 :   return mocked_node;
     283             : }
     284             : 
     285             : static bool mocked_supports_ed25519_link_authentication = 0;
     286             : static bool
     287           4 : mock_node_supports_ed25519_link_authentication(const node_t *node,
     288             :                                                bool compatible_with_us)
     289             : {
     290           4 :   (void)node;
     291           4 :   (void)compatible_with_us;
     292           4 :   return mocked_supports_ed25519_link_authentication;
     293             : }
     294             : 
     295             : static ed25519_public_key_t * mocked_ed25519_id = NULL;
     296             : static const ed25519_public_key_t *
     297           3 : mock_node_get_ed25519_id(const node_t *node)
     298             : {
     299           3 :   (void)node;
     300           3 :   return mocked_ed25519_id;
     301             : }
     302             : 
     303             : /* Test the different cases in circuit_extend_add_ed25519_helper(). */
     304             : static void
     305           1 : test_circuit_extend_add_ed25519(void *arg)
     306             : {
     307           1 :   (void)arg;
     308           1 :   extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
     309           1 :   extend_cell_t *old_ec = tor_malloc_zero(sizeof(extend_cell_t));
     310           1 :   extend_cell_t *zero_ec = tor_malloc_zero(sizeof(extend_cell_t));
     311             : 
     312           1 :   node_t *fake_node = tor_malloc_zero(sizeof(node_t));
     313           1 :   ed25519_public_key_t *fake_ed25519_id = NULL;
     314           1 :   fake_ed25519_id = tor_malloc_zero(sizeof(ed25519_public_key_t));
     315             : 
     316           1 :   MOCK(node_get_by_id, mock_node_get_by_id);
     317           1 :   MOCK(node_supports_ed25519_link_authentication,
     318             :        mock_node_supports_ed25519_link_authentication);
     319           1 :   MOCK(node_get_ed25519_id, mock_node_get_ed25519_id);
     320             : 
     321           1 :   setup_full_capture_of_logs(LOG_INFO);
     322             : 
     323             : #ifndef ALL_BUGS_ARE_FATAL
     324             :   /* The extend cell must be non-NULL */
     325           1 :   tor_capture_bugs_(1);
     326           1 :   tt_int_op(circuit_extend_add_ed25519_helper(NULL), OP_EQ, -1);
     327           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     328           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     329             :             "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
     330           1 :   tor_end_capture_bugs_();
     331           1 :   mock_clean_saved_logs();
     332             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
     333             : 
     334             :   /* The node id must be non-zero */
     335           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     336           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, -1);
     337           1 :   expect_log_msg(
     338           1 :     "Client asked me to extend without specifying an id_digest.\n");
     339             :   /* And nothing should have changed */
     340           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     341           1 :   mock_clean_saved_logs();
     342             : 
     343             :   /* Fill in fake node_id, and try again */
     344           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     345           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     346           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     347             :   /* There's no node with that id, so the ed pubkey should still be zeroed */
     348           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     349             :   /* In fact, nothing should have changed */
     350           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     351           1 :   mock_clean_saved_logs();
     352             : 
     353             :   /* Provide 2 out of 3 of node, supports link auth, and ed_id.
     354             :    * The ed_id should remain zeroed. */
     355             : 
     356             :   /* Provide node and supports link auth */
     357           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     358           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     359             :   /* Set up the fake variables */
     360           1 :   mocked_node = fake_node;
     361           1 :   mocked_supports_ed25519_link_authentication = 1;
     362             :   /* Do the test */
     363           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     364             :   /* The ed pubkey should still be zeroed */
     365           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     366             :   /* In fact, nothing should have changed */
     367           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     368             :   /* Cleanup */
     369           1 :   mock_clean_saved_logs();
     370           1 :   mocked_node = NULL;
     371           1 :   mocked_supports_ed25519_link_authentication = 0;
     372           1 :   mocked_ed25519_id = NULL;
     373           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     374             : 
     375             :   /* Provide supports link auth and ed id */
     376           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     377           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     378             :   /* Set up the fake variables */
     379           1 :   mocked_supports_ed25519_link_authentication = 1;
     380           1 :   memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
     381           1 :   mocked_ed25519_id = fake_ed25519_id;
     382             :   /* Do the test */
     383           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     384             :   /* The ed pubkey should still be zeroed */
     385           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     386             :   /* In fact, nothing should have changed */
     387           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     388             :   /* Cleanup */
     389           1 :   mock_clean_saved_logs();
     390           1 :   mocked_node = NULL;
     391           1 :   mocked_supports_ed25519_link_authentication = 0;
     392           1 :   mocked_ed25519_id = NULL;
     393           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     394             : 
     395             :   /* Provide node and ed id */
     396           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     397           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     398             :   /* Set up the fake variables */
     399           1 :   mocked_node = fake_node;
     400           1 :   memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
     401           1 :   mocked_ed25519_id = fake_ed25519_id;
     402             :   /* Do the test */
     403           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     404             :   /* The ed pubkey should still be zeroed */
     405           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     406             :   /* In fact, nothing should have changed */
     407           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     408             :   /* Cleanup */
     409           1 :   mock_clean_saved_logs();
     410           1 :   mocked_node = NULL;
     411           1 :   mocked_supports_ed25519_link_authentication = 0;
     412           1 :   mocked_ed25519_id = NULL;
     413           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     414             : 
     415             :   /* Now do the real lookup */
     416           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     417           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     418             :   /* Set up the fake variables */
     419           1 :   mocked_node = fake_node;
     420           1 :   mocked_supports_ed25519_link_authentication = 1;
     421           1 :   memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
     422           1 :   mocked_ed25519_id = fake_ed25519_id;
     423             :   /* Do the test */
     424           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     425             :   /* The ed pubkey should match */
     426           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, fake_ed25519_id, sizeof(ec->ed_pubkey));
     427             :   /* Nothing else should have changed */
     428           1 :   memcpy(&ec->ed_pubkey, &old_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     429           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     430             :   /* Cleanup */
     431           1 :   mock_clean_saved_logs();
     432           1 :   mocked_node = NULL;
     433           1 :   mocked_supports_ed25519_link_authentication = 0;
     434           1 :   mocked_ed25519_id = NULL;
     435           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     436             : 
     437             :   /* Now do the real lookup, but with a zeroed ed id */
     438           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     439           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     440             :   /* Set up the fake variables */
     441           1 :   mocked_node = fake_node;
     442           1 :   mocked_supports_ed25519_link_authentication = 1;
     443           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     444           1 :   mocked_ed25519_id = fake_ed25519_id;
     445             :   /* Do the test */
     446           1 :   tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
     447             :   /* The ed pubkey should match */
     448           1 :   tt_mem_op(&ec->ed_pubkey, OP_EQ, fake_ed25519_id, sizeof(ec->ed_pubkey));
     449             :   /* Nothing else should have changed */
     450           1 :   memcpy(&ec->ed_pubkey, &old_ec->ed_pubkey, sizeof(ec->ed_pubkey));
     451           1 :   tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
     452             :   /* Cleanup */
     453           1 :   mock_clean_saved_logs();
     454           1 :   mocked_node = NULL;
     455           1 :   mocked_supports_ed25519_link_authentication = 0;
     456           1 :   mocked_ed25519_id = NULL;
     457           1 :   memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
     458             : 
     459           1 :  done:
     460           1 :   UNMOCK(node_get_by_id);
     461           1 :   UNMOCK(node_supports_ed25519_link_authentication);
     462           1 :   UNMOCK(node_get_ed25519_id);
     463             : 
     464           1 :   tor_end_capture_bugs_();
     465           1 :   teardown_capture_of_logs();
     466             : 
     467           1 :   tor_free(ec);
     468           1 :   tor_free(old_ec);
     469           1 :   tor_free(zero_ec);
     470             : 
     471           1 :   tor_free(fake_ed25519_id);
     472           1 :   tor_free(fake_node);
     473           1 : }
     474             : 
     475             : static or_options_t *mocked_options = NULL;
     476             : static const or_options_t *
     477          51 : mock_get_options(void)
     478             : {
     479          51 :   return mocked_options;
     480             : }
     481             : 
     482             : #define PUBLIC_IPV4   "1.2.3.4"
     483             : #define INTERNAL_IPV4 "0.0.0.1"
     484             : 
     485             : #define PUBLIC_IPV6   "1234::cdef"
     486             : #define INTERNAL_IPV6 "::1"
     487             : 
     488             : #define VALID_PORT    0x1234
     489             : 
     490             : /* Test the different cases in circuit_extend_lspec_valid_helper(). */
     491             : static void
     492           1 : test_circuit_extend_lspec_valid(void *arg)
     493             : {
     494           1 :   (void)arg;
     495           1 :   extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
     496           1 :   channel_t *p_chan = tor_malloc_zero(sizeof(channel_t));
     497           1 :   or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
     498           1 :   circuit_t *circ = TO_CIRCUIT(or_circ);
     499             : 
     500           1 :   or_options_t *fake_options = options_new();
     501           1 :   MOCK(get_options, mock_get_options);
     502           1 :   mocked_options = fake_options;
     503             : 
     504           1 :   setup_full_capture_of_logs(LOG_INFO);
     505             : 
     506             : #ifndef ALL_BUGS_ARE_FATAL
     507             :   /* Extend cell must be non-NULL */
     508           1 :   tor_capture_bugs_(1);
     509           1 :   tt_int_op(circuit_extend_lspec_valid_helper(NULL, circ), OP_EQ, -1);
     510           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     511           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     512             :             "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
     513           1 :   tor_end_capture_bugs_();
     514           1 :   mock_clean_saved_logs();
     515             : 
     516             :   /* Circuit must be non-NULL */
     517           1 :   tor_capture_bugs_(1);
     518           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, NULL), OP_EQ, -1);
     519           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     520           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     521             :             "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
     522           1 :   tor_end_capture_bugs_();
     523           1 :   mock_clean_saved_logs();
     524             : 
     525             :   /* Extend cell and circuit must be non-NULL */
     526           1 :   tor_capture_bugs_(1);
     527           1 :   tt_int_op(circuit_extend_lspec_valid_helper(NULL, NULL), OP_EQ, -1);
     528             :   /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
     529           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
     530           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
     531           1 :   tor_end_capture_bugs_();
     532           1 :   mock_clean_saved_logs();
     533             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
     534             : 
     535             :   /* IPv4 and IPv6 addr and port are all zero, this should fail */
     536           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     537           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
     538           1 :                  "or unspecified address '[scrubbed]'.\n");
     539           1 :   mock_clean_saved_logs();
     540             : 
     541             :   /* Now ask for the actual address in the logs */
     542           1 :   fake_options->SafeLogging_ = SAFELOG_SCRUB_NONE;
     543             : 
     544             :   /* IPv4 port is 0, IPv6 addr and port are both zero, this should fail */
     545           1 :   tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
     546           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     547           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
     548           1 :                  "or IPv4 address '1.2.3.4:0'.\n");
     549           1 :   mock_clean_saved_logs();
     550           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     551           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     552             : 
     553             :   /* IPv4 addr is 0, IPv6 addr and port are both zero, this should fail */
     554           1 :   ec->orport_ipv4.port = VALID_PORT;
     555           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     556           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
     557           1 :                  "or IPv4 address '0.0.0.0:4660'.\n");
     558           1 :   mock_clean_saved_logs();
     559           1 :   ec->orport_ipv4.port = 0;
     560           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     561           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     562             : 
     563             :   /* IPv4 addr is internal, and port is valid.
     564             :    * (IPv6 addr and port are both zero.)
     565             :    * Result depends on ExtendAllowPrivateAddresses. */
     566           1 :   tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
     567           1 :   ec->orport_ipv4.port = VALID_PORT;
     568             : 
     569           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     570           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     571           1 :   expect_log_msg("Client asked me to extend "
     572           1 :                  "to a private IPv4 address '0.0.0.1'.\n");
     573           1 :   mock_clean_saved_logs();
     574           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     575           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     576           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     577             : 
     578             :   /* Now do the same tests, but for IPv6 */
     579             : 
     580             :   /* IPv6 port is 0, IPv4 addr and port are both zero, this should fail */
     581           1 :   tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
     582           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     583           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
     584           1 :                  "or IPv6 address '[1234::cdef]:0'.\n");
     585           1 :   mock_clean_saved_logs();
     586           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     587           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     588             : 
     589             :   /* IPv6 addr is 0, IPv4 addr and port are both zero, this should fail */
     590           1 :   ec->orport_ipv6.port = VALID_PORT;
     591           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     592           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
     593           1 :                  "or IPv6 address '[::]:4660'.\n");
     594           1 :   mock_clean_saved_logs();
     595           1 :   ec->orport_ipv4.port = 0;
     596           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     597           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     598             : 
     599             :   /* IPv6 addr is internal, and port is valid.
     600             :    * (IPv4 addr and port are both zero.)
     601             :    * Result depends on ExtendAllowPrivateAddresses. */
     602           1 :   tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
     603           1 :   ec->orport_ipv6.port = VALID_PORT;
     604             : 
     605           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     606           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     607           1 :   expect_log_msg("Client asked me to extend "
     608           1 :                  "to a private IPv6 address '[::1]'.\n");
     609           1 :   mock_clean_saved_logs();
     610           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     611           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     612           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     613             : 
     614             :   /* Both addresses are internal.
     615             :    * Result depends on ExtendAllowPrivateAddresses. */
     616           1 :   tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
     617           1 :   ec->orport_ipv4.port = VALID_PORT;
     618           1 :   tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
     619           1 :   ec->orport_ipv6.port = VALID_PORT;
     620             : 
     621           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     622           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     623           1 :   expect_log_msg("Client asked me to extend "
     624           1 :                  "to a private IPv4 address '0.0.0.1'.\n");
     625           1 :   expect_log_msg("Client asked me to extend "
     626           1 :                  "to a private IPv6 address '[::1]'.\n");
     627           1 :   mock_clean_saved_logs();
     628           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     629           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     630           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     631             : 
     632             : #ifndef ALL_BUGS_ARE_FATAL
     633             :   /* If we pass the private address check, but don't have the right
     634             :    * OR circuit magic number, we trigger another bug */
     635           1 :   tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
     636           1 :   ec->orport_ipv4.port = VALID_PORT;
     637           1 :   tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
     638           1 :   ec->orport_ipv6.port = VALID_PORT;
     639           1 :   fake_options->ExtendAllowPrivateAddresses = 1;
     640             : 
     641           1 :   tor_capture_bugs_(1);
     642           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     643           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     644           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     645             :             "!(ASSERT_PREDICT_UNLIKELY_(circ->magic != 0x98ABC04Fu))");
     646           1 :   tor_end_capture_bugs_();
     647           1 :   mock_clean_saved_logs();
     648           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     649           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     650           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     651             : 
     652             :   /* Fail again, but this time only set an IPv4 address. */
     653           1 :   tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
     654           1 :   ec->orport_ipv4.port = VALID_PORT;
     655           1 :   fake_options->ExtendAllowPrivateAddresses = 1;
     656           1 :   tor_capture_bugs_(1);
     657           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     658             :   /* Since we're using IF_BUG_ONCE(), expect 0-1 bug logs */
     659           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
     660           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 1);
     661           1 :   tor_end_capture_bugs_();
     662           1 :   mock_clean_saved_logs();
     663           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     664             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
     665             : 
     666             :   /* Now set the right magic */
     667           1 :   or_circ->base_.magic = OR_CIRCUIT_MAGIC;
     668             : 
     669             : #ifndef ALL_BUGS_ARE_FATAL
     670             :   /* If we pass the OR circuit magic check, but don't have p_chan,
     671             :    * we trigger another bug */
     672           1 :   fake_options->ExtendAllowPrivateAddresses = 1;
     673           1 :   tor_capture_bugs_(1);
     674           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     675           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
     676           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
     677             :             "!(ASSERT_PREDICT_UNLIKELY_(!p_chan))");
     678           1 :   tor_end_capture_bugs_();
     679           1 :   mock_clean_saved_logs();
     680           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     681             : 
     682             :   /* We can also pass the OR circuit magic check with a public address */
     683           1 :   tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
     684           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     685           1 :   tor_capture_bugs_(1);
     686           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     687             :   /* Since we're using IF_BUG_ONCE(), expect 0-1 bug logs */
     688           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
     689           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 1);
     690           1 :   tor_end_capture_bugs_();
     691           1 :   mock_clean_saved_logs();
     692           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     693             : 
     694           1 :   tor_addr_make_null(&ec->orport_ipv4.addr, AF_INET);
     695           1 :   ec->orport_ipv4.port = 0x0000;
     696             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
     697             : 
     698             :   /* Now let's fake a p_chan and the addresses */
     699           1 :   tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
     700           1 :   ec->orport_ipv4.port = VALID_PORT;
     701           1 :   or_circ->p_chan = p_chan;
     702             : 
     703             :   /* This is a trivial failure: node_id and p_chan->identity_digest are both
     704             :    * zeroed */
     705           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     706           1 :   expect_log_msg("Client asked me to extend back to the previous hop.\n");
     707           1 :   mock_clean_saved_logs();
     708             : 
     709             :   /* Let's check with non-zero identities as well */
     710           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     711           1 :   memset(p_chan->identity_digest, 0xAA, sizeof(p_chan->identity_digest));
     712             : 
     713           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     714           1 :   expect_log_msg("Client asked me to extend back to the previous hop.\n");
     715           1 :   mock_clean_saved_logs();
     716             : 
     717           1 :   memset(ec->node_id, 0, sizeof(ec->node_id));
     718           1 :   memset(p_chan->identity_digest, 0, sizeof(p_chan->identity_digest));
     719             : 
     720             :   /* Let's pass the node_id test */
     721           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     722           1 :   memset(p_chan->identity_digest, 0xBB, sizeof(p_chan->identity_digest));
     723             : 
     724             :   /* ed_pubkey is zero, and that's allowed, so we should succeed */
     725           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     726           1 :   mock_clean_saved_logs();
     727             : 
     728             :   /* Now let's check that we warn, but succeed, when only one address is
     729             :    * private */
     730           1 :   tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
     731           1 :   ec->orport_ipv4.port = VALID_PORT;
     732           1 :   tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
     733           1 :   ec->orport_ipv6.port = VALID_PORT;
     734           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     735             : 
     736           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     737           1 :   expect_log_msg("Client asked me to extend "
     738           1 :                  "to a private IPv4 address '0.0.0.1'.\n");
     739           1 :   mock_clean_saved_logs();
     740           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     741           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     742             : 
     743             :   /* Now with private IPv6 */
     744           1 :   tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
     745           1 :   ec->orport_ipv4.port = VALID_PORT;
     746           1 :   tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
     747           1 :   ec->orport_ipv6.port = VALID_PORT;
     748           1 :   fake_options->ExtendAllowPrivateAddresses = 0;
     749             : 
     750           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     751           1 :   expect_log_msg("Client asked me to extend "
     752           1 :                  "to a private IPv6 address '[::1]'.\n");
     753           1 :   mock_clean_saved_logs();
     754           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
     755           1 :   tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
     756             : 
     757             :   /* Now reset to public IPv4 and IPv6 */
     758           1 :   tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
     759           1 :   ec->orport_ipv4.port = VALID_PORT;
     760           1 :   tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
     761           1 :   ec->orport_ipv6.port = VALID_PORT;
     762             : 
     763             :   /* Fail on matching non-zero identities */
     764           1 :   memset(&ec->ed_pubkey, 0xEE, sizeof(ec->ed_pubkey));
     765           1 :   memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
     766             : 
     767           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
     768           1 :   expect_log_msg("Client asked me to extend back to the previous hop "
     769           1 :                  "(by Ed25519 ID).\n");
     770           1 :   mock_clean_saved_logs();
     771             : 
     772           1 :   memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
     773           1 :   memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
     774             : 
     775             :   /* Succeed on different, non-zero identities */
     776           1 :   memset(&ec->ed_pubkey, 0xDD, sizeof(ec->ed_pubkey));
     777           1 :   memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
     778             : 
     779           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     780           1 :   mock_clean_saved_logs();
     781             : 
     782           1 :   memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
     783           1 :   memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
     784             : 
     785             :   /* Succeed if the client knows the identity, but we don't */
     786           1 :   memset(&ec->ed_pubkey, 0xDD, sizeof(ec->ed_pubkey));
     787           1 :   memset(&p_chan->ed25519_identity, 0x00, sizeof(p_chan->ed25519_identity));
     788             : 
     789           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     790           1 :   mock_clean_saved_logs();
     791             : 
     792           1 :   memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
     793           1 :   memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
     794             : 
     795             :   /* Succeed if we know the identity, but the client doesn't */
     796           1 :   memset(&ec->ed_pubkey, 0x00, sizeof(ec->ed_pubkey));
     797           1 :   memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
     798             : 
     799           1 :   tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
     800           1 :   mock_clean_saved_logs();
     801             : 
     802           1 :   memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
     803           1 :   memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
     804             : 
     805             :   /* Cleanup the node ids */
     806           1 :   memset(ec->node_id, 0, sizeof(ec->node_id));
     807           1 :   memset(p_chan->identity_digest, 0, sizeof(p_chan->identity_digest));
     808             : 
     809             :   /* Cleanup the p_chan and the addresses */
     810           1 :   tor_addr_make_null(&ec->orport_ipv4.addr, AF_UNSPEC);
     811           1 :   ec->orport_ipv4.port = 0;
     812           1 :   or_circ->p_chan = NULL;
     813             : 
     814           1 :  done:
     815           1 :   tor_end_capture_bugs_();
     816           1 :   teardown_capture_of_logs();
     817             : 
     818           1 :   UNMOCK(get_options);
     819           1 :   or_options_free(fake_options);
     820           1 :   mocked_options = NULL;
     821             : 
     822           1 :   tor_free(ec);
     823           1 :   tor_free(or_circ);
     824           1 :   tor_free(p_chan);
     825           1 : }
     826             : 
     827             : #define NODE_SET_IPV4(node, ipv4_addr_str, ipv4_port) { \
     828             :     tor_addr_parse(&node->ri->ipv4_addr, ipv4_addr_str); \
     829             :     node->ri->ipv4_orport = ipv4_port; \
     830             :   }
     831             : 
     832             : #define NODE_CLEAR_IPV4(node) { \
     833             :     tor_addr_make_unspec(&node->ri->ipv4_addr); \
     834             :     node->ri->ipv4_orport = 0; \
     835             :   }
     836             : 
     837             : #define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \
     838             :     tor_addr_parse(&node->ri->ipv6_addr, ipv6_addr_str); \
     839             :     node->ri->ipv6_orport = ipv6_port; \
     840             :   }
     841             : 
     842             : /* Test the different cases in circuit_extend_add_ed25519_helper(). */
     843             : static void
     844           1 : test_circuit_extend_add_ip(void *arg)
     845             : {
     846           1 :   (void) arg;
     847           1 :   tor_addr_t ipv4_tmp;
     848           1 :   extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
     849           1 :   extend_cell_t *old_ec = tor_malloc_zero(sizeof(extend_cell_t));
     850             : 
     851           1 :   node_t *fake_node = tor_malloc_zero(sizeof(node_t));
     852           1 :   routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
     853             : 
     854           1 :   MOCK(node_get_by_id, mock_node_get_by_id);
     855             : 
     856             :   /* Set up the fake variables for the IPv4 test */
     857           1 :   fake_node->ri = ri;
     858           1 :   mocked_node = fake_node;
     859           1 :   memset(ec->node_id, 0xAA, sizeof(ec->node_id));
     860           1 :   memcpy(old_ec, ec, sizeof(extend_cell_t));
     861           1 :   NODE_SET_IPV4(fake_node, PUBLIC_IPV4, VALID_PORT);
     862             : 
     863             :   /* Do the IPv4 test */
     864           1 :   tt_int_op(circuit_extend_add_ipv4_helper(ec), OP_EQ, 0);
     865           1 :   tor_addr_copy(&ipv4_tmp, &fake_node->ri->ipv4_addr);
     866             :   /* The IPv4 should match */
     867           1 :   tt_int_op(tor_addr_compare(&ec->orport_ipv4.addr, &ipv4_tmp, CMP_SEMANTIC),
     868             :             OP_EQ, 0);
     869           1 :   tt_int_op(ec->orport_ipv4.port, OP_EQ, VALID_PORT);
     870             : 
     871             :   /* Set up the fake variables for the IPv6 test */
     872           1 :   memcpy(ec, old_ec, sizeof(extend_cell_t));
     873           1 :   NODE_CLEAR_IPV4(fake_node);
     874           1 :   NODE_SET_IPV6(fake_node, PUBLIC_IPV6, VALID_PORT);
     875             : 
     876             :   /* Do the IPv6 test */
     877           1 :   tt_int_op(circuit_extend_add_ipv6_helper(ec), OP_EQ, 0);
     878             :   /* The IPv6 should match */
     879           1 :   tt_int_op(tor_addr_compare(&ec->orport_ipv6.addr, &fake_node->ri->ipv6_addr,
     880             :             CMP_SEMANTIC), OP_EQ, 0);
     881           1 :   tt_int_op(ec->orport_ipv6.port, OP_EQ, VALID_PORT);
     882             : 
     883             :   /* Cleanup */
     884           1 :   mocked_node = NULL;
     885             : 
     886           1 :  done:
     887           1 :   UNMOCK(node_get_by_id);
     888             : 
     889           1 :   tor_free(ec);
     890           1 :   tor_free(old_ec);
     891             : 
     892           1 :   tor_free(ri);
     893           1 :   tor_free(fake_node);
     894           1 : }
     895             : 
     896             : static bool can_extend_over_ipv6_result = false;
     897             : static int mock_router_can_extend_over_ipv6_calls = 0;
     898             : static bool
     899          17 : mock_router_can_extend_over_ipv6(const or_options_t *options)
     900             : {
     901          17 :   (void)options;
     902          17 :   mock_router_can_extend_over_ipv6_calls++;
     903          17 :   return can_extend_over_ipv6_result;
     904             : }
     905             : 
     906             : /* Test the different cases in circuit_choose_ip_ap_for_extend(). */
     907             : static void
     908           1 : test_circuit_choose_ip_ap_for_extend(void *arg)
     909             : {
     910           1 :   (void)arg;
     911           1 :   tor_addr_port_t ipv4_ap;
     912           1 :   tor_addr_port_t ipv6_ap;
     913             : 
     914             :   /* Set up valid addresses */
     915           1 :   tor_addr_parse(&ipv4_ap.addr, PUBLIC_IPV4);
     916           1 :   ipv4_ap.port = VALID_PORT;
     917           1 :   tor_addr_parse(&ipv6_ap.addr, PUBLIC_IPV6);
     918           1 :   ipv6_ap.port = VALID_PORT;
     919             : 
     920           1 :   or_options_t *fake_options = options_new();
     921           1 :   MOCK(get_options, mock_get_options);
     922           1 :   mocked_options = fake_options;
     923             : 
     924           1 :   MOCK(router_can_extend_over_ipv6,
     925             :        mock_router_can_extend_over_ipv6);
     926           1 :   can_extend_over_ipv6_result = true;
     927           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     928             : 
     929             :   /* No valid addresses */
     930           1 :   can_extend_over_ipv6_result = true;
     931           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     932           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
     933           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     934             : 
     935           1 :   can_extend_over_ipv6_result = false;
     936           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     937           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
     938           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     939             : 
     940             :   /* One valid address: IPv4 */
     941           1 :   can_extend_over_ipv6_result = true;
     942           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     943           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
     944           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     945             : 
     946           1 :   can_extend_over_ipv6_result = false;
     947           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     948           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
     949           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     950             : 
     951             :   /* One valid address: IPv6 */
     952           1 :   can_extend_over_ipv6_result = true;
     953           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     954           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, &ipv6_ap);
     955           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     956             : 
     957           1 :   can_extend_over_ipv6_result = false;
     958           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     959           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, NULL);
     960           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     961             : 
     962             :   /* Two valid addresses */
     963           1 :   const tor_addr_port_t *chosen_addr = NULL;
     964             : 
     965           1 :   can_extend_over_ipv6_result = true;
     966           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     967           1 :   chosen_addr = circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap);
     968           1 :   tt_assert(chosen_addr == &ipv4_ap || chosen_addr == &ipv6_ap);
     969           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     970             : 
     971           1 :   can_extend_over_ipv6_result = false;
     972           1 :   mock_router_can_extend_over_ipv6_calls = 0;
     973           1 :   tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap),
     974             :             OP_EQ, &ipv4_ap);
     975           1 :   tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
     976             : 
     977           1 :  done:
     978           1 :   UNMOCK(get_options);
     979           1 :   or_options_free(fake_options);
     980           1 :   mocked_options = NULL;
     981             : 
     982           1 :   UNMOCK(router_can_extend_over_ipv6);
     983             : 
     984           1 :   tor_free(fake_options);
     985           1 : }
     986             : 
     987             : static int mock_circuit_close_calls = 0;
     988             : static void
     989           9 : mock_circuit_mark_for_close_(circuit_t *circ, int reason,
     990             :                              int line, const char *cfile)
     991             : {
     992           9 :   (void)circ;
     993           9 :   (void)reason;
     994           9 :   (void)line;
     995           9 :   (void)cfile;
     996           9 :   mock_circuit_close_calls++;
     997           9 : }
     998             : 
     999             : static int mock_channel_connect_calls = 0;
    1000             : static channel_t *mock_channel_connect_nchan = NULL;
    1001             : static channel_t *
    1002           7 : mock_channel_connect_for_circuit(const extend_info_t *ei)
    1003             : {
    1004           7 :   (void)ei;
    1005           7 :   mock_channel_connect_calls++;
    1006           7 :   return mock_channel_connect_nchan;
    1007             : }
    1008             : 
    1009             : /* Test the different cases in circuit_open_connection_for_extend().
    1010             :  * Chooses different IP addresses depending on the first character in arg:
    1011             :  *  - 4: IPv4
    1012             :  *  - 6: IPv6
    1013             :  *  - d: IPv4 and IPv6 (dual-stack)
    1014             :  */
    1015             : static void
    1016           3 : test_circuit_open_connection_for_extend(void *arg)
    1017             : {
    1018           3 :   const char ip_version = ((const char *)arg)[0];
    1019           3 :   const bool use_ipv4 = (ip_version == '4' || ip_version == 'd');
    1020           3 :   const bool use_ipv6 = (ip_version == '6' || ip_version == 'd');
    1021           3 :   tor_assert(use_ipv4 || use_ipv6);
    1022             : 
    1023           3 :   extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
    1024           3 :   circuit_t *circ = tor_malloc_zero(sizeof(circuit_t));
    1025           3 :   channel_t *fake_n_chan = tor_malloc_zero(sizeof(channel_t));
    1026             : 
    1027           3 :   or_options_t *fake_options = options_new();
    1028           3 :   MOCK(get_options, mock_get_options);
    1029           3 :   mocked_options = fake_options;
    1030             : 
    1031           3 :   MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close_);
    1032           3 :   mock_circuit_close_calls = 0;
    1033           3 :   MOCK(channel_connect_for_circuit, mock_channel_connect_for_circuit);
    1034           3 :   mock_channel_connect_calls = 0;
    1035           3 :   mock_channel_connect_nchan = NULL;
    1036             : 
    1037           3 :   MOCK(router_can_extend_over_ipv6,
    1038             :        mock_router_can_extend_over_ipv6);
    1039           3 :   can_extend_over_ipv6_result = true;
    1040             : 
    1041           3 :   setup_full_capture_of_logs(LOG_INFO);
    1042             : 
    1043             : #ifndef ALL_BUGS_ARE_FATAL
    1044             :   /* Circuit must be non-NULL */
    1045           3 :   mock_circuit_close_calls = 0;
    1046           3 :   mock_channel_connect_calls = 0;
    1047           3 :   tor_capture_bugs_(1);
    1048           3 :   circuit_open_connection_for_extend(ec, NULL, 0);
    1049             :   /* We can't close a NULL circuit */
    1050           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
    1051           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1052           3 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1053           3 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1054             :             "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
    1055           3 :   tor_end_capture_bugs_();
    1056           3 :   mock_clean_saved_logs();
    1057             : 
    1058             :   /* Extend cell must be non-NULL */
    1059           3 :   mock_circuit_close_calls = 0;
    1060           3 :   mock_channel_connect_calls = 0;
    1061           3 :   tor_capture_bugs_(1);
    1062           3 :   circuit_open_connection_for_extend(NULL, circ, 0);
    1063           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
    1064           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1065           3 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1066           3 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1067             :             "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
    1068           3 :   tor_end_capture_bugs_();
    1069           3 :   mock_clean_saved_logs();
    1070             : 
    1071             :   /* Extend cell and circuit must be non-NULL */
    1072           3 :   mock_circuit_close_calls = 0;
    1073           3 :   mock_channel_connect_calls = 0;
    1074           3 :   tor_capture_bugs_(1);
    1075           3 :   circuit_open_connection_for_extend(NULL, NULL, 0);
    1076             :   /* We can't close a NULL circuit */
    1077           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
    1078           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1079             :   /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
    1080           3 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
    1081           3 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
    1082           3 :   tor_end_capture_bugs_();
    1083           3 :   mock_clean_saved_logs();
    1084             : 
    1085             :   /* Fail, because neither address is valid */
    1086           3 :   mock_circuit_close_calls = 0;
    1087           3 :   mock_channel_connect_calls = 0;
    1088           3 :   tor_capture_bugs_(1);
    1089           3 :   circuit_open_connection_for_extend(ec, circ, 0);
    1090             :   /* Close the circuit, don't connect */
    1091           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
    1092           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1093             :   /* Check state */
    1094           3 :   tt_ptr_op(circ->n_hop, OP_EQ, NULL);
    1095           3 :   tt_ptr_op(circ->n_chan_create_cell, OP_EQ, NULL);
    1096           3 :   tt_int_op(circ->state, OP_EQ, 0);
    1097             :   /* Cleanup */
    1098           3 :   tor_end_capture_bugs_();
    1099           3 :   mock_clean_saved_logs();
    1100             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    1101             : 
    1102             :   /* Set up valid addresses */
    1103           3 :   if (use_ipv4) {
    1104           2 :     tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
    1105           2 :     ec->orport_ipv4.port = VALID_PORT;
    1106             :   }
    1107           3 :   if (use_ipv6) {
    1108           2 :     tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
    1109           2 :     ec->orport_ipv6.port = VALID_PORT;
    1110             :   }
    1111             : 
    1112             :   /* Succeed, but don't try to open a connection */
    1113           3 :   mock_circuit_close_calls = 0;
    1114           3 :   mock_channel_connect_calls = 0;
    1115           3 :   circuit_open_connection_for_extend(ec, circ, 0);
    1116             :   /* If we haven't closed the circuit, that's success */
    1117           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
    1118           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1119             :   /* Check state */
    1120           3 :   tt_ptr_op(circ->n_hop, OP_NE, NULL);
    1121           3 :   tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
    1122           3 :   tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
    1123             :   /* Cleanup */
    1124           3 :   mock_clean_saved_logs();
    1125           3 :   tor_free(circ->n_hop);
    1126           3 :   tor_free(circ->n_chan_create_cell);
    1127           3 :   circ->state = 0;
    1128             : 
    1129             :   /* Try to open a connection, but fail with a NULL n_chan */
    1130           3 :   mock_circuit_close_calls = 0;
    1131           3 :   mock_channel_connect_calls = 0;
    1132           3 :   circuit_open_connection_for_extend(ec, circ, 1);
    1133             :   /* Try to connect, but fail, and close the circuit */
    1134           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
    1135           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
    1136           3 :   expect_log_msg("Launching n_chan failed. Closing circuit.\n");
    1137             :   /* Check state */
    1138           3 :   tt_ptr_op(circ->n_hop, OP_NE, NULL);
    1139           3 :   tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
    1140           3 :   tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
    1141             :   /* Cleanup */
    1142           3 :   mock_clean_saved_logs();
    1143           3 :   tor_free(circ->n_hop);
    1144           3 :   tor_free(circ->n_chan_create_cell);
    1145           3 :   circ->state = 0;
    1146             : 
    1147             :   /* Try to open a connection, and succeed, because n_chan is not NULL */
    1148           3 :   mock_channel_connect_nchan = fake_n_chan;
    1149           3 :   mock_circuit_close_calls = 0;
    1150           3 :   mock_channel_connect_calls = 0;
    1151           3 :   circuit_open_connection_for_extend(ec, circ, 1);
    1152             :   /* Connection attempt succeeded, leaving the circuit open */
    1153           3 :   tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
    1154           3 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
    1155             :   /* Check state */
    1156           3 :   tt_ptr_op(circ->n_hop, OP_NE, NULL);
    1157           3 :   tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
    1158           3 :   tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
    1159             :   /* Cleanup */
    1160           3 :   mock_clean_saved_logs();
    1161           3 :   tor_free(circ->n_hop);
    1162           3 :   tor_free(circ->n_chan_create_cell);
    1163           3 :   circ->state = 0;
    1164           3 :   mock_channel_connect_nchan = NULL;
    1165             : 
    1166           3 :  done:
    1167           3 :   tor_end_capture_bugs_();
    1168           3 :   teardown_capture_of_logs();
    1169             : 
    1170           3 :   UNMOCK(circuit_mark_for_close_);
    1171           3 :   mock_circuit_close_calls = 0;
    1172           3 :   UNMOCK(channel_connect_for_circuit);
    1173           3 :   mock_channel_connect_calls = 0;
    1174             : 
    1175           3 :   UNMOCK(get_options);
    1176           3 :   or_options_free(fake_options);
    1177           3 :   mocked_options = NULL;
    1178             : 
    1179           3 :   UNMOCK(router_can_extend_over_ipv6);
    1180             : 
    1181           3 :   tor_free(ec);
    1182           3 :   tor_free(circ->n_hop);
    1183           3 :   tor_free(circ->n_chan_create_cell);
    1184           3 :   tor_free(circ);
    1185           3 :   tor_free(fake_n_chan);
    1186           3 : }
    1187             : 
    1188             : /* Guaranteed to be initialised to zero. */
    1189             : static extend_cell_t mock_extend_cell_parse_cell_out;
    1190             : static int mock_extend_cell_parse_result = 0;
    1191             : static int mock_extend_cell_parse_calls = 0;
    1192             : 
    1193             : static int
    1194           7 : mock_extend_cell_parse(extend_cell_t *cell_out,
    1195             :                        const uint8_t command,
    1196             :                        const uint8_t *payload_in,
    1197             :                        size_t payload_len)
    1198             : {
    1199           7 :   (void)command;
    1200           7 :   (void)payload_in;
    1201           7 :   (void)payload_len;
    1202             : 
    1203           7 :   mock_extend_cell_parse_calls++;
    1204           7 :   memcpy(cell_out, &mock_extend_cell_parse_cell_out,
    1205             :          sizeof(extend_cell_t));
    1206           7 :   return mock_extend_cell_parse_result;
    1207             : }
    1208             : 
    1209             : static int mock_channel_get_for_extend_calls = 0;
    1210             : static int mock_channel_get_for_extend_launch_out = 0;
    1211             : static channel_t *mock_channel_get_for_extend_nchan = NULL;
    1212             : static channel_t *
    1213           4 : mock_channel_get_for_extend(const char *rsa_id_digest,
    1214             :                             const ed25519_public_key_t *ed_id,
    1215             :                             const tor_addr_t *target_ipv4_addr,
    1216             :                             const tor_addr_t *target_ipv6_addr,
    1217             :                             bool for_origin_circ,
    1218             :                             const char **msg_out,
    1219             :                             int *launch_out)
    1220             : {
    1221           4 :   (void)rsa_id_digest;
    1222           4 :   (void)ed_id;
    1223           4 :   (void)target_ipv4_addr;
    1224           4 :   (void)target_ipv6_addr;
    1225           4 :   (void)for_origin_circ;
    1226             : 
    1227             :   /* channel_get_for_extend() requires non-NULL arguments */
    1228           4 :   tt_ptr_op(msg_out, OP_NE, NULL);
    1229           4 :   tt_ptr_op(launch_out, OP_NE, NULL);
    1230             : 
    1231           4 :   mock_channel_get_for_extend_calls++;
    1232           4 :   *msg_out = NULL;
    1233           4 :   *launch_out = mock_channel_get_for_extend_launch_out;
    1234           4 :   return mock_channel_get_for_extend_nchan;
    1235             : 
    1236             :  done:
    1237             :   return NULL;
    1238             : }
    1239             : 
    1240             : static const char *
    1241           2 : mock_channel_get_canonical_remote_descr(channel_t *chan)
    1242             : {
    1243           2 :   (void)chan;
    1244           2 :   return "mock_channel_get_canonical_remote_descr()";
    1245             : }
    1246             : 
    1247             : /* Should mock_circuit_deliver_create_cell() expect a direct connection? */
    1248             : static bool mock_circuit_deliver_create_cell_expect_direct = false;
    1249             : static int mock_circuit_deliver_create_cell_calls = 0;
    1250             : static int mock_circuit_deliver_create_cell_result = 0;
    1251             : static int
    1252           4 : mock_circuit_deliver_create_cell(circuit_t *circ,
    1253             :                                  const struct create_cell_t *create_cell,
    1254             :                                  int relayed)
    1255             : {
    1256           4 :   (void)create_cell;
    1257             : 
    1258             :   /* circuit_deliver_create_cell() requires non-NULL arguments,
    1259             :    * but we only check circ and circ->n_chan here. */
    1260           4 :   tt_ptr_op(circ, OP_NE, NULL);
    1261             :   /* We expect n_chan for relayed cells. But should we also expect it for
    1262             :    * direct connections? */
    1263           4 :   if (!mock_circuit_deliver_create_cell_expect_direct)
    1264           2 :     tt_ptr_op(circ->n_chan, OP_NE, NULL);
    1265             : 
    1266             :   /* We should only ever get relayed cells from extends */
    1267           4 :   tt_int_op(relayed, OP_EQ, !mock_circuit_deliver_create_cell_expect_direct);
    1268             : 
    1269           4 :   mock_circuit_deliver_create_cell_calls++;
    1270           4 :   return mock_circuit_deliver_create_cell_result;
    1271             : 
    1272             :  done:
    1273             :   return -1;
    1274             : }
    1275             : 
    1276             : /* Test the different cases in circuit_extend(). */
    1277             : static void
    1278           1 : test_circuit_extend(void *arg)
    1279             : {
    1280           1 :   (void)arg;
    1281           1 :   cell_t *cell = tor_malloc_zero(sizeof(cell_t));
    1282           1 :   channel_t *p_chan = tor_malloc_zero(sizeof(channel_t));
    1283           1 :   or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
    1284           1 :   circuit_t *circ = TO_CIRCUIT(or_circ);
    1285           1 :   channel_t *fake_n_chan = tor_malloc_zero(sizeof(channel_t));
    1286             : 
    1287           1 :   server = 0;
    1288           1 :   MOCK(server_mode, mock_server_mode);
    1289             : 
    1290             :   /* Mock a debug function, but otherwise ignore it */
    1291           1 :   MOCK(channel_describe_peer,
    1292             :        mock_channel_get_canonical_remote_descr);
    1293             : 
    1294           1 :   setup_full_capture_of_logs(LOG_INFO);
    1295             : 
    1296             : #ifndef ALL_BUGS_ARE_FATAL
    1297             :   /* Circuit must be non-NULL */
    1298           1 :   tor_capture_bugs_(1);
    1299           1 :   tt_int_op(circuit_extend(cell, NULL), OP_EQ, -1);
    1300           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1301           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1302             :             "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
    1303           1 :   tor_end_capture_bugs_();
    1304           1 :   mock_clean_saved_logs();
    1305             : 
    1306             :   /* Cell must be non-NULL */
    1307           1 :   tor_capture_bugs_(1);
    1308           1 :   tt_int_op(circuit_extend(NULL, circ), OP_EQ, -1);
    1309           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1310           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1311             :             "!(ASSERT_PREDICT_UNLIKELY_(!cell))");
    1312           1 :   tor_end_capture_bugs_();
    1313           1 :   mock_clean_saved_logs();
    1314             : 
    1315             :   /* Extend cell and circuit must be non-NULL */
    1316           1 :   tor_capture_bugs_(1);
    1317           1 :   tt_int_op(circuit_extend(NULL, NULL), OP_EQ, -1);
    1318             :   /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
    1319           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
    1320           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
    1321           1 :   tor_end_capture_bugs_();
    1322           1 :   mock_clean_saved_logs();
    1323             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    1324             : 
    1325             :   /* Clients can't extend */
    1326           1 :   server = 0;
    1327           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1328           1 :   expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
    1329           1 :   mock_clean_saved_logs();
    1330             : 
    1331             :   /* But servers can. Unpack the cell, but fail parsing. */
    1332           1 :   server = 1;
    1333           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1334           1 :   expect_log_msg("Can't parse extend cell. Closing circuit.\n");
    1335           1 :   mock_clean_saved_logs();
    1336             : 
    1337             :   /* Now mock parsing */
    1338           1 :   MOCK(extend_cell_parse, mock_extend_cell_parse);
    1339             : 
    1340             :   /* And make parsing succeed, but fail on adding ed25519 */
    1341           1 :   memset(&mock_extend_cell_parse_cell_out, 0,
    1342             :              sizeof(mock_extend_cell_parse_cell_out));
    1343           1 :   mock_extend_cell_parse_result = 0;
    1344           1 :   mock_extend_cell_parse_calls = 0;
    1345             : 
    1346           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1347           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1348           1 :   expect_log_msg(
    1349           1 :     "Client asked me to extend without specifying an id_digest.\n");
    1350           1 :   mock_clean_saved_logs();
    1351           1 :   mock_extend_cell_parse_calls = 0;
    1352             : 
    1353             :   /* Now add a node_id. Fail the lspec check because IPv4 and port are zero. */
    1354           1 :   memset(&mock_extend_cell_parse_cell_out.node_id, 0xAA,
    1355             :              sizeof(mock_extend_cell_parse_cell_out.node_id));
    1356             : 
    1357           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1358           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1359           1 :   expect_log_msg("Client asked me to extend to a zero destination port "
    1360           1 :                  "or unspecified address '[scrubbed]'.\n");
    1361           1 :   mock_clean_saved_logs();
    1362           1 :   mock_extend_cell_parse_calls = 0;
    1363             : 
    1364             :   /* Now add a valid IPv4 and port. Fail the OR circuit magic check. */
    1365           1 :   tor_addr_parse(&mock_extend_cell_parse_cell_out.orport_ipv4.addr,
    1366             :                  PUBLIC_IPV4);
    1367           1 :   mock_extend_cell_parse_cell_out.orport_ipv4.port = VALID_PORT;
    1368             : 
    1369             : #ifndef ALL_BUGS_ARE_FATAL
    1370           1 :   tor_capture_bugs_(1);
    1371           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1372           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1373           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1374           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1375             :             "!(ASSERT_PREDICT_UNLIKELY_(circ->magic != 0x98ABC04Fu))");
    1376           1 :   tor_end_capture_bugs_();
    1377           1 :   mock_clean_saved_logs();
    1378           1 :   mock_extend_cell_parse_calls = 0;
    1379             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    1380             : 
    1381             :   /* Now add the right magic and a p_chan. */
    1382           1 :   or_circ->base_.magic = OR_CIRCUIT_MAGIC;
    1383           1 :   or_circ->p_chan = p_chan;
    1384             : 
    1385             :   /* Mock channel_get_for_extend(), so it doesn't crash. */
    1386           1 :   mock_channel_get_for_extend_calls = 0;
    1387           1 :   MOCK(channel_get_for_extend, mock_channel_get_for_extend);
    1388             : 
    1389             :   /* Test circuit not established, but don't launch another one */
    1390           1 :   mock_channel_get_for_extend_launch_out = 0;
    1391           1 :   mock_channel_get_for_extend_nchan = NULL;
    1392           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
    1393           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1394           1 :   tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
    1395             : 
    1396             :   /* cleanup */
    1397           1 :   mock_clean_saved_logs();
    1398           1 :   mock_extend_cell_parse_calls = 0;
    1399           1 :   mock_channel_get_for_extend_calls = 0;
    1400             :   /* circ and or_circ are the same object */
    1401           1 :   tor_free(circ->n_hop);
    1402           1 :   tor_free(circ->n_chan_create_cell);
    1403             : 
    1404             :   /* Mock channel_connect_for_circuit(), so we don't crash */
    1405           1 :   mock_channel_connect_calls = 0;
    1406           1 :   MOCK(channel_connect_for_circuit, mock_channel_connect_for_circuit);
    1407             : 
    1408             :   /* Test circuit not established, and successful launch of a channel */
    1409           1 :   mock_channel_get_for_extend_launch_out = 1;
    1410           1 :   mock_channel_get_for_extend_nchan = NULL;
    1411           1 :   mock_channel_connect_nchan = fake_n_chan;
    1412           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
    1413           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1414           1 :   tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
    1415           1 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
    1416             : 
    1417             :   /* cleanup */
    1418           1 :   mock_clean_saved_logs();
    1419           1 :   mock_extend_cell_parse_calls = 0;
    1420           1 :   mock_channel_get_for_extend_calls = 0;
    1421           1 :   mock_channel_connect_calls = 0;
    1422             :   /* circ and or_circ are the same object */
    1423           1 :   tor_free(circ->n_hop);
    1424           1 :   tor_free(circ->n_chan_create_cell);
    1425             : 
    1426             :   /* Mock circuit_deliver_create_cell(), so it doesn't crash */
    1427           1 :   mock_circuit_deliver_create_cell_calls = 0;
    1428           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1429           1 :   MOCK(circuit_deliver_create_cell, mock_circuit_deliver_create_cell);
    1430             : 
    1431             :   /* Test circuit established, re-using channel, successful delivery */
    1432           1 :   mock_channel_get_for_extend_launch_out = 0;
    1433           1 :   mock_channel_get_for_extend_nchan = fake_n_chan;
    1434           1 :   mock_channel_connect_nchan = NULL;
    1435           1 :   mock_circuit_deliver_create_cell_result = 0;
    1436           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
    1437           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1438           1 :   tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
    1439           1 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1440           1 :   tt_int_op(mock_circuit_deliver_create_cell_calls, OP_EQ, 1);
    1441           1 :   tt_ptr_op(circ->n_chan, OP_EQ, fake_n_chan);
    1442             : 
    1443             :   /* cleanup */
    1444           1 :   circ->n_chan = NULL;
    1445           1 :   mock_clean_saved_logs();
    1446           1 :   mock_extend_cell_parse_calls = 0;
    1447           1 :   mock_channel_get_for_extend_calls = 0;
    1448           1 :   mock_channel_connect_calls = 0;
    1449           1 :   mock_circuit_deliver_create_cell_calls = 0;
    1450             :   /* circ and or_circ are the same object */
    1451           1 :   tor_free(circ->n_hop);
    1452           1 :   tor_free(circ->n_chan_create_cell);
    1453             : 
    1454             :   /* Test circuit established, re-using channel, failed delivery */
    1455           1 :   mock_channel_get_for_extend_launch_out = 0;
    1456           1 :   mock_channel_get_for_extend_nchan = fake_n_chan;
    1457           1 :   mock_channel_connect_nchan = NULL;
    1458           1 :   mock_circuit_deliver_create_cell_result = -1;
    1459           1 :   tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
    1460           1 :   tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
    1461           1 :   tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
    1462           1 :   tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
    1463           1 :   tt_int_op(mock_circuit_deliver_create_cell_calls, OP_EQ, 1);
    1464           1 :   tt_ptr_op(circ->n_chan, OP_EQ, fake_n_chan);
    1465             : 
    1466             :   /* cleanup */
    1467           1 :   circ->n_chan = NULL;
    1468           1 :   mock_clean_saved_logs();
    1469           1 :   mock_extend_cell_parse_calls = 0;
    1470           1 :   mock_channel_get_for_extend_calls = 0;
    1471           1 :   mock_channel_connect_calls = 0;
    1472           1 :   mock_circuit_deliver_create_cell_calls = 0;
    1473             :   /* circ and or_circ are the same object */
    1474           1 :   tor_free(circ->n_hop);
    1475           1 :   tor_free(circ->n_chan_create_cell);
    1476             : 
    1477           1 :  done:
    1478           1 :   tor_end_capture_bugs_();
    1479           1 :   teardown_capture_of_logs();
    1480             : 
    1481           1 :   UNMOCK(server_mode);
    1482           1 :   server = 0;
    1483             : 
    1484           1 :   UNMOCK(channel_describe_peer);
    1485             : 
    1486           1 :   UNMOCK(extend_cell_parse);
    1487           1 :   memset(&mock_extend_cell_parse_cell_out, 0,
    1488             :          sizeof(mock_extend_cell_parse_cell_out));
    1489           1 :   mock_extend_cell_parse_result = 0;
    1490           1 :   mock_extend_cell_parse_calls = 0;
    1491             : 
    1492           1 :   UNMOCK(channel_get_for_extend);
    1493           1 :   mock_channel_get_for_extend_calls = 0;
    1494           1 :   mock_channel_get_for_extend_launch_out = 0;
    1495           1 :   mock_channel_get_for_extend_nchan = NULL;
    1496             : 
    1497           1 :   UNMOCK(channel_connect_for_circuit);
    1498           1 :   mock_channel_connect_calls = 0;
    1499           1 :   mock_channel_connect_nchan = NULL;
    1500             : 
    1501           1 :   UNMOCK(circuit_deliver_create_cell);
    1502           1 :   mock_circuit_deliver_create_cell_calls = 0;
    1503           1 :   mock_circuit_deliver_create_cell_result = 0;
    1504             : 
    1505           1 :   tor_free(cell);
    1506             :   /* circ and or_circ are the same object */
    1507           1 :   tor_free(circ->n_hop);
    1508           1 :   tor_free(circ->n_chan_create_cell);
    1509           1 :   tor_free(or_circ);
    1510           1 :   tor_free(p_chan);
    1511           1 :   tor_free(fake_n_chan);
    1512           1 : }
    1513             : 
    1514             : /* Test the different cases in onionskin_answer(). */
    1515             : static void
    1516           1 : test_onionskin_answer(void *arg)
    1517             : {
    1518           1 :   (void)arg;
    1519           1 :   created_cell_t *created_cell = tor_malloc_zero(sizeof(created_cell_t));
    1520           1 :   or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
    1521           1 :   char keys[CPATH_KEY_MATERIAL_LEN] = {0};
    1522           1 :   uint8_t rend_circ_nonce[DIGEST_LEN] = {0};
    1523             : 
    1524           1 :   setup_full_capture_of_logs(LOG_INFO);
    1525             : 
    1526             : #ifndef ALL_BUGS_ARE_FATAL
    1527             :   /* Circuit must be non-NULL */
    1528           1 :   tor_capture_bugs_(1);
    1529           1 :   tt_int_op(onionskin_answer(NULL, created_cell,
    1530             :                              keys, CPATH_KEY_MATERIAL_LEN,
    1531             :                              rend_circ_nonce), OP_EQ, -1);
    1532           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1533           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1534             :             "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
    1535           1 :   tor_end_capture_bugs_();
    1536           1 :   mock_clean_saved_logs();
    1537             : 
    1538             :   /* Created cell must be non-NULL */
    1539           1 :   tor_capture_bugs_(1);
    1540           1 :   tt_int_op(onionskin_answer(or_circ, NULL,
    1541             :                              keys, CPATH_KEY_MATERIAL_LEN,
    1542             :                              rend_circ_nonce), OP_EQ, -1);
    1543           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1544           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1545             :             "!(ASSERT_PREDICT_UNLIKELY_(!created_cell))");
    1546           1 :   tor_end_capture_bugs_();
    1547           1 :   mock_clean_saved_logs();
    1548             : 
    1549             :   /* Keys must be non-NULL */
    1550           1 :   tor_capture_bugs_(1);
    1551           1 :   tt_int_op(onionskin_answer(or_circ, created_cell,
    1552             :                              NULL, CPATH_KEY_MATERIAL_LEN,
    1553             :                              rend_circ_nonce), OP_EQ, -1);
    1554           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1555           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1556             :             "!(ASSERT_PREDICT_UNLIKELY_(!keys))");
    1557           1 :   tor_end_capture_bugs_();
    1558           1 :   mock_clean_saved_logs();
    1559             : 
    1560             :   /* The rend circuit nonce must be non-NULL */
    1561           1 :   tor_capture_bugs_(1);
    1562           1 :   tt_int_op(onionskin_answer(or_circ, created_cell,
    1563             :                              keys, CPATH_KEY_MATERIAL_LEN,
    1564             :                              NULL), OP_EQ, -1);
    1565           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1566           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1567             :             "!(ASSERT_PREDICT_UNLIKELY_(!rend_circ_nonce))");
    1568           1 :   tor_end_capture_bugs_();
    1569           1 :   mock_clean_saved_logs();
    1570             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    1571             : 
    1572             :   /* Also, the keys length must be CPATH_KEY_MATERIAL_LEN, but we can't catch
    1573             :    * asserts in unit tests. */
    1574             : 
    1575             :   /* Fail when formatting the created cell */
    1576           1 :   tt_int_op(onionskin_answer(or_circ, created_cell,
    1577             :                              keys, CPATH_KEY_MATERIAL_LEN,
    1578             :                              rend_circ_nonce), OP_EQ, -1);
    1579           1 :   expect_log_msg("couldn't format created cell (type=0, len=0).\n");
    1580           1 :   mock_clean_saved_logs();
    1581             : 
    1582             :   /* TODO: test the rest of onionskin_answer(), see #33860 */
    1583             :   /* TODO: mock created_cell_format for the next test  */
    1584             : 
    1585           1 :  done:
    1586           1 :   tor_end_capture_bugs_();
    1587           1 :   teardown_capture_of_logs();
    1588             : 
    1589           1 :   tor_free(created_cell);
    1590           1 :   tor_free(or_circ);
    1591           1 : }
    1592             : 
    1593             : /* Test the different cases in origin_circuit_init(). */
    1594             : static void
    1595           1 : test_origin_circuit_init(void *arg)
    1596             : {
    1597           1 :   (void)arg;
    1598           1 :   origin_circuit_t *origin_circ = NULL;
    1599             : 
    1600             :   /* Init with 0 purpose and 0 flags */
    1601           1 :   origin_circ = origin_circuit_init(0, 0);
    1602           1 :   tt_int_op(origin_circ->base_.purpose, OP_EQ, 0);
    1603           1 :   tt_int_op(origin_circ->base_.state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
    1604           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1605           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
    1606           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
    1607           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
    1608           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
    1609           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
    1610             :   /* The circuits are automatically freed by the circuitlist. */
    1611             : 
    1612             :   /* Init with a purpose */
    1613           1 :   origin_circ = origin_circuit_init(CIRCUIT_PURPOSE_C_GENERAL, 0);
    1614           1 :   tt_int_op(origin_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL);
    1615             : 
    1616             :   /* Init with each flag */
    1617           1 :   origin_circ = origin_circuit_init(0, CIRCLAUNCH_IS_INTERNAL);
    1618           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1619           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 1);
    1620           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
    1621           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
    1622           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
    1623           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
    1624             : 
    1625           1 :   origin_circ = origin_circuit_init(0, CIRCLAUNCH_IS_IPV6_SELFTEST);
    1626           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1627           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
    1628           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 1);
    1629           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
    1630           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
    1631           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
    1632             : 
    1633           1 :   origin_circ = origin_circuit_init(0, CIRCLAUNCH_NEED_CAPACITY);
    1634           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1635           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
    1636           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
    1637           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 1);
    1638           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
    1639           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
    1640             : 
    1641           1 :   origin_circ = origin_circuit_init(0, CIRCLAUNCH_NEED_UPTIME);
    1642           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1643           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
    1644           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
    1645           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
    1646           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 1);
    1647           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
    1648             : 
    1649           1 :   origin_circ = origin_circuit_init(0, CIRCLAUNCH_ONEHOP_TUNNEL);
    1650           1 :   tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
    1651           1 :   tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
    1652           1 :   tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
    1653           1 :   tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
    1654           1 :   tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
    1655           1 :   tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 1);
    1656             : 
    1657           1 :  done:
    1658             :   /* The circuits are automatically freed by the circuitlist. */
    1659           1 :   ;
    1660           1 : }
    1661             : 
    1662             : /* Test the different cases in circuit_send_next_onion_skin(). */
    1663             : static void
    1664           1 : test_circuit_send_next_onion_skin(void *arg)
    1665             : {
    1666           1 :   (void)arg;
    1667           1 :   origin_circuit_t *origin_circ = NULL;
    1668           1 :   struct timeval circ_start_time;
    1669           1 :   memset(&circ_start_time, 0, sizeof(circ_start_time));
    1670             : 
    1671           1 :   extend_info_t fakehop;
    1672           1 :   memset(&fakehop, 0, sizeof(fakehop));
    1673           1 :   extend_info_t *single_fakehop = &fakehop;
    1674           1 :   extend_info_t *multi_fakehop[DEFAULT_ROUTE_LEN] = {&fakehop,
    1675             :                                                      &fakehop,
    1676             :                                                      &fakehop};
    1677             : 
    1678           1 :   extend_info_t ipv6_hop;
    1679           1 :   memset(&ipv6_hop, 0, sizeof(ipv6_hop));
    1680           1 :   tor_addr_parse(&ipv6_hop.orports[0].addr, "1::2");
    1681           1 :   extend_info_t *multi_ipv6_hop[DEFAULT_ROUTE_LEN] = {&ipv6_hop,
    1682             :                                                       &ipv6_hop,
    1683             :                                                       &ipv6_hop};
    1684             : 
    1685           1 :   extend_info_t ipv4_hop;
    1686           1 :   memset(&ipv4_hop, 0, sizeof(ipv4_hop));
    1687           1 :   tor_addr_from_ipv4h(&ipv4_hop.orports[0].addr, 0x20304050);
    1688           1 :   extend_info_t *multi_ipv4_hop[DEFAULT_ROUTE_LEN] = {&ipv4_hop,
    1689             :                                                       &ipv4_hop,
    1690             :                                                       &ipv4_hop};
    1691             : 
    1692           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1693           1 :   MOCK(circuit_deliver_create_cell, mock_circuit_deliver_create_cell);
    1694           1 :   server = 0;
    1695           1 :   MOCK(server_mode, mock_server_mode);
    1696             : 
    1697             :   /* Try a direct connection, and succeed on a client */
    1698           1 :   server = 0;
    1699           1 :   origin_circ = new_test_origin_circuit(false,
    1700             :                                         circ_start_time,
    1701             :                                         1,
    1702             :                                         &single_fakehop);
    1703           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1704             :   /* Skip some of the multi-hop checks */
    1705           1 :   origin_circ->build_state->onehop_tunnel = 1;
    1706             :   /* This is a direct connection */
    1707           1 :   mock_circuit_deliver_create_cell_expect_direct = true;
    1708           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, 0);
    1709             :   /* The circuits are automatically freed by the circuitlist. */
    1710             : 
    1711             :   /* Try a direct connection, and succeed on a server */
    1712           1 :   server = 1;
    1713           1 :   origin_circ = new_test_origin_circuit(false,
    1714             :                                         circ_start_time,
    1715             :                                         1,
    1716             :                                         &single_fakehop);
    1717           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1718           1 :   origin_circ->build_state->onehop_tunnel = 1;
    1719           1 :   mock_circuit_deliver_create_cell_expect_direct = true;
    1720           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, 0);
    1721             : 
    1722             :   /* Start capturing bugs */
    1723           1 :   setup_full_capture_of_logs(LOG_WARN);
    1724           1 :   tor_capture_bugs_(1);
    1725             : 
    1726             :   /* Try an extend, but fail the client valid address family check */
    1727           1 :   server = 0;
    1728           1 :   origin_circ = new_test_origin_circuit(true,
    1729             :                                         circ_start_time,
    1730             :                                         ARRAY_LENGTH(multi_fakehop),
    1731             :                                         multi_fakehop);
    1732           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1733             :   /* Fix the state */
    1734           1 :   origin_circ->base_.state = 0;
    1735             :   /* This is an indirect connection */
    1736           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1737             :   /* Fail because the address family is invalid */
    1738           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1739             :             -END_CIRC_REASON_INTERNAL);
    1740           1 :   expect_log_msg("No supported address family found in extend_info.\n");
    1741           1 :   mock_clean_saved_logs();
    1742             : 
    1743             :   /* Try an extend, but fail the server valid address check */
    1744           1 :   server = 1;
    1745           1 :   origin_circ = new_test_origin_circuit(true,
    1746             :                                         circ_start_time,
    1747             :                                         ARRAY_LENGTH(multi_fakehop),
    1748             :                                         multi_fakehop);
    1749           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1750           1 :   origin_circ->base_.state = 0;
    1751           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1752           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1753             :             -END_CIRC_REASON_INTERNAL);
    1754           1 :   expect_log_msg("No supported address family found in extend_info.\n");
    1755           1 :   mock_clean_saved_logs();
    1756             : 
    1757             :   /* Try an extend, but fail in the client code, with an IPv6 address */
    1758           1 :   server = 0;
    1759           1 :   origin_circ = new_test_origin_circuit(true,
    1760             :                                         circ_start_time,
    1761             :                                         ARRAY_LENGTH(multi_ipv6_hop),
    1762             :                                         multi_ipv6_hop);
    1763           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1764           1 :   origin_circ->base_.state = 0;
    1765           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1766           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1767             :             -END_CIRC_REASON_INTERNAL);
    1768           1 :   expect_log_msg("No supported address family found in extend_info.\n");
    1769           1 :   mock_clean_saved_logs();
    1770             : 
    1771             :   /* Stop capturing bugs, but keep capturing logs */
    1772           1 :   tor_end_capture_bugs_();
    1773             : 
    1774             :   /* Try an extend, pass the client IPv4 check, but fail later */
    1775           1 :   server = 0;
    1776           1 :   origin_circ = new_test_origin_circuit(true,
    1777             :                                         circ_start_time,
    1778             :                                         ARRAY_LENGTH(multi_ipv4_hop),
    1779             :                                         multi_ipv4_hop);
    1780           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1781           1 :   origin_circ->base_.state = 0;
    1782           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1783             :   /* Fail because the circuit data is invalid */
    1784           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1785             :             -END_CIRC_REASON_INTERNAL);
    1786           1 :   expect_log_msg("onion_skin_create failed.\n");
    1787           1 :   mock_clean_saved_logs();
    1788             : 
    1789             :   /* Try an extend, pass the server IPv4 check, but fail later */
    1790           1 :   server = 1;
    1791           1 :   origin_circ = new_test_origin_circuit(true,
    1792             :                                         circ_start_time,
    1793             :                                         ARRAY_LENGTH(multi_ipv4_hop),
    1794             :                                         multi_ipv4_hop);
    1795           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1796           1 :   origin_circ->base_.state = 0;
    1797           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1798           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1799             :             -END_CIRC_REASON_INTERNAL);
    1800           1 :   expect_log_msg("onion_skin_create failed.\n");
    1801           1 :   mock_clean_saved_logs();
    1802             : 
    1803             :   /* Try an extend, pass the server IPv6 check, but fail later */
    1804           1 :   server = 1;
    1805           1 :   origin_circ = new_test_origin_circuit(true,
    1806             :                                         circ_start_time,
    1807             :                                         ARRAY_LENGTH(multi_ipv6_hop),
    1808             :                                         multi_ipv6_hop);
    1809           1 :   tt_ptr_op(origin_circ, OP_NE, NULL);
    1810           1 :   origin_circ->base_.state = 0;
    1811           1 :   mock_circuit_deliver_create_cell_expect_direct = false;
    1812           1 :   tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
    1813             :             -END_CIRC_REASON_INTERNAL);
    1814           1 :   expect_log_msg("onion_skin_create failed.\n");
    1815           1 :   mock_clean_saved_logs();
    1816             : 
    1817             :   /* Things we're not testing right now:
    1818             :    * - the addresses in the extend cell inside
    1819             :    *   circuit_send_intermediate_onion_skin() matches the address in the
    1820             :    *   supplied extend_info.
    1821             :    * - valid circuit data.
    1822             :    * - actually extending the circuit to each hop. */
    1823             : 
    1824           1 :  done:
    1825           1 :   tor_end_capture_bugs_();
    1826           1 :   mock_clean_saved_logs();
    1827           1 :   teardown_capture_of_logs();
    1828             : 
    1829           1 :   UNMOCK(circuit_deliver_create_cell);
    1830           1 :   UNMOCK(server_mode);
    1831           1 :   server = 0;
    1832             : 
    1833             :   /* The circuits are automatically freed by the circuitlist. */
    1834           1 : }
    1835             : 
    1836             : /* Test the different cases in cpath_build_state_to_crn_flags(). */
    1837             : static void
    1838           1 : test_cpath_build_state_to_crn_flags(void *arg)
    1839             : {
    1840           1 :   (void)arg;
    1841             : 
    1842           1 :   cpath_build_state_t state;
    1843           1 :   memset(&state, 0, sizeof(state));
    1844             : 
    1845           1 :   tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
    1846             :             0);
    1847             : 
    1848           1 :   memset(&state, 0, sizeof(state));
    1849           1 :   state.need_uptime = 1;
    1850           1 :   tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
    1851             :             CRN_NEED_UPTIME);
    1852             : 
    1853           1 :   memset(&state, 0, sizeof(state));
    1854           1 :   state.need_capacity = 1;
    1855           1 :   tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
    1856             :             CRN_NEED_CAPACITY);
    1857             : 
    1858           1 :   memset(&state, 0, sizeof(state));
    1859           1 :   state.need_capacity = 1;
    1860           1 :   state.need_uptime = 1;
    1861           1 :   tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
    1862             :             CRN_NEED_CAPACITY | CRN_NEED_UPTIME);
    1863             : 
    1864             :   /* Check that no other flags are handled */
    1865           1 :   memset(&state, 0xff, sizeof(state));
    1866           1 :   tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
    1867             :             CRN_NEED_CAPACITY | CRN_NEED_UPTIME);
    1868             : 
    1869           1 :  done:
    1870           1 :   ;
    1871           1 : }
    1872             : 
    1873             : /* Test the different cases in cpath_build_state_to_crn_ipv6_extend_flag(). */
    1874             : static void
    1875           1 : test_cpath_build_state_to_crn_ipv6_extend_flag(void *arg)
    1876             : {
    1877           1 :   (void)arg;
    1878             : 
    1879           1 :   cpath_build_state_t state;
    1880             : 
    1881           1 :   memset(&state, 0, sizeof(state));
    1882           1 :   state.desired_path_len = DEFAULT_ROUTE_LEN;
    1883           1 :   tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, 0), OP_EQ,
    1884             :             0);
    1885             : 
    1886             :   /* Pass the state flag check, but not the length check */
    1887           1 :   memset(&state, 0, sizeof(state));
    1888           1 :   state.desired_path_len = DEFAULT_ROUTE_LEN;
    1889           1 :   state.is_ipv6_selftest = 1;
    1890           1 :   tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, 0), OP_EQ,
    1891             :             0);
    1892             : 
    1893             :   /* Pass the length check, but not the state flag check */
    1894           1 :   memset(&state, 0, sizeof(state));
    1895           1 :   state.desired_path_len = DEFAULT_ROUTE_LEN;
    1896           1 :   tt_int_op(
    1897             :       cpath_build_state_to_crn_ipv6_extend_flag(&state,
    1898             :                                                 DEFAULT_ROUTE_LEN - 2),
    1899             :       OP_EQ, 0);
    1900             : 
    1901             :   /* Pass both checks */
    1902           1 :   memset(&state, 0, sizeof(state));
    1903           1 :   state.desired_path_len = DEFAULT_ROUTE_LEN;
    1904           1 :   state.is_ipv6_selftest = 1;
    1905           1 :   tt_int_op(
    1906             :       cpath_build_state_to_crn_ipv6_extend_flag(&state,
    1907             :                                                 DEFAULT_ROUTE_LEN - 2),
    1908             :       OP_EQ, CRN_INITIATE_IPV6_EXTEND);
    1909             : 
    1910             :   /* Check that no other flags are handled */
    1911           1 :   memset(&state, 0xff, sizeof(state));
    1912           1 :   state.desired_path_len = INT_MAX;
    1913           1 :   tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, INT_MAX), OP_EQ,
    1914             :             0);
    1915             : 
    1916             : #ifndef ALL_BUGS_ARE_FATAL
    1917             :   /* Start capturing bugs */
    1918           1 :   setup_full_capture_of_logs(LOG_INFO);
    1919           1 :   tor_capture_bugs_(1);
    1920             : 
    1921             :   /* Now test the single hop circuit case */
    1922             : #define SINGLE_HOP_ROUTE_LEN 1
    1923           1 :   memset(&state, 0, sizeof(state));
    1924           1 :   state.desired_path_len = SINGLE_HOP_ROUTE_LEN;
    1925           1 :   state.is_ipv6_selftest = 1;
    1926           1 :   tt_int_op(
    1927             :       cpath_build_state_to_crn_ipv6_extend_flag(&state,
    1928             :                                                 SINGLE_HOP_ROUTE_LEN - 2),
    1929             :       OP_EQ, 0);
    1930           1 :   tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
    1931           1 :   tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
    1932             :             "!(ASSERT_PREDICT_UNLIKELY_(state->desired_path_len < 2))");
    1933           1 :   mock_clean_saved_logs();
    1934             : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
    1935             : 
    1936           1 :  done:
    1937           1 :   tor_end_capture_bugs_();
    1938           1 :   mock_clean_saved_logs();
    1939           1 :   teardown_capture_of_logs();
    1940           1 : }
    1941             : 
    1942             : #define TEST(name, flags, setup, cleanup) \
    1943             :   { #name, test_ ## name, flags, setup, cleanup }
    1944             : 
    1945             : #define TEST_NEW_ROUTE_LEN(name, flags) \
    1946             :   { #name, test_new_route_len_ ## name, flags, NULL, NULL }
    1947             : 
    1948             : #define TEST_CIRCUIT(name, flags) \
    1949             :   { #name, test_circuit_ ## name, flags, NULL, NULL }
    1950             : 
    1951             : #define TEST_CPATH(name, flags) \
    1952             :   { #name, test_cpath_ ## name, flags, NULL, NULL }
    1953             : 
    1954             : #ifndef COCCI
    1955             : #define TEST_CIRCUIT_PASSTHROUGH(name, flags, arg) \
    1956             :   { #name "/" arg, test_circuit_ ## name, flags, \
    1957             :     &passthrough_setup, (void *)(arg) }
    1958             : #endif
    1959             : 
    1960             : struct testcase_t circuitbuild_tests[] = {
    1961             :   TEST_NEW_ROUTE_LEN(noexit, 0),
    1962             :   TEST_NEW_ROUTE_LEN(safe_exit, 0),
    1963             :   TEST_NEW_ROUTE_LEN(unsafe_exit, 0),
    1964             :   TEST_NEW_ROUTE_LEN(unhandled_exit, 0),
    1965             : 
    1966             :   TEST(upgrade_from_guard_wait, TT_FORK, &helper_pubsub_setup, NULL),
    1967             : 
    1968             :   TEST_CIRCUIT(extend_state_valid, TT_FORK),
    1969             :   TEST_CIRCUIT(extend_add_ed25519, TT_FORK),
    1970             :   TEST_CIRCUIT(extend_lspec_valid, TT_FORK),
    1971             :   TEST_CIRCUIT(extend_add_ip, TT_FORK),
    1972             :   TEST_CIRCUIT(choose_ip_ap_for_extend, 0),
    1973             : 
    1974             :   TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "4"),
    1975             :   TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "6"),
    1976             :   TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "dual-stack"),
    1977             : 
    1978             :   TEST_CIRCUIT(extend, TT_FORK),
    1979             : 
    1980             :   TEST(onionskin_answer, TT_FORK, NULL, NULL),
    1981             : 
    1982             :   TEST(origin_circuit_init, TT_FORK, NULL, NULL),
    1983             :   TEST_CIRCUIT(send_next_onion_skin, TT_FORK),
    1984             :   TEST_CPATH(build_state_to_crn_flags, 0),
    1985             :   TEST_CPATH(build_state_to_crn_ipv6_extend_flag, TT_FORK),
    1986             : 
    1987             :   END_OF_TESTCASES
    1988             : };

Generated by: LCOV version 1.14