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