tor

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

test_controller_events.c (26605B)


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