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

          Line data    Source code
       1             : /* Copyright (c) 2013-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #define CONNECTION_PRIVATE
       5             : #define CHANNEL_OBJECT_PRIVATE
       6             : #define CONTROL_PRIVATE
       7             : #define CONTROL_EVENTS_PRIVATE
       8             : #define OCIRC_EVENT_PRIVATE
       9             : #define ORCONN_EVENT_PRIVATE
      10             : #include "app/main/subsysmgr.h"
      11             : #include "core/or/or.h"
      12             : #include "core/or/channel.h"
      13             : #include "core/or/channeltls.h"
      14             : #include "core/or/circuitlist.h"
      15             : #include "core/or/ocirc_event.h"
      16             : #include "core/or/orconn_event.h"
      17             : #include "core/mainloop/connection.h"
      18             : #include "feature/control/control_events.h"
      19             : #include "feature/control/control_fmt.h"
      20             : #include "test/test.h"
      21             : #include "test/test_helpers.h"
      22             : #include "test/log_test_helpers.h"
      23             : 
      24             : #include "core/or/entry_connection_st.h"
      25             : #include "core/or/or_circuit_st.h"
      26             : #include "core/or/origin_circuit_st.h"
      27             : #include "core/or/socks_request_st.h"
      28             : 
      29             : static void
      30           4 : add_testing_cell_stats_entry(circuit_t *circ, uint8_t command,
      31             :                              unsigned int waiting_time,
      32             :                              unsigned int removed, unsigned int exitward)
      33             : {
      34           4 :   testing_cell_stats_entry_t *ent = tor_malloc_zero(
      35             :                                     sizeof(testing_cell_stats_entry_t));
      36           4 :   ent->command = command;
      37           4 :   ent->waiting_time = waiting_time;
      38           4 :   ent->removed = removed;
      39           4 :   ent->exitward = exitward;
      40           4 :   if (!circ->testing_cell_stats)
      41           4 :     circ->testing_cell_stats = smartlist_new();
      42           4 :   smartlist_add(circ->testing_cell_stats, ent);
      43           4 : }
      44             : 
      45             : static void
      46           1 : test_cntev_sum_up_cell_stats(void *arg)
      47             : {
      48           1 :   or_circuit_t *or_circ;
      49           1 :   circuit_t *circ;
      50           1 :   cell_stats_t *cell_stats = NULL;
      51           1 :   (void)arg;
      52             : 
      53             :   /* This circuit is fake. */
      54           1 :   or_circ = tor_malloc_zero(sizeof(or_circuit_t));
      55           1 :   or_circ->base_.magic = OR_CIRCUIT_MAGIC;
      56           1 :   or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
      57           1 :   circ = TO_CIRCUIT(or_circ);
      58             : 
      59             :   /* A single RELAY cell was added to the appward queue. */
      60           1 :   cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
      61           1 :   add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 0);
      62           1 :   sum_up_cell_stats_by_command(circ, cell_stats);
      63           1 :   tt_u64_op(1, OP_EQ, cell_stats->added_cells_appward[CELL_RELAY]);
      64             : 
      65             :   /* A single RELAY cell was added to the exitward queue. */
      66           1 :   add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 1);
      67           1 :   sum_up_cell_stats_by_command(circ, cell_stats);
      68           1 :   tt_u64_op(1, OP_EQ, cell_stats->added_cells_exitward[CELL_RELAY]);
      69             : 
      70             :   /* A single RELAY cell was removed from the appward queue where it spent
      71             :    * 20 msec. */
      72           1 :   add_testing_cell_stats_entry(circ, CELL_RELAY, 2, 1, 0);
      73           1 :   sum_up_cell_stats_by_command(circ, cell_stats);
      74           1 :   tt_u64_op(20, OP_EQ, cell_stats->total_time_appward[CELL_RELAY]);
      75           1 :   tt_u64_op(1, OP_EQ, cell_stats->removed_cells_appward[CELL_RELAY]);
      76             : 
      77             :   /* A single RELAY cell was removed from the exitward queue where it
      78             :    * spent 30 msec. */
      79           1 :   add_testing_cell_stats_entry(circ, CELL_RELAY, 3, 1, 1);
      80           1 :   sum_up_cell_stats_by_command(circ, cell_stats);
      81           1 :   tt_u64_op(30, OP_EQ, cell_stats->total_time_exitward[CELL_RELAY]);
      82           1 :   tt_u64_op(1, OP_EQ, cell_stats->removed_cells_exitward[CELL_RELAY]);
      83             : 
      84           1 :  done:
      85           1 :   tor_free(cell_stats);
      86           1 :   tor_free(or_circ);
      87           1 : }
      88             : 
      89             : static void
      90           1 : test_cntev_append_cell_stats(void *arg)
      91             : {
      92           1 :   smartlist_t *event_parts;
      93           1 :   char *cp = NULL;
      94           1 :   const char *key = "Z";
      95           1 :   uint64_t include_if_non_zero[CELL_COMMAND_MAX_ + 1],
      96             :            number_to_include[CELL_COMMAND_MAX_ + 1];
      97           1 :   (void)arg;
      98             : 
      99           1 :   event_parts = smartlist_new();
     100           1 :   memset(include_if_non_zero, 0,
     101             :          (CELL_COMMAND_MAX_ + 1) * sizeof(uint64_t));
     102           1 :   memset(number_to_include, 0,
     103             :          (CELL_COMMAND_MAX_ + 1) * sizeof(uint64_t));
     104             : 
     105             :   /* All array entries empty. */
     106           1 :   append_cell_stats_by_command(event_parts, key,
     107             :                                include_if_non_zero,
     108             :                                number_to_include);
     109           1 :   tt_int_op(0, OP_EQ, smartlist_len(event_parts));
     110             : 
     111             :   /* There's a RELAY cell to include, but the corresponding field in
     112             :    * include_if_non_zero is still zero. */
     113           1 :   number_to_include[CELL_RELAY] = 1;
     114           1 :   append_cell_stats_by_command(event_parts, key,
     115             :                                include_if_non_zero,
     116             :                                number_to_include);
     117           1 :   tt_int_op(0, OP_EQ, smartlist_len(event_parts));
     118             : 
     119             :   /* Now include single RELAY cell. */
     120           1 :   include_if_non_zero[CELL_RELAY] = 2;
     121           1 :   append_cell_stats_by_command(event_parts, key,
     122             :                                include_if_non_zero,
     123             :                                number_to_include);
     124           1 :   cp = smartlist_pop_last(event_parts);
     125           1 :   tt_str_op("Z=relay:1", OP_EQ, cp);
     126           1 :   tor_free(cp);
     127             : 
     128             :   /* Add four CREATE cells. */
     129           1 :   include_if_non_zero[CELL_CREATE] = 3;
     130           1 :   number_to_include[CELL_CREATE] = 4;
     131           1 :   append_cell_stats_by_command(event_parts, key,
     132             :                                include_if_non_zero,
     133             :                                number_to_include);
     134           1 :   cp = smartlist_pop_last(event_parts);
     135           1 :   tt_str_op("Z=create:4,relay:1", OP_EQ, cp);
     136             : 
     137           1 :  done:
     138           1 :   tor_free(cp);
     139           1 :   smartlist_free(event_parts);
     140           1 : }
     141             : 
     142             : static void
     143           1 : test_cntev_format_cell_stats(void *arg)
     144             : {
     145           1 :   char *event_string = NULL;
     146           1 :   origin_circuit_t *ocirc = NULL;
     147           1 :   or_circuit_t *or_circ = NULL;
     148           1 :   cell_stats_t *cell_stats = NULL;
     149           1 :   channel_tls_t *n_chan=NULL, *p_chan=NULL;
     150           1 :   (void)arg;
     151             : 
     152           1 :   n_chan = tor_malloc_zero(sizeof(channel_tls_t));
     153           1 :   n_chan->base_.global_identifier = 1;
     154             : 
     155           1 :   ocirc = tor_malloc_zero(sizeof(origin_circuit_t));
     156           1 :   ocirc->base_.magic = ORIGIN_CIRCUIT_MAGIC;
     157           1 :   ocirc->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
     158           1 :   ocirc->global_identifier = 2;
     159           1 :   ocirc->base_.n_circ_id = 3;
     160           1 :   ocirc->base_.n_chan = &(n_chan->base_);
     161             : 
     162             :   /* Origin circuit was completely idle. */
     163           1 :   cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
     164           1 :   format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
     165           1 :   tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1", OP_EQ, event_string);
     166           1 :   tor_free(event_string);
     167             : 
     168             :   /* Origin circuit had 4 RELAY cells added to its exitward queue. */
     169           1 :   cell_stats->added_cells_exitward[CELL_RELAY] = 4;
     170           1 :   format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
     171           1 :   tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4",
     172             :             OP_EQ, event_string);
     173           1 :   tor_free(event_string);
     174             : 
     175             :   /* Origin circuit also had 5 CREATE2 cells added to its exitward
     176             :    * queue. */
     177           1 :   cell_stats->added_cells_exitward[CELL_CREATE2] = 5;
     178           1 :   format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
     179           1 :   tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
     180             :             "create2:5", OP_EQ, event_string);
     181           1 :   tor_free(event_string);
     182             : 
     183             :   /* Origin circuit also had 7 RELAY cells removed from its exitward queue
     184             :    * which together spent 6 msec in the queue. */
     185           1 :   cell_stats->total_time_exitward[CELL_RELAY] = 6;
     186           1 :   cell_stats->removed_cells_exitward[CELL_RELAY] = 7;
     187           1 :   format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
     188           1 :   tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
     189             :             "create2:5 OutboundRemoved=relay:7 OutboundTime=relay:6",
     190             :             OP_EQ, event_string);
     191           1 :   tor_free(event_string);
     192             : 
     193           1 :   p_chan = tor_malloc_zero(sizeof(channel_tls_t));
     194           1 :   p_chan->base_.global_identifier = 2;
     195             : 
     196           1 :   or_circ = tor_malloc_zero(sizeof(or_circuit_t));
     197           1 :   or_circ->base_.magic = OR_CIRCUIT_MAGIC;
     198           1 :   or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
     199           1 :   or_circ->p_circ_id = 8;
     200           1 :   or_circ->p_chan = &(p_chan->base_);
     201           1 :   or_circ->base_.n_circ_id = 9;
     202           1 :   or_circ->base_.n_chan = &(n_chan->base_);
     203             : 
     204           1 :   tor_free(cell_stats);
     205             : 
     206             :   /* OR circuit was idle. */
     207           1 :   cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
     208           1 :   format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
     209           1 :   tt_str_op("InboundQueue=8 InboundConn=2 OutboundQueue=9 OutboundConn=1",
     210             :             OP_EQ, event_string);
     211           1 :   tor_free(event_string);
     212             : 
     213             :   /* OR circuit had 3 RELAY cells added to its appward queue. */
     214           1 :   cell_stats->added_cells_appward[CELL_RELAY] = 3;
     215           1 :   format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
     216           1 :   tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
     217             :             "OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
     218           1 :   tor_free(event_string);
     219             : 
     220             :   /* OR circuit had 7 RELAY cells removed from its appward queue which
     221             :    * together spent 6 msec in the queue. */
     222           1 :   cell_stats->total_time_appward[CELL_RELAY] = 6;
     223           1 :   cell_stats->removed_cells_appward[CELL_RELAY] = 7;
     224           1 :   format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
     225           1 :   tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
     226             :             "InboundRemoved=relay:7 InboundTime=relay:6 "
     227             :             "OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
     228             : 
     229           1 :  done:
     230           1 :   tor_free(cell_stats);
     231           1 :   tor_free(event_string);
     232           1 :   tor_free(or_circ);
     233           1 :   tor_free(ocirc);
     234           1 :   tor_free(p_chan);
     235           1 :   tor_free(n_chan);
     236           1 : }
     237             : 
     238             : static void
     239           1 : test_cntev_event_mask(void *arg)
     240             : {
     241           1 :   unsigned int test_event, selected_event;
     242           1 :   (void)arg;
     243             : 
     244             :   /* Check that nothing is interesting when no events are set */
     245           1 :   control_testing_set_global_event_mask(EVENT_MASK_NONE_);
     246             : 
     247             :   /* Check that nothing is interesting between EVENT_MIN_ and EVENT_MAX_ */
     248          39 :   for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++)
     249          37 :     tt_assert(!control_event_is_interesting(test_event));
     250             : 
     251             :   /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
     252             :    * This will break if control_event_is_interesting() checks its arguments */
     253           2 :   for (test_event = 0; test_event < EVENT_MIN_; test_event++)
     254           2 :     tt_assert(!control_event_is_interesting(test_event));
     255             :   for (test_event = EVENT_MAX_ + 1;
     256          27 :        test_event < EVENT_CAPACITY_;
     257          26 :        test_event++)
     258          26 :     tt_assert(!control_event_is_interesting(test_event));
     259             : 
     260             :   /* Check that all valid events are interesting when all events are set */
     261           1 :   control_testing_set_global_event_mask(EVENT_MASK_ALL_);
     262             : 
     263             :   /* Check that everything is interesting between EVENT_MIN_ and EVENT_MAX_ */
     264          39 :   for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++)
     265          37 :     tt_assert(control_event_is_interesting(test_event));
     266             : 
     267             :   /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
     268             :    * This will break if control_event_is_interesting() checks its arguments */
     269           2 :   for (test_event = 0; test_event < EVENT_MIN_; test_event++)
     270           2 :     tt_assert(!control_event_is_interesting(test_event));
     271             :   for (test_event = EVENT_MAX_ + 1;
     272          27 :        test_event < EVENT_CAPACITY_;
     273          26 :        test_event++)
     274          26 :     tt_assert(!control_event_is_interesting(test_event));
     275             : 
     276             :   /* Check that only that event is interesting when a single event is set */
     277             :   for (selected_event = EVENT_MIN_;
     278          38 :        selected_event <= EVENT_MAX_;
     279          37 :        selected_event++) {
     280          37 :     control_testing_set_global_event_mask(EVENT_MASK_(selected_event));
     281             : 
     282             :     /* Check that only this event is interesting
     283             :      * between EVENT_MIN_ and EVENT_MAX_ */
     284        1443 :     for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++) {
     285        1369 :       if (test_event == selected_event) {
     286          37 :         tt_assert(control_event_is_interesting(test_event));
     287             :       } else {
     288        1369 :         tt_assert(!control_event_is_interesting(test_event));
     289             :       }
     290             :     }
     291             : 
     292             :     /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
     293             :      * This will break if control_event_is_interesting checks its arguments */
     294          74 :     for (test_event = 0; test_event < EVENT_MIN_; test_event++)
     295          74 :       tt_assert(!control_event_is_interesting(test_event));
     296             :     for (test_event = EVENT_MAX_ + 1;
     297         999 :          test_event < EVENT_CAPACITY_;
     298         962 :          test_event++)
     299         962 :       tt_assert(!control_event_is_interesting(test_event));
     300             :   }
     301             : 
     302             :   /* Check that only that event is not-interesting
     303             :    * when a single event is un-set */
     304             :   for (selected_event = EVENT_MIN_;
     305          38 :        selected_event <= EVENT_MAX_;
     306          37 :        selected_event++) {
     307          37 :     control_testing_set_global_event_mask(
     308             :                                           EVENT_MASK_ALL_
     309          37 :                                           & ~(EVENT_MASK_(selected_event))
     310             :                                           );
     311             : 
     312             :     /* Check that only this event is not-interesting
     313             :      * between EVENT_MIN_ and EVENT_MAX_ */
     314        1443 :     for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++) {
     315        1369 :       if (test_event == selected_event) {
     316          37 :         tt_assert(!control_event_is_interesting(test_event));
     317             :       } else {
     318        1369 :         tt_assert(control_event_is_interesting(test_event));
     319             :       }
     320             :     }
     321             : 
     322             :     /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
     323             :      * This will break if control_event_is_interesting checks its arguments */
     324          74 :     for (test_event = 0; test_event < EVENT_MIN_; test_event++)
     325          74 :       tt_assert(!control_event_is_interesting(test_event));
     326             :     for (test_event = EVENT_MAX_ + 1;
     327         999 :          test_event < EVENT_CAPACITY_;
     328         962 :          test_event++)
     329         962 :       tt_assert(!control_event_is_interesting(test_event));
     330             :   }
     331             : 
     332           1 :  done:
     333           1 :   ;
     334           1 : }
     335             : 
     336             : static char *saved_event_str = NULL;
     337             : 
     338             : static void
     339          32 : mock_queue_control_event_string(uint16_t event, char *msg)
     340             : {
     341          32 :   (void)event;
     342             : 
     343          32 :   tor_free(saved_event_str);
     344          32 :   saved_event_str = msg;
     345          32 : }
     346             : 
     347             : /* Helper macro for checking bootstrap control event strings */
     348             : #define assert_bootmsg(s)                                               \
     349             :   tt_ptr_op(strstr(saved_event_str, "650 STATUS_CLIENT NOTICE "         \
     350             :                    "BOOTSTRAP PROGRESS=" s), OP_EQ, saved_event_str)
     351             : 
     352             : /* Test deferral of directory bootstrap messages (requesting_descriptors) */
     353             : static void
     354           1 : test_cntev_dirboot_defer_desc(void *arg)
     355             : {
     356           1 :   (void)arg;
     357             : 
     358           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     359           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
     360           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
     361           1 :   assert_bootmsg("0 TAG=starting");
     362             :   /* This event should get deferred */
     363           1 :   control_event_boot_dir(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
     364           1 :   assert_bootmsg("0 TAG=starting");
     365           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0);
     366           1 :   assert_bootmsg("5 TAG=conn");
     367           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
     368           1 :   assert_bootmsg("14 TAG=handshake");
     369             :   /* The deferred event should appear */
     370           1 :   control_event_boot_first_orconn();
     371           1 :   assert_bootmsg("45 TAG=requesting_descriptors");
     372           1 :  done:
     373           1 :   tor_free(saved_event_str);
     374           1 :   UNMOCK(queue_control_event_string);
     375           1 : }
     376             : 
     377             : /* Test deferral of directory bootstrap messages (conn_or) */
     378             : static void
     379           1 : test_cntev_dirboot_defer_orconn(void *arg)
     380             : {
     381           1 :   (void)arg;
     382             : 
     383           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     384           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
     385           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
     386           1 :   assert_bootmsg("0 TAG=starting");
     387             :   /* This event should get deferred */
     388           1 :   control_event_boot_dir(BOOTSTRAP_STATUS_ENOUGH_DIRINFO, 0);
     389           1 :   assert_bootmsg("0 TAG=starting");
     390           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0);
     391           1 :   assert_bootmsg("5 TAG=conn");
     392           1 :   control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
     393           1 :   assert_bootmsg("14 TAG=handshake");
     394             :   /* The deferred event should appear */
     395           1 :   control_event_boot_first_orconn();
     396           1 :   assert_bootmsg("75 TAG=enough_dirinfo");
     397           1 :  done:
     398           1 :   tor_free(saved_event_str);
     399           1 :   UNMOCK(queue_control_event_string);
     400           1 : }
     401             : 
     402             : static void
     403           1 : test_cntev_signal(void *arg)
     404             : {
     405           1 :   (void)arg;
     406           1 :   int rv;
     407             : 
     408           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     409             : 
     410             :   /* Nothing is listening for signals, so no event should be queued. */
     411           1 :   rv = control_event_signal(SIGHUP);
     412           1 :   tt_int_op(0, OP_EQ, rv);
     413           1 :   tt_ptr_op(saved_event_str, OP_EQ, NULL);
     414             : 
     415             :   /* Now try with signals included in the event mask. */
     416           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_GOT_SIGNAL));
     417           1 :   rv = control_event_signal(SIGHUP);
     418           1 :   tt_int_op(0, OP_EQ, rv);
     419           1 :   tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL RELOAD\r\n");
     420             : 
     421           1 :   rv = control_event_signal(SIGACTIVE);
     422           1 :   tt_int_op(0, OP_EQ, rv);
     423           1 :   tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL ACTIVE\r\n");
     424             : 
     425             :   /* Try a signal that doesn't exist. */
     426           1 :   setup_full_capture_of_logs(LOG_WARN);
     427           1 :   tor_free(saved_event_str);
     428           1 :   rv = control_event_signal(99999);
     429           1 :   tt_int_op(-1, OP_EQ, rv);
     430           1 :   tt_ptr_op(saved_event_str, OP_EQ, NULL);
     431           1 :   expect_single_log_msg_containing("Unrecognized signal 99999");
     432             : 
     433           1 :  done:
     434           1 :   tor_free(saved_event_str);
     435           1 :  teardown_capture_of_logs();
     436           1 :   UNMOCK(queue_control_event_string);
     437           1 : }
     438             : 
     439             : static void
     440           1 : test_cntev_log_fmt(void *arg)
     441             : {
     442           1 :   (void) arg;
     443           1 :   char *result = NULL;
     444             : #define CHECK(pre, post) \
     445             :   do {                                            \
     446             :     result = tor_strdup((pre));                   \
     447             :     control_logmsg_strip_newlines(result);        \
     448             :     tt_str_op(result, OP_EQ, (post));             \
     449             :     tor_free(result);                             \
     450             :   } while (0)
     451             : 
     452           1 :   CHECK("There is a ", "There is a");
     453           1 :   CHECK("hello", "hello");
     454           1 :   CHECK("", "");
     455           1 :   CHECK("Put    spaces at the end   ", "Put    spaces at the end");
     456           1 :   CHECK("         ", "");
     457           1 :   CHECK("\n\n\n", "");
     458           1 :   CHECK("Testing\r\n", "Testing");
     459           1 :   CHECK("T e s t\ni n g\n", "T e s t i n g");
     460             : 
     461           1 :  done:
     462           1 :   tor_free(result);
     463             : #undef CHECK
     464           1 : }
     465             : 
     466             : static void
     467           3 : setup_orconn_state(orconn_state_msg_t *msg, uint64_t gid, uint64_t chan,
     468             :                    int proxy_type)
     469             : {
     470           3 :   msg->gid = gid;
     471           3 :   msg->chan = chan;
     472           3 :   msg->proxy_type = proxy_type;
     473           3 : }
     474             : 
     475             : static void
     476          22 : send_orconn_state(const orconn_state_msg_t *msg_in, uint8_t state)
     477             : {
     478          22 :   orconn_state_msg_t *msg = tor_malloc(sizeof(*msg));
     479             : 
     480          22 :   *msg = *msg_in;
     481          22 :   msg->state = state;
     482          22 :   orconn_state_publish(msg);
     483          22 : }
     484             : 
     485             : static void
     486           6 : send_ocirc_chan(uint32_t gid, uint64_t chan, bool onehop)
     487             : {
     488           6 :   ocirc_chan_msg_t *msg = tor_malloc(sizeof(*msg));
     489             : 
     490           6 :   msg->gid = gid;
     491           6 :   msg->chan = chan;
     492           6 :   msg->onehop = onehop;
     493           6 :   ocirc_chan_publish(msg);
     494           6 : }
     495             : 
     496             : static void
     497           1 : test_cntev_orconn_state(void *arg)
     498             : {
     499           1 :   orconn_state_msg_t conn;
     500           1 :   memset(&conn, 0, sizeof(conn));
     501             : 
     502           1 :   (void)arg;
     503           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     504           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
     505           1 :   setup_orconn_state(&conn, 1, 1, PROXY_NONE);
     506             : 
     507           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     508           1 :   send_ocirc_chan(1, 1, true);
     509           1 :   assert_bootmsg("5 TAG=conn");
     510           1 :   send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING);
     511           1 :   assert_bootmsg("10 TAG=conn_done");
     512           1 :   send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3);
     513           1 :   assert_bootmsg("14 TAG=handshake");
     514           1 :   send_orconn_state(&conn, OR_CONN_STATE_OPEN);
     515           1 :   assert_bootmsg("15 TAG=handshake_done");
     516             : 
     517           1 :   conn.gid = 2;
     518           1 :   conn.chan = 2;
     519           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     520             :   /* It doesn't know it's an origin circuit yet */
     521           1 :   assert_bootmsg("15 TAG=handshake_done");
     522           1 :   send_ocirc_chan(2, 2, false);
     523           1 :   assert_bootmsg("80 TAG=ap_conn");
     524           1 :   send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING);
     525           1 :   assert_bootmsg("85 TAG=ap_conn_done");
     526           1 :   send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3);
     527           1 :   assert_bootmsg("89 TAG=ap_handshake");
     528           1 :   send_orconn_state(&conn, OR_CONN_STATE_OPEN);
     529           1 :   assert_bootmsg("90 TAG=ap_handshake_done");
     530             : 
     531           1 :  done:
     532           1 :   tor_free(saved_event_str);
     533           1 :   UNMOCK(queue_control_event_string);
     534           1 : }
     535             : 
     536             : static void
     537           1 : test_cntev_orconn_state_pt(void *arg)
     538             : {
     539           1 :   orconn_state_msg_t conn;
     540           1 :   memset(&conn, 0, sizeof(conn));
     541             : 
     542           1 :   (void)arg;
     543           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     544           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
     545           1 :   setup_orconn_state(&conn, 1, 1, PROXY_PLUGGABLE);
     546           1 :   send_ocirc_chan(1, 1, true);
     547             : 
     548           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     549           1 :   assert_bootmsg("1 TAG=conn_pt");
     550           1 :   send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING);
     551           1 :   assert_bootmsg("2 TAG=conn_done_pt");
     552           1 :   send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING);
     553           1 :   assert_bootmsg("10 TAG=conn_done");
     554           1 :   send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3);
     555           1 :   assert_bootmsg("14 TAG=handshake");
     556           1 :   send_orconn_state(&conn, OR_CONN_STATE_OPEN);
     557           1 :   assert_bootmsg("15 TAG=handshake_done");
     558             : 
     559           1 :   send_ocirc_chan(2, 2, false);
     560           1 :   conn.gid = 2;
     561           1 :   conn.chan = 2;
     562           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     563           1 :   assert_bootmsg("76 TAG=ap_conn_pt");
     564           1 :   send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING);
     565           1 :   assert_bootmsg("77 TAG=ap_conn_done_pt");
     566             : 
     567           1 :  done:
     568           1 :   tor_free(saved_event_str);
     569           1 :   UNMOCK(queue_control_event_string);
     570           1 : }
     571             : 
     572             : static void
     573           1 : test_cntev_orconn_state_proxy(void *arg)
     574             : {
     575           1 :   orconn_state_msg_t conn;
     576           1 :   memset(&conn, 0, sizeof(conn));
     577             : 
     578           1 :   (void)arg;
     579           1 :   MOCK(queue_control_event_string, mock_queue_control_event_string);
     580           1 :   control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
     581           1 :   setup_orconn_state(&conn, 1, 1, PROXY_CONNECT);
     582           1 :   send_ocirc_chan(1, 1, true);
     583             : 
     584           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     585           1 :   assert_bootmsg("3 TAG=conn_proxy");
     586           1 :   send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING);
     587           1 :   assert_bootmsg("4 TAG=conn_done_proxy");
     588           1 :   send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING);
     589           1 :   assert_bootmsg("10 TAG=conn_done");
     590           1 :   send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3);
     591           1 :   assert_bootmsg("14 TAG=handshake");
     592           1 :   send_orconn_state(&conn, OR_CONN_STATE_OPEN);
     593           1 :   assert_bootmsg("15 TAG=handshake_done");
     594             : 
     595           1 :   send_ocirc_chan(2, 2, false);
     596           1 :   conn.gid = 2;
     597           1 :   conn.chan = 2;
     598           1 :   send_orconn_state(&conn, OR_CONN_STATE_CONNECTING);
     599           1 :   assert_bootmsg("78 TAG=ap_conn_proxy");
     600           1 :   send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING);
     601           1 :   assert_bootmsg("79 TAG=ap_conn_done_proxy");
     602             : 
     603           1 :  done:
     604           1 :   tor_free(saved_event_str);
     605           1 :   UNMOCK(queue_control_event_string);
     606           1 : }
     607             : 
     608             : static void
     609           1 : test_cntev_format_stream(void *arg)
     610             : {
     611           1 :   entry_connection_t *ec = NULL;
     612           1 :   char *conndesc = NULL;
     613           1 :   (void)arg;
     614             : 
     615           1 :   ec = entry_connection_new(CONN_TYPE_AP, AF_INET);
     616             : 
     617           1 :   char *username = tor_strdup("jeremy");
     618           1 :   char *password = tor_strdup("letmein");
     619           1 :   ec->socks_request->username = username; // steal reference
     620           1 :   ec->socks_request->usernamelen = strlen(username);
     621           1 :   ec->socks_request->password = password; // steal reference
     622           1 :   ec->socks_request->passwordlen = strlen(password);
     623           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     624           1 :   tt_assert(strstr(conndesc, "SOCKS_USERNAME=\"jeremy\""));
     625           1 :   tt_assert(strstr(conndesc, "SOCKS_PASSWORD=\"letmein\""));
     626           1 :   tor_free(conndesc);
     627             : 
     628           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER;
     629           1 :   ec->socks_request->socks_version = 4;
     630           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     631           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=SOCKS4"));
     632           1 :   tor_free(conndesc);
     633             : 
     634           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER;
     635           1 :   ec->socks_request->socks_version = 5;
     636           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     637           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=SOCKS5"));
     638           1 :   tor_free(conndesc);
     639             : 
     640           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER;
     641           1 :   ec->socks_request->socks_version = 6;
     642           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     643           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=UNKNOWN"));
     644           1 :   tor_free(conndesc);
     645             : 
     646           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_TRANS_LISTENER;
     647           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     648           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=TRANS"));
     649           1 :   tor_free(conndesc);
     650             : 
     651           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_NATD_LISTENER;
     652           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     653           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=NATD"));
     654           1 :   tor_free(conndesc);
     655             : 
     656           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_DNS_LISTENER;
     657           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     658           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=DNS"));
     659           1 :   tor_free(conndesc);
     660             : 
     661           1 :   ec->socks_request->listener_type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER;
     662           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     663           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=HTTPCONNECT"));
     664           1 :   tor_free(conndesc);
     665             : 
     666           1 :   ec->socks_request->listener_type = CONN_TYPE_OR;
     667           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     668           1 :   tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=UNKNOWN"));
     669           1 :   tor_free(conndesc);
     670             : 
     671           1 :   ec->nym_epoch = 1337;
     672           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     673           1 :   tt_assert(strstr(conndesc, "NYM_EPOCH=1337"));
     674           1 :   tor_free(conndesc);
     675             : 
     676           1 :   ec->entry_cfg.session_group = 4321;
     677           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     678           1 :   tt_assert(strstr(conndesc, "SESSION_GROUP=4321"));
     679           1 :   tor_free(conndesc);
     680             : 
     681           1 :   ec->entry_cfg.isolation_flags = ISO_DESTPORT;
     682           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     683           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=DESTPORT"));
     684           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=DESTPORT,"));
     685           1 :   tor_free(conndesc);
     686             : 
     687           1 :   ec->entry_cfg.isolation_flags = ISO_DESTADDR;
     688           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     689           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=DESTADDR"));
     690           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=DESTADDR,"));
     691           1 :   tor_free(conndesc);
     692             : 
     693           1 :   ec->entry_cfg.isolation_flags = ISO_SOCKSAUTH;
     694           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     695           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=SOCKS_USERNAME,SOCKS_PASSWORD"));
     696           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=SOCKS_USERNAME,SOCKS_PASSWORD,"));
     697           1 :   tor_free(conndesc);
     698             : 
     699           1 :   ec->entry_cfg.isolation_flags = ISO_CLIENTPROTO;
     700           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     701           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=CLIENT_PROTOCOL"));
     702           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=CLIENT_PROTOCOL,"));
     703           1 :   tor_free(conndesc);
     704             : 
     705           1 :   ec->entry_cfg.isolation_flags = ISO_CLIENTADDR;
     706           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     707           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=CLIENTADDR"));
     708           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=CLIENTADDR,"));
     709           1 :   tor_free(conndesc);
     710             : 
     711           1 :   ec->entry_cfg.isolation_flags = ISO_SESSIONGRP;
     712           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     713           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=SESSION_GROUP"));
     714           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=SESSION_GROUP,"));
     715           1 :   tor_free(conndesc);
     716             : 
     717           1 :   ec->entry_cfg.isolation_flags = ISO_NYM_EPOCH;
     718           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     719           1 :   tt_assert(strstr(conndesc, "ISO_FIELDS=NYM_EPOCH"));
     720           1 :   tt_assert(!strstr(conndesc, "ISO_FIELDS=NYM_EPOCH,"));
     721           1 :   tor_free(conndesc);
     722             : 
     723           1 :   ec->entry_cfg.isolation_flags = ISO_DESTPORT | ISO_SOCKSAUTH | ISO_NYM_EPOCH;
     724           1 :   conndesc = entry_connection_describe_status_for_controller(ec);
     725           1 :   tt_assert(strstr(conndesc,
     726             :     "ISO_FIELDS=DESTPORT,SOCKS_USERNAME,SOCKS_PASSWORD,NYM_EPOCH"));
     727           1 :   tt_assert(!strstr(conndesc,
     728             :     "ISO_FIELDS=DESTPORT,SOCKS_USERNAME,SOCKS_PASSWORD,NYM_EPOCH,"));
     729             : 
     730           1 :  done:
     731           1 :   tor_free(conndesc);
     732           1 :   connection_free_minimal(ENTRY_TO_CONN(ec));
     733           1 : }
     734             : 
     735             : #define TEST(name, flags)                               \
     736             :   { #name, test_cntev_ ## name, flags, 0, NULL }
     737             : 
     738             : #define T_PUBSUB(name, setup)                                           \
     739             :   { #name, test_cntev_ ## name, TT_FORK, &helper_pubsub_setup, NULL }
     740             : 
     741             : struct testcase_t controller_event_tests[] = {
     742             :   TEST(sum_up_cell_stats, TT_FORK),
     743             :   TEST(append_cell_stats, TT_FORK),
     744             :   TEST(format_cell_stats, TT_FORK),
     745             :   TEST(event_mask, TT_FORK),
     746             :   TEST(format_stream, TT_FORK),
     747             :   TEST(signal, TT_FORK),
     748             :   TEST(log_fmt, 0),
     749             :   T_PUBSUB(dirboot_defer_desc, TT_FORK),
     750             :   T_PUBSUB(dirboot_defer_orconn, TT_FORK),
     751             :   T_PUBSUB(orconn_state, TT_FORK),
     752             :   T_PUBSUB(orconn_state_pt, TT_FORK),
     753             :   T_PUBSUB(orconn_state_proxy, TT_FORK),
     754             :   END_OF_TESTCASES
     755             : };

Generated by: LCOV version 1.14