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 : };
|