LCOV - code coverage report
Current view: top level - test - test_connection.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 380 404 94.1 %
Date: 2021-11-24 03:28:48 Functions: 19 21 90.5 %

          Line data    Source code
       1             : /* Copyright (c) 2015-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #include "orconfig.h"
       5             : 
       6             : #define CONNECTION_PRIVATE
       7             : #define MAINLOOP_PRIVATE
       8             : #define CONNECTION_OR_PRIVATE
       9             : 
      10             : #include "core/or/or.h"
      11             : #include "test/test.h"
      12             : 
      13             : #include "app/config/config.h"
      14             : #include "app/config/or_options_st.h"
      15             : #include "core/mainloop/connection.h"
      16             : #include "core/or/connection_edge.h"
      17             : #include "feature/hs/hs_common.h"
      18             : #include "core/mainloop/mainloop.h"
      19             : #include "feature/nodelist/microdesc.h"
      20             : #include "feature/nodelist/nodelist.h"
      21             : #include "feature/nodelist/networkstatus.h"
      22             : #include "feature/dircommon/directory.h"
      23             : #include "core/or/connection_or.h"
      24             : #include "lib/net/resolve.h"
      25             : 
      26             : #include "test/test_connection.h"
      27             : #include "test/test_helpers.h"
      28             : 
      29             : #include "feature/dircommon/dir_connection_st.h"
      30             : #include "core/or/entry_connection_st.h"
      31             : #include "feature/nodelist/node_st.h"
      32             : #include "core/or/or_connection_st.h"
      33             : #include "feature/nodelist/routerinfo_st.h"
      34             : #include "core/or/socks_request_st.h"
      35             : 
      36             : static void * test_conn_get_basic_setup(const struct testcase_t *tc);
      37             : static int test_conn_get_basic_teardown(const struct testcase_t *tc,
      38             :                                         void *arg);
      39             : 
      40             : static void * test_conn_get_rsrc_setup(const struct testcase_t *tc);
      41             : static int test_conn_get_rsrc_teardown(const struct testcase_t *tc,
      42             :                                         void *arg);
      43             : 
      44             : /* Arbitrary choice - IPv4 Directory Connection to localhost */
      45             : #define TEST_CONN_TYPE          (CONN_TYPE_DIR)
      46             : /* We assume every machine has IPv4 localhost, is that ok? */
      47             : #define TEST_CONN_ADDRESS       "127.0.0.1"
      48             : #define TEST_CONN_PORT          (12345)
      49             : #define TEST_CONN_ADDRESS_PORT  "127.0.0.1:12345"
      50             : #define TEST_CONN_FAMILY        (AF_INET)
      51             : #define TEST_CONN_STATE         (DIR_CONN_STATE_MIN_)
      52             : #define TEST_CONN_ADDRESS_2     "127.0.0.2"
      53             : 
      54             : #define TEST_CONN_BASIC_PURPOSE (DIR_PURPOSE_MIN_)
      55             : 
      56             : #define TEST_CONN_REND_ADDR     "cfs3rltphxxvabci"
      57             : #define TEST_CONN_REND_PURPOSE  (DIR_PURPOSE_FETCH_RENDDESC_V2)
      58             : #define TEST_CONN_REND_PURPOSE_SUCCESSFUL (DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2)
      59             : #define TEST_CONN_REND_TYPE_2   (CONN_TYPE_AP)
      60             : #define TEST_CONN_REND_ADDR_2   "icbavxxhptlr3sfc"
      61             : 
      62             : #define TEST_CONN_RSRC          (networkstatus_get_flavor_name(FLAV_MICRODESC))
      63             : #define TEST_CONN_RSRC_PURPOSE  (DIR_PURPOSE_FETCH_CONSENSUS)
      64             : #define TEST_CONN_RSRC_STATE_SUCCESSFUL (DIR_CONN_STATE_CLIENT_FINISHED)
      65             : #define TEST_CONN_RSRC_2        (networkstatus_get_flavor_name(FLAV_NS))
      66             : 
      67             : #define TEST_CONN_DL_STATE      (DIR_CONN_STATE_CLIENT_READING)
      68             : 
      69             : /* see AP_CONN_STATE_IS_UNATTACHED() */
      70             : #define TEST_CONN_UNATTACHED_STATE (AP_CONN_STATE_CIRCUIT_WAIT)
      71             : #define TEST_CONN_ATTACHED_STATE   (AP_CONN_STATE_CONNECT_WAIT)
      72             : 
      73             : void
      74          25 : test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr)
      75             : {
      76          25 :   int rv = 0;
      77             : 
      78          25 :   tt_assert(addr);
      79             : 
      80          25 :   rv = tor_addr_lookup(address, family, addr);
      81             :   /* XXXX - should we retry on transient failure? */
      82          25 :   tt_int_op(rv, OP_EQ, 0);
      83          25 :   tt_assert(tor_addr_is_loopback(addr));
      84          25 :   tt_assert(tor_addr_is_v4(addr));
      85             : 
      86             :   return;
      87             : 
      88           0 :  done:
      89           0 :   tor_addr_make_null(addr, TEST_CONN_FAMILY);
      90             : }
      91             : 
      92             : static void *
      93           1 : test_conn_get_basic_setup(const struct testcase_t *tc)
      94             : {
      95           1 :   (void)tc;
      96           1 :   return test_conn_get_connection(TEST_CONN_STATE, TEST_CONN_TYPE,
      97             :                                   TEST_CONN_BASIC_PURPOSE);
      98             : }
      99             : 
     100             : static int
     101           8 : test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg)
     102             : {
     103           8 :   (void)tc;
     104           8 :   connection_t *conn = arg;
     105             : 
     106           8 :   tt_assert(conn);
     107           8 :   assert_connection_ok(conn, time(NULL));
     108             : 
     109             :   /* teardown the connection as fast as possible */
     110           8 :   if (conn->linked_conn) {
     111           6 :     assert_connection_ok(conn->linked_conn, time(NULL));
     112             : 
     113             :     /* We didn't call tor_libevent_initialize(), so event_base was NULL,
     114             :      * so we can't rely on connection_unregister_events() use of event_del().
     115             :      */
     116           6 :     if (conn->linked_conn->read_event) {
     117           6 :       tor_free(conn->linked_conn->read_event);
     118           6 :       conn->linked_conn->read_event = NULL;
     119             :     }
     120           6 :     if (conn->linked_conn->write_event) {
     121           6 :       tor_free(conn->linked_conn->write_event);
     122           6 :       conn->linked_conn->write_event = NULL;
     123             :     }
     124             : 
     125           6 :     if (!conn->linked_conn->marked_for_close) {
     126           6 :       connection_close_immediate(conn->linked_conn);
     127           6 :       if (CONN_IS_EDGE(conn->linked_conn)) {
     128             :         /* Suppress warnings about all the stuff we didn't do */
     129           4 :         TO_EDGE_CONN(conn->linked_conn)->edge_has_sent_end = 1;
     130           4 :         TO_EDGE_CONN(conn->linked_conn)->end_reason =
     131             :           END_STREAM_REASON_INTERNAL;
     132           4 :         if (conn->linked_conn->type == CONN_TYPE_AP) {
     133           4 :           TO_ENTRY_CONN(conn->linked_conn)->socks_request->has_finished = 1;
     134             :         }
     135             :       }
     136           6 :       connection_mark_for_close(conn->linked_conn);
     137             :     }
     138             : 
     139           6 :     close_closeable_connections();
     140             :   }
     141             : 
     142             :   /* We didn't set the events up properly, so we can't use event_del() in
     143             :    * close_closeable_connections() > connection_free()
     144             :    * > connection_unregister_events() */
     145           8 :   if (conn->read_event) {
     146           8 :     tor_free(conn->read_event);
     147           8 :     conn->read_event = NULL;
     148             :   }
     149           8 :   if (conn->write_event) {
     150           8 :     tor_free(conn->write_event);
     151           8 :     conn->write_event = NULL;
     152             :   }
     153             : 
     154           8 :   if (!conn->marked_for_close) {
     155           8 :     connection_close_immediate(conn);
     156           8 :     if (CONN_IS_EDGE(conn)) {
     157             :       /* Suppress warnings about all the stuff we didn't do */
     158           2 :       TO_EDGE_CONN(conn)->edge_has_sent_end = 1;
     159           2 :       TO_EDGE_CONN(conn)->end_reason = END_STREAM_REASON_INTERNAL;
     160           2 :       if (conn->type == CONN_TYPE_AP) {
     161           2 :         TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
     162             :       }
     163             :     }
     164           8 :     connection_mark_for_close(conn);
     165             :   }
     166             : 
     167           8 :   close_closeable_connections();
     168             : 
     169             :   /* The unit test will fail if we return 0 */
     170           8 :   return 1;
     171             : 
     172             :   /* When conn == NULL, we can't cleanup anything */
     173           0 :  done:
     174           0 :   return 0;
     175             : }
     176             : 
     177             : static dir_connection_t *
     178           9 : test_conn_download_status_add_a_connection(const char *resource)
     179             : {
     180           9 :   dir_connection_t *conn = DOWNCAST(dir_connection_t,
     181             :                                     test_conn_get_connection(
     182             :                                                       TEST_CONN_STATE,
     183             :                                                       TEST_CONN_TYPE,
     184             :                                                       TEST_CONN_RSRC_PURPOSE));
     185             : 
     186           9 :   tt_assert(conn);
     187           9 :   assert_connection_ok(&conn->base_, time(NULL));
     188             : 
     189             :   /* Replace the existing resource with the one we want */
     190           9 :   if (resource) {
     191           9 :     if (conn->requested_resource) {
     192           0 :       tor_free(conn->requested_resource);
     193             :     }
     194           9 :     conn->requested_resource = tor_strdup(resource);
     195           9 :     assert_connection_ok(&conn->base_, time(NULL));
     196             :   }
     197             : 
     198             :   return conn;
     199             : 
     200           0 :  done:
     201           0 :   test_conn_get_rsrc_teardown(NULL, conn);
     202           0 :   return NULL;
     203             : }
     204             : 
     205             : static void *
     206           1 : test_conn_get_rsrc_setup(const struct testcase_t *tc)
     207             : {
     208           1 :   (void)tc;
     209           1 :   return test_conn_download_status_add_a_connection(TEST_CONN_RSRC);
     210             : }
     211             : 
     212             : static int
     213           7 : test_conn_get_rsrc_teardown(const struct testcase_t *tc, void *arg)
     214             : {
     215           7 :   int rv = 0;
     216             : 
     217           7 :   connection_t *conn = (connection_t *)arg;
     218           7 :   tt_assert(conn);
     219           7 :   assert_connection_ok(conn, time(NULL));
     220             : 
     221           7 :   if (conn->type == CONN_TYPE_DIR) {
     222           5 :     dir_connection_t *dir_conn = DOWNCAST(dir_connection_t, arg);
     223             : 
     224           5 :     tt_assert(dir_conn);
     225           5 :     assert_connection_ok(&dir_conn->base_, time(NULL));
     226             : 
     227             :     /* avoid a last-ditch attempt to refetch the consensus */
     228           5 :     dir_conn->base_.state = TEST_CONN_RSRC_STATE_SUCCESSFUL;
     229           5 :     assert_connection_ok(&dir_conn->base_, time(NULL));
     230             :   }
     231             : 
     232             :   /* connection_free_() cleans up requested_resource */
     233           7 :   rv = test_conn_get_basic_teardown(tc, conn);
     234             : 
     235           7 :  done:
     236           7 :   return rv;
     237             : }
     238             : 
     239             : static void *
     240           2 : test_conn_download_status_setup(const struct testcase_t *tc)
     241             : {
     242           2 :   return (void*)tc;
     243             : }
     244             : 
     245             : static int
     246           2 : test_conn_download_status_teardown(const struct testcase_t *tc, void *arg)
     247             : {
     248           2 :   (void)arg;
     249           2 :   int rv = 0;
     250             : 
     251             :   /* Ignore arg, and just loop through the connection array */
     252          16 :   SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
     253          14 :     if (conn) {
     254           6 :       assert_connection_ok(conn, time(NULL));
     255             : 
     256             :       /* connection_free_() cleans up requested_resource */
     257           6 :       rv = test_conn_get_rsrc_teardown(tc, conn);
     258           6 :       tt_int_op(rv, OP_EQ, 1);
     259             :     }
     260          14 :   } SMARTLIST_FOREACH_END(conn);
     261             : 
     262           2 :  done:
     263           2 :   return rv;
     264             : }
     265             : 
     266             : static void *
     267           2 : test_conn_proxy_connect_setup(const struct testcase_t *tc)
     268             : {
     269           2 :   return test_conn_get_proxy_or_connection(*(unsigned int *)tc->setup_data);
     270             : }
     271             : 
     272             : static int
     273           2 : test_conn_proxy_connect_teardown(const struct testcase_t *tc, void *arg)
     274             : {
     275           2 :   (void)tc;
     276           2 :   or_connection_t *conn = arg;
     277             : 
     278           2 :   tt_assert(conn);
     279           2 :   assert_connection_ok(&conn->base_, time(NULL));
     280             : 
     281           2 :  done:
     282           2 :   return 1;
     283             : }
     284             : 
     285             : /* Like connection_ap_make_link(), but does much less */
     286             : static connection_t *
     287           6 : test_conn_get_linked_connection(connection_t *l_conn, uint8_t state)
     288             : {
     289           6 :   tt_assert(l_conn);
     290           6 :   assert_connection_ok(l_conn, time(NULL));
     291             : 
     292             :   /* AP connections don't seem to have purposes */
     293           6 :   connection_t *conn = test_conn_get_connection(state, CONN_TYPE_AP,
     294             :                                                        0);
     295             : 
     296           6 :   tt_assert(conn);
     297           6 :   assert_connection_ok(conn, time(NULL));
     298             : 
     299           6 :   conn->linked = 1;
     300           6 :   l_conn->linked = 1;
     301           6 :   conn->linked_conn = l_conn;
     302           6 :   l_conn->linked_conn = conn;
     303             :   /* we never opened a real socket, so we can just overwrite it */
     304           6 :   conn->s = TOR_INVALID_SOCKET;
     305           6 :   l_conn->s = TOR_INVALID_SOCKET;
     306             : 
     307           6 :   assert_connection_ok(conn, time(NULL));
     308           6 :   assert_connection_ok(l_conn, time(NULL));
     309             : 
     310           6 :   return conn;
     311             : 
     312           0 :  done:
     313           0 :   test_conn_download_status_teardown(NULL, NULL);
     314           0 :   return NULL;
     315             : }
     316             : 
     317             : static struct testcase_setup_t test_conn_get_basic_st = {
     318             :   test_conn_get_basic_setup, test_conn_get_basic_teardown
     319             : };
     320             : 
     321             : static struct testcase_setup_t test_conn_get_rsrc_st = {
     322             :   test_conn_get_rsrc_setup, test_conn_get_rsrc_teardown
     323             : };
     324             : 
     325             : static struct testcase_setup_t test_conn_download_status_st = {
     326             :   test_conn_download_status_setup, test_conn_download_status_teardown
     327             : };
     328             : 
     329             : static struct testcase_setup_t test_conn_proxy_connect_st = {
     330             :   test_conn_proxy_connect_setup, test_conn_proxy_connect_teardown
     331             : };
     332             : 
     333             : static void
     334           1 : test_conn_get_basic(void *arg)
     335             : {
     336           1 :   connection_t *conn = (connection_t*)arg;
     337           1 :   tor_addr_t addr, addr2;
     338             : 
     339           1 :   tt_assert(conn);
     340           1 :   assert_connection_ok(conn, time(NULL));
     341             : 
     342           1 :   test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &addr);
     343           1 :   tt_assert(!tor_addr_is_null(&addr));
     344           1 :   test_conn_lookup_addr_helper(TEST_CONN_ADDRESS_2, TEST_CONN_FAMILY, &addr2);
     345           1 :   tt_assert(!tor_addr_is_null(&addr2));
     346             : 
     347             :   /* Check that we get this connection back when we search for it by
     348             :    * its attributes, but get NULL when we supply a different value. */
     349             : 
     350           1 :   tt_assert(connection_get_by_global_id(conn->global_identifier) == conn);
     351           1 :   tt_ptr_op(connection_get_by_global_id(!conn->global_identifier), OP_EQ,
     352             :             NULL);
     353             : 
     354           1 :   tt_assert(connection_get_by_type(conn->type) == conn);
     355           1 :   tt_assert(connection_get_by_type(TEST_CONN_TYPE) == conn);
     356           1 :   tt_ptr_op(connection_get_by_type(!conn->type), OP_EQ, NULL);
     357           1 :   tt_ptr_op(connection_get_by_type(!TEST_CONN_TYPE), OP_EQ, NULL);
     358             : 
     359           1 :   tt_assert(connection_get_by_type_state(conn->type, conn->state)
     360             :             == conn);
     361           1 :   tt_assert(connection_get_by_type_state(TEST_CONN_TYPE, TEST_CONN_STATE)
     362             :             == conn);
     363           1 :   tt_assert(connection_get_by_type_state(!conn->type, !conn->state)
     364             :             == NULL);
     365           1 :   tt_assert(connection_get_by_type_state(!TEST_CONN_TYPE, !TEST_CONN_STATE)
     366             :             == NULL);
     367             : 
     368             :   /* Match on the connection fields themselves */
     369           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     370             :                                                      &conn->addr,
     371             :                                                      conn->port,
     372             :                                                      conn->purpose)
     373             :             == conn);
     374             :   /* Match on the original inputs to the connection */
     375           1 :   tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE,
     376             :                                                      &conn->addr,
     377             :                                                      conn->port,
     378             :                                                      conn->purpose)
     379             :             == conn);
     380           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     381             :                                                      &addr,
     382             :                                                      conn->port,
     383             :                                                      conn->purpose)
     384             :             == conn);
     385           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     386             :                                                      &conn->addr,
     387             :                                                      TEST_CONN_PORT,
     388             :                                                      conn->purpose)
     389             :             == conn);
     390           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     391             :                                                      &conn->addr,
     392             :                                                      conn->port,
     393             :                                                      TEST_CONN_BASIC_PURPOSE)
     394             :             == conn);
     395           1 :   tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE,
     396             :                                                      &addr,
     397             :                                                      TEST_CONN_PORT,
     398             :                                                      TEST_CONN_BASIC_PURPOSE)
     399             :             == conn);
     400             :   /* Then try each of the not-matching combinations */
     401           1 :   tt_assert(connection_get_by_type_addr_port_purpose(!conn->type,
     402             :                                                      &conn->addr,
     403             :                                                      conn->port,
     404             :                                                      conn->purpose)
     405             :             == NULL);
     406           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     407             :                                                      &addr2,
     408             :                                                      conn->port,
     409             :                                                      conn->purpose)
     410             :             == NULL);
     411           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     412             :                                                      &conn->addr,
     413             :                                                      !conn->port,
     414             :                                                      conn->purpose)
     415             :             == NULL);
     416           1 :   tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
     417             :                                                      &conn->addr,
     418             :                                                      conn->port,
     419             :                                                      !conn->purpose)
     420             :             == NULL);
     421             :   /* Then try everything not-matching */
     422           1 :   tt_assert(connection_get_by_type_addr_port_purpose(!conn->type,
     423             :                                                      &addr2,
     424             :                                                      !conn->port,
     425             :                                                      !conn->purpose)
     426             :             == NULL);
     427           1 :   tt_assert(connection_get_by_type_addr_port_purpose(!TEST_CONN_TYPE,
     428             :                                                      &addr2,
     429             :                                                      !TEST_CONN_PORT,
     430             :                                                      !TEST_CONN_BASIC_PURPOSE)
     431             :             == NULL);
     432             : 
     433           1 :  done:
     434           1 :   ;
     435           1 : }
     436             : 
     437             : #define sl_is_conn_assert(sl_input, conn) \
     438             :   do {                                               \
     439             :     the_sl = (sl_input);                             \
     440             :     tt_int_op(smartlist_len((the_sl)), OP_EQ, 1);         \
     441             :     tt_assert(smartlist_get((the_sl), 0) == (conn)); \
     442             :     smartlist_free(the_sl); the_sl = NULL;           \
     443             :   } while (0)
     444             : 
     445             : #define sl_no_conn_assert(sl_input)          \
     446             :   do {                                       \
     447             :     the_sl = (sl_input);                     \
     448             :     tt_int_op(smartlist_len((the_sl)), OP_EQ, 0); \
     449             :     smartlist_free(the_sl); the_sl = NULL;   \
     450             :   } while (0)
     451             : 
     452             : static void
     453           1 : test_conn_get_rsrc(void *arg)
     454             : {
     455           1 :   dir_connection_t *conn = DOWNCAST(dir_connection_t, arg);
     456           1 :   smartlist_t *the_sl = NULL;
     457           1 :   tt_assert(conn);
     458           1 :   assert_connection_ok(&conn->base_, time(NULL));
     459             : 
     460           1 :   sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
     461             :                                                     conn->base_.purpose,
     462             :                                                     conn->requested_resource),
     463             :                     conn);
     464           1 :   sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
     465             :                                                     TEST_CONN_RSRC_PURPOSE,
     466             :                                                     TEST_CONN_RSRC),
     467             :                     conn);
     468           1 :   sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
     469             :                                                     !conn->base_.purpose,
     470             :                                                     ""));
     471           1 :   sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
     472             :                                                     !TEST_CONN_RSRC_PURPOSE,
     473             :                                                     TEST_CONN_RSRC_2));
     474             : 
     475           1 :   sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
     476             :                                                     conn->base_.purpose,
     477             :                                                     conn->requested_resource,
     478             :                                                     conn->base_.state),
     479             :                     conn);
     480           1 :   sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
     481             :                                                     TEST_CONN_RSRC_PURPOSE,
     482             :                                                     TEST_CONN_RSRC,
     483             :                                                     TEST_CONN_STATE),
     484             :                     conn);
     485           1 :   sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state(
     486             :                                                     !conn->base_.purpose,
     487             :                                                     "",
     488             :                                                     !conn->base_.state));
     489           1 :   sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state(
     490             :                                                     !TEST_CONN_RSRC_PURPOSE,
     491             :                                                     TEST_CONN_RSRC_2,
     492             :                                                     !TEST_CONN_STATE));
     493             : 
     494           1 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     495             :                  conn->base_.purpose, conn->requested_resource),
     496             :             OP_EQ, 1);
     497           1 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     498             :                  TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC),
     499             :             OP_EQ, 1);
     500           1 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     501             :                  !conn->base_.purpose, ""),
     502             :             OP_EQ, 0);
     503           1 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     504             :                  !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2),
     505             :             OP_EQ, 0);
     506             : 
     507           1 :   tt_int_op(connection_dir_count_by_purpose_resource_and_state(
     508             :                  conn->base_.purpose, conn->requested_resource,
     509             :                  conn->base_.state),
     510             :             OP_EQ, 1);
     511           1 :   tt_int_op(connection_dir_count_by_purpose_resource_and_state(
     512             :                  TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC, TEST_CONN_STATE),
     513             :             OP_EQ, 1);
     514           1 :   tt_int_op(connection_dir_count_by_purpose_resource_and_state(
     515             :                  !conn->base_.purpose, "", !conn->base_.state),
     516             :             OP_EQ, 0);
     517           1 :   tt_int_op(connection_dir_count_by_purpose_resource_and_state(
     518             :                  !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2, !TEST_CONN_STATE),
     519             :             OP_EQ, 0);
     520             : 
     521           1 :  done:
     522           1 :   smartlist_free(the_sl);
     523           1 : }
     524             : 
     525             : static void
     526           2 : test_conn_download_status(void *arg)
     527             : {
     528           2 :   dir_connection_t *conn = NULL;
     529           2 :   dir_connection_t *conn2 = NULL;
     530           2 :   dir_connection_t *conn4 = NULL;
     531           2 :   connection_t *ap_conn = NULL;
     532             : 
     533           2 :   const struct testcase_t *tc = arg;
     534           4 :   consensus_flavor_t usable_flavor =
     535           2 :     networkstatus_parse_flavor_name((const char*) tc->setup_data);
     536             : 
     537             :   /* The "other flavor" trick only works if there are two flavors */
     538           2 :   tor_assert(N_CONSENSUS_FLAVORS == 2);
     539           2 :   consensus_flavor_t other_flavor = ((usable_flavor == FLAV_NS)
     540             :                                      ? FLAV_MICRODESC
     541           2 :                                      : FLAV_NS);
     542           2 :   const char *res = networkstatus_get_flavor_name(usable_flavor);
     543           2 :   const char *other_res = networkstatus_get_flavor_name(other_flavor);
     544             : 
     545             :   /* no connections */
     546           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     547           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     548             :             0);
     549           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     550             :                                            TEST_CONN_RSRC_PURPOSE, res),
     551             :             OP_EQ, 0);
     552           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     553             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     554             :             OP_EQ, 0);
     555             : 
     556             :   /* one connection, not downloading */
     557           2 :   conn = test_conn_download_status_add_a_connection(res);
     558           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     559           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     560             :             0);
     561           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     562             :                                            TEST_CONN_RSRC_PURPOSE, res),
     563             :             OP_EQ, 1);
     564           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     565             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     566             :             OP_EQ, 0);
     567             : 
     568             :   /* one connection, downloading but not linked (not possible on a client,
     569             :    * but possible on a relay) */
     570           2 :   conn->base_.state = TEST_CONN_DL_STATE;
     571           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     572           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     573             :             0);
     574           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     575             :                                            TEST_CONN_RSRC_PURPOSE, res),
     576             :             OP_EQ, 1);
     577           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     578             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     579             :             OP_EQ, 0);
     580             : 
     581             :   /* one connection, downloading and linked, but not yet attached */
     582           2 :   ap_conn = test_conn_get_linked_connection(TO_CONN(conn),
     583             :                                             TEST_CONN_UNATTACHED_STATE);
     584           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     585           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     586             :             0);
     587           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     588             :                                            TEST_CONN_RSRC_PURPOSE, res),
     589             :             OP_EQ, 1);
     590           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     591             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     592             :             OP_EQ, 0);
     593             : 
     594             :     /* one connection, downloading and linked and attached */
     595           2 :   ap_conn->state = TEST_CONN_ATTACHED_STATE;
     596           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     597           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     598             :             0);
     599           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     600             :                                            TEST_CONN_RSRC_PURPOSE, res),
     601             :             OP_EQ, 1);
     602           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     603             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     604             :             OP_EQ, 0);
     605             : 
     606             :   /* one connection, linked and attached but not downloading */
     607           2 :   conn->base_.state = TEST_CONN_STATE;
     608           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     609           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     610             :             0);
     611           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     612             :                                            TEST_CONN_RSRC_PURPOSE, res),
     613             :             OP_EQ, 1);
     614           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     615             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     616             :             OP_EQ, 0);
     617             : 
     618             :   /* two connections, both not downloading */
     619           2 :   conn2 = test_conn_download_status_add_a_connection(res);
     620           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     621           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     622             :             0);
     623           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     624             :                                            TEST_CONN_RSRC_PURPOSE, res),
     625             :             OP_EQ, 2);
     626           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     627             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     628             :             OP_EQ, 0);
     629             : 
     630             :   /* two connections, one downloading */
     631           2 :   conn->base_.state = TEST_CONN_DL_STATE;
     632           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     633           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     634             :             0);
     635           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     636             :                                            TEST_CONN_RSRC_PURPOSE, res),
     637             :             OP_EQ, 2);
     638           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     639             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     640             :             OP_EQ, 0);
     641           2 :   conn->base_.state = TEST_CONN_STATE;
     642             : 
     643             :   /* more connections, all not downloading */
     644             :   /* ignore the return value, it's free'd using the connection list */
     645           2 :   (void)test_conn_download_status_add_a_connection(res);
     646           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
     647           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     648             :             0);
     649           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     650             :                                            TEST_CONN_RSRC_PURPOSE, res),
     651             :             OP_EQ, 3);
     652           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     653             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     654             :             OP_EQ, 0);
     655             : 
     656             :   /* more connections, one downloading */
     657           2 :   conn->base_.state = TEST_CONN_DL_STATE;
     658           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     659           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     660             :             0);
     661           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     662             :                                            TEST_CONN_RSRC_PURPOSE, res),
     663             :             OP_EQ, 3);
     664           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     665             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     666             :             OP_EQ, 0);
     667             : 
     668             :   /* more connections, two downloading (should never happen, but needs
     669             :    * to be tested for completeness) */
     670           2 :   conn2->base_.state = TEST_CONN_DL_STATE;
     671             :   /* ignore the return value, it's free'd using the connection list */
     672           2 :   (void)test_conn_get_linked_connection(TO_CONN(conn2),
     673             :                                         TEST_CONN_ATTACHED_STATE);
     674           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     675           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     676             :             0);
     677           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     678             :                                            TEST_CONN_RSRC_PURPOSE, res),
     679             :             OP_EQ, 3);
     680           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     681             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     682             :             OP_EQ, 0);
     683           2 :   conn->base_.state = TEST_CONN_STATE;
     684             : 
     685             :   /* more connections, a different one downloading */
     686           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     687           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     688             :             0);
     689           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     690             :                                            TEST_CONN_RSRC_PURPOSE, res),
     691             :             OP_EQ, 3);
     692           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     693             :                                            TEST_CONN_RSRC_PURPOSE, other_res),
     694             :             OP_EQ, 0);
     695             : 
     696             :   /* a connection for the other flavor (could happen if a client is set to
     697             :    * cache directory documents), one preferred flavor downloading
     698             :    */
     699           2 :   conn4 = test_conn_download_status_add_a_connection(other_res);
     700           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     701           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     702             :             0);
     703           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     704             :                                    TEST_CONN_RSRC_PURPOSE, res),
     705             :             OP_EQ, 3);
     706           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     707             :                                    TEST_CONN_RSRC_PURPOSE, other_res),
     708             :             OP_EQ, 1);
     709             : 
     710             :   /* a connection for the other flavor (could happen if a client is set to
     711             :    * cache directory documents), both flavors downloading
     712             :    */
     713           2 :   conn4->base_.state = TEST_CONN_DL_STATE;
     714             :   /* ignore the return value, it's free'd using the connection list */
     715           2 :   (void)test_conn_get_linked_connection(TO_CONN(conn4),
     716             :                                         TEST_CONN_ATTACHED_STATE);
     717           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
     718           2 :   tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
     719             :             1);
     720           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     721             :                                    TEST_CONN_RSRC_PURPOSE, res),
     722             :             OP_EQ, 3);
     723           2 :   tt_int_op(connection_dir_count_by_purpose_and_resource(
     724             :                                    TEST_CONN_RSRC_PURPOSE, other_res),
     725             :             OP_EQ, 1);
     726             : 
     727           2 :  done:
     728           2 :   /* the teardown function removes all the connections in the global list*/;
     729           2 : }
     730             : 
     731             : static void
     732           1 : test_conn_https_proxy_connect(void *arg)
     733             : {
     734           1 :   size_t sz;
     735           1 :   char *buf = NULL;
     736           1 :   or_connection_t *conn = arg;
     737             : 
     738           1 :   MOCK(connection_or_change_state, mock_connection_or_change_state);
     739             : 
     740           1 :   tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HTTPS_WANT_CONNECT_OK);
     741             : 
     742           1 :   buf = buf_get_contents(conn->base_.outbuf, &sz);
     743           1 :   tt_str_op(buf, OP_EQ, "CONNECT 127.0.0.1:12345 HTTP/1.0\r\n\r\n");
     744             : 
     745           1 :  done:
     746           1 :   UNMOCK(connection_or_change_state);
     747           1 :   tor_free(buf);
     748           1 : }
     749             : 
     750             : static int handshake_start_called = 0;
     751             : 
     752             : static int
     753           1 : handshake_start(or_connection_t *conn, int receiving)
     754             : {
     755           1 :   (void)receiving;
     756             : 
     757           1 :   tor_assert(conn);
     758             : 
     759           1 :   handshake_start_called = 1;
     760           1 :   return 0;
     761             : }
     762             : 
     763             : static void
     764           1 : test_conn_haproxy_proxy_connect(void *arg)
     765             : {
     766           1 :   size_t sz;
     767           1 :   char *buf = NULL;
     768           1 :   or_connection_t *conn = arg;
     769             : 
     770           1 :   MOCK(connection_or_change_state, mock_connection_or_change_state);
     771           1 :   MOCK(connection_tls_start_handshake, handshake_start);
     772             : 
     773           1 :   tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HAPROXY_WAIT_FOR_FLUSH);
     774             : 
     775           1 :   buf = buf_get_contents(conn->base_.outbuf, &sz);
     776           1 :   tt_str_op(buf, OP_EQ, "PROXY TCP4 0.0.0.0 127.0.0.1 0 12345\r\n");
     777             : 
     778           1 :   connection_or_finished_flushing(conn);
     779             : 
     780           1 :   tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_CONNECTED);
     781           1 :   tt_int_op(handshake_start_called, OP_EQ, 1);
     782             : 
     783           1 :  done:
     784           1 :   UNMOCK(connection_or_change_state);
     785           1 :   UNMOCK(connection_tls_start_handshake);
     786           1 :   tor_free(buf);
     787           1 : }
     788             : 
     789             : static node_t test_node;
     790             : 
     791             : static node_t *
     792           0 : mock_node_get_mutable_by_id(const char *digest)
     793             : {
     794           0 :   (void) digest;
     795           0 :   static routerinfo_t node_ri;
     796           0 :   memset(&node_ri, 0, sizeof(node_ri));
     797             : 
     798           0 :   test_node.ri = &node_ri;
     799           0 :   memset(test_node.identity, 'c', sizeof(test_node.identity));
     800             : 
     801           0 :   tor_addr_parse(&node_ri.ipv4_addr, "18.0.0.1");
     802           0 :   node_ri.ipv4_orport = 1;
     803             : 
     804           0 :   return &test_node;
     805             : }
     806             : 
     807             : static const node_t *
     808           0 : mock_node_get_by_id(const char *digest)
     809             : {
     810           0 :   (void) digest;
     811           0 :   memset(test_node.identity, 'c', sizeof(test_node.identity));
     812           0 :   return &test_node;
     813             : }
     814             : 
     815             : /* Test whether we correctly track failed connections between relays. */
     816             : static void
     817           1 : test_failed_orconn_tracker(void *arg)
     818             : {
     819           1 :   (void) arg;
     820             : 
     821           1 :   int can_connect;
     822           1 :   time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
     823           1 :   (void) now;
     824             : 
     825           1 :   update_approx_time(now);
     826             : 
     827             :   /* Prepare the OR connection that will be used in this test */
     828           1 :   or_connection_t or_conn;
     829           1 :   tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.canonical_orport.addr,
     830             :                                           "18.0.0.1"));
     831           1 :   tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1"));
     832           1 :   or_conn.base_.port = 1;
     833           1 :   memset(or_conn.identity_digest, 'c', sizeof(or_conn.identity_digest));
     834             : 
     835             :   /* Check whether we can connect with an empty failure cache:
     836             :    * this should succeed */
     837           1 :   can_connect = should_connect_to_relay(&or_conn);
     838           1 :   tt_int_op(can_connect, OP_EQ, 1);
     839             : 
     840             :   /* Now add the destination to the failure cache */
     841           1 :   note_or_connect_failed(&or_conn);
     842             : 
     843             :   /* Check again: now it shouldn't connect */
     844           1 :   can_connect = should_connect_to_relay(&or_conn);
     845           1 :   tt_int_op(can_connect, OP_EQ, 0);
     846             : 
     847             :   /* Move time forward and check again: the cache should have been cleared and
     848             :    * now it should connect */
     849           1 :   now += 3600;
     850           1 :   update_approx_time(now);
     851           1 :   can_connect = should_connect_to_relay(&or_conn);
     852           1 :   tt_int_op(can_connect, OP_EQ, 1);
     853             : 
     854             :   /* Now mock the node_get_*by_id() functions to start using the node subsystem
     855             :    * optimization. */
     856           1 :   MOCK(node_get_by_id, mock_node_get_by_id);
     857           1 :   MOCK(node_get_mutable_by_id, mock_node_get_mutable_by_id);
     858             : 
     859             :   /* Since we just started using the node subsystem it will allow connections
     860             :    * now */
     861           1 :   can_connect = should_connect_to_relay(&or_conn);
     862           1 :   tt_int_op(can_connect, OP_EQ, 1);
     863             : 
     864             :   /* Mark it as failed */
     865           1 :   note_or_connect_failed(&or_conn);
     866             : 
     867             :   /* Check that it shouldn't connect now */
     868           1 :   can_connect = should_connect_to_relay(&or_conn);
     869           1 :   tt_int_op(can_connect, OP_EQ, 0);
     870             : 
     871             :   /* Move time forward and check again: now it should connect  */
     872           1 :   now += 3600;
     873           1 :   update_approx_time(now);
     874           1 :   can_connect = should_connect_to_relay(&or_conn);
     875           1 :   tt_int_op(can_connect, OP_EQ, 1);
     876             : 
     877           1 :  done:
     878           1 :   ;
     879           1 : }
     880             : 
     881             : static void
     882           1 : test_conn_describe(void *arg)
     883             : {
     884           1 :   (void)arg;
     885           1 :   or_options_t *options = get_options_mutable();
     886           1 :   options->SafeLogging_ = SAFELOG_SCRUB_ALL;
     887             : 
     888             :   // Let's start with a listener connection since they're simple.
     889           1 :   connection_t *conn = connection_new(CONN_TYPE_OR_LISTENER, AF_INET);
     890           1 :   tor_addr_parse(&conn->addr, "44.22.11.11");
     891           1 :   conn->port = 80;
     892           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     893             :             "OR listener connection (ready) on 44.22.11.11:80");
     894             :   // If the address is unspec, we should still work.
     895           1 :   tor_addr_make_unspec(&conn->addr);
     896           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     897             :             "OR listener connection (ready) on <unset>:80");
     898             :   // Try making the address null.
     899           1 :   tor_addr_make_null(&conn->addr, AF_INET);
     900           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     901             :             "OR listener connection (ready) on 0.0.0.0:80");
     902             :   // What if the address is uninitialized? (This can happen if we log about the
     903             :   // connection before we set the address.)
     904           1 :   memset(&conn->addr, 0, sizeof(conn->addr));
     905           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     906             :             "OR listener connection (ready) on <unset>:80");
     907           1 :   connection_free_minimal(conn);
     908             : 
     909             :   // Try a unix socket.
     910           1 :   conn = connection_new(CONN_TYPE_CONTROL_LISTENER, AF_UNIX);
     911           1 :   conn->address = tor_strdup("/a/path/that/could/exist");
     912           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     913             :             "Control listener connection (ready) on /a/path/that/could/exist");
     914           1 :   connection_free_minimal(conn);
     915             : 
     916             :   // Try an IPv6 address.
     917           1 :   conn = connection_new(CONN_TYPE_AP_LISTENER, AF_INET6);
     918           1 :   tor_addr_parse(&conn->addr, "ff00::3");
     919           1 :   conn->port = 9050;
     920           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     921             :             "Socks listener connection (ready) on [ff00::3]:9050");
     922           1 :   connection_free_minimal(conn);
     923             : 
     924             :   // Now let's mess with exit connections.  They have some special issues.
     925           1 :   options->SafeLogging_ = SAFELOG_SCRUB_NONE;
     926           1 :   conn = connection_new(CONN_TYPE_EXIT, AF_INET);
     927             :   // If address and state are unset, we should say SOMETHING.
     928           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     929             :             "Exit connection (uninitialized) to <unset> (DNS lookup pending)");
     930             :   // Now suppose that the address is set but we haven't resolved the hostname.
     931           1 :   conn->port = 443;
     932           1 :   conn->address = tor_strdup("www.torproject.org");
     933           1 :   conn->state = EXIT_CONN_STATE_RESOLVING;
     934           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     935             :             "Exit connection (waiting for dest info) to "
     936             :             "www.torproject.org:443 (DNS lookup pending)");
     937             :   //  Now give it a hostname!
     938           1 :   tor_addr_parse(&conn->addr, "192.168.8.8");
     939           1 :   conn->state = EXIT_CONN_STATE_OPEN;
     940           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     941             :             "Exit connection (open) to 192.168.8.8:443");
     942             :   // But what if safelogging is on?
     943           1 :   options->SafeLogging_ = SAFELOG_SCRUB_RELAY;
     944           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     945             :             "Exit connection (open) to [scrubbed]");
     946           1 :   connection_free_minimal(conn);
     947             : 
     948             :   // Now at last we look at OR addresses, which are complicated.
     949           1 :   conn = connection_new(CONN_TYPE_OR, AF_INET6);
     950           1 :   conn->state = OR_CONN_STATE_OPEN;
     951           1 :   conn->port = 8080;
     952           1 :   tor_addr_parse(&conn->addr, "[ffff:3333:1111::2]");
     953             :   // This should get scrubbed, since the lack of a set ID means we might be
     954             :   // talking to a client.
     955           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     956             :             "OR connection (open) with [scrubbed]");
     957             :   // But now suppose we aren't safelogging? We'll get the address then.
     958           1 :   options->SafeLogging_ = SAFELOG_SCRUB_NONE;
     959           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     960             :             "OR connection (open) with [ffff:3333:1111::2]:8080");
     961             :   // Suppose we have an ID, so we know it isn't a client.
     962           1 :   TO_OR_CONN(conn)->identity_digest[3] = 7;
     963           1 :   options->SafeLogging_ = SAFELOG_SCRUB_RELAY; // back to safelogging.
     964           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     965             :             "OR connection (open) with [ffff:3333:1111::2]:8080 "
     966             :             "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
     967             :   // Add a 'canonical address' that is the same as the one we have.
     968           1 :   tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr,
     969             :                  "[ffff:3333:1111::2]");
     970           1 :   TO_OR_CONN(conn)->canonical_orport.port = 8080;
     971           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     972             :             "OR connection (open) with [ffff:3333:1111::2]:8080 "
     973             :             "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
     974             :   // Add a different 'canonical address'
     975           1 :   tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr,
     976             :                  "[ffff:3333:1111::8]");
     977           1 :   tt_str_op(connection_describe(conn), OP_EQ,
     978             :             "OR connection (open) with [ffff:3333:1111::2]:8080 "
     979             :             "ID=<none> RSA_ID=0000000700000000000000000000000000000000 "
     980             :             "canonical_addr=[ffff:3333:1111::8]:8080");
     981             : 
     982             :   // Clear identity_digest so that free_minimal won't complain.
     983           1 :   memset(TO_OR_CONN(conn)->identity_digest, 0, DIGEST_LEN);
     984             : 
     985           1 :  done:
     986           1 :   connection_free_minimal(conn);
     987           1 : }
     988             : 
     989             : #ifndef COCCI
     990             : #define CONNECTION_TESTCASE(name, fork, setup)                           \
     991             :   { #name, test_conn_##name, fork, &setup, NULL }
     992             : 
     993             : #define STR(x) #x
     994             : /* where arg is an expression (constant, variable, compound expression) */
     995             : #define CONNECTION_TESTCASE_ARG(name, extra, fork, setup, arg)          \
     996             :   { STR(name)"/"extra,                                                  \
     997             :       test_conn_##name,                                                 \
     998             :       (fork),                                                           \
     999             :       &(setup),                                                         \
    1000             :       (void *)(arg) }
    1001             : #endif /* !defined(COCCI) */
    1002             : 
    1003             : static const unsigned int PROXY_CONNECT_ARG = PROXY_CONNECT;
    1004             : static const unsigned int PROXY_HAPROXY_ARG = PROXY_HAPROXY;
    1005             : 
    1006             : struct testcase_t connection_tests[] = {
    1007             :   CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st),
    1008             :   CONNECTION_TESTCASE(get_rsrc,  TT_FORK, test_conn_get_rsrc_st),
    1009             : 
    1010             :   CONNECTION_TESTCASE_ARG(download_status, "microdesc", TT_FORK,
    1011             :                           test_conn_download_status_st, "microdesc"),
    1012             :   CONNECTION_TESTCASE_ARG(download_status, "ns", TT_FORK,
    1013             :                           test_conn_download_status_st, "ns"),
    1014             : 
    1015             :   CONNECTION_TESTCASE_ARG(https_proxy_connect, "https", TT_FORK,
    1016             :                           test_conn_proxy_connect_st, &PROXY_CONNECT_ARG),
    1017             :   CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, "haproxy", TT_FORK,
    1018             :                           test_conn_proxy_connect_st, &PROXY_HAPROXY_ARG),
    1019             : 
    1020             :   //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
    1021             :   { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
    1022             :   { "describe", test_conn_describe, TT_FORK, NULL, NULL },
    1023             :   END_OF_TESTCASES
    1024             : };

Generated by: LCOV version 1.14