1 /* Copyright (c) 2015-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
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
,
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
,
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)
74 test_conn_lookup_addr_helper(const char *address
, int family
, tor_addr_t
*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
));
89 tor_addr_make_null(addr
, TEST_CONN_FAMILY
);
93 test_conn_get_basic_setup(const struct testcase_t
*tc
)
96 return test_conn_get_connection(TEST_CONN_STATE
, TEST_CONN_TYPE
,
97 TEST_CONN_BASIC_PURPOSE
);
101 test_conn_get_basic_teardown(const struct testcase_t
*tc
, void *arg
)
104 connection_t
*conn
= arg
;
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 */
172 /* When conn == NULL, we can't cleanup anything */
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(
184 TEST_CONN_RSRC_PURPOSE
));
187 assert_connection_ok(&conn
->base_
, time(NULL
));
189 /* Replace the existing resource with the one we want */
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
));
201 test_conn_get_rsrc_teardown(NULL
, conn
);
206 test_conn_get_rsrc_setup(const struct testcase_t
*tc
)
209 return test_conn_download_status_add_a_connection(TEST_CONN_RSRC
);
213 test_conn_get_rsrc_teardown(const struct testcase_t
*tc
, void *arg
)
217 connection_t
*conn
= (connection_t
*)arg
;
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
);
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
);
240 test_conn_download_status_setup(const struct testcase_t
*tc
)
246 test_conn_download_status_teardown(const struct testcase_t
*tc
, void *arg
)
251 /* Ignore arg, and just loop through the connection array */
252 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t
*, 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
);
267 test_conn_proxy_connect_setup(const struct testcase_t
*tc
)
269 return test_conn_get_proxy_or_connection(*(unsigned int *)tc
->setup_data
);
273 test_conn_proxy_connect_teardown(const struct testcase_t
*tc
, void *arg
)
276 or_connection_t
*conn
= arg
;
279 assert_connection_ok(&conn
->base_
, time(NULL
));
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
)
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
,
297 assert_connection_ok(conn
, time(NULL
));
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
));
313 test_conn_download_status_teardown(NULL
, 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
334 test_conn_get_basic(void *arg
)
336 connection_t
*conn
= (connection_t
*)arg
;
337 tor_addr_t addr
, addr2
;
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
,
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
)
361 tt_assert(connection_get_by_type_state(TEST_CONN_TYPE
, TEST_CONN_STATE
)
363 tt_assert(connection_get_by_type_state(!conn
->type
, !conn
->state
)
365 tt_assert(connection_get_by_type_state(!TEST_CONN_TYPE
, !TEST_CONN_STATE
)
368 /* Match on the connection fields themselves */
369 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
374 /* Match on the original inputs to the connection */
375 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE
,
380 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
385 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
390 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
393 TEST_CONN_BASIC_PURPOSE
)
395 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE
,
398 TEST_CONN_BASIC_PURPOSE
)
400 /* Then try each of the not-matching combinations */
401 tt_assert(connection_get_by_type_addr_port_purpose(!conn
->type
,
406 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
411 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
416 tt_assert(connection_get_by_type_addr_port_purpose(conn
->type
,
421 /* Then try everything not-matching */
422 tt_assert(connection_get_by_type_addr_port_purpose(!conn
->type
,
427 tt_assert(connection_get_by_type_addr_port_purpose(!TEST_CONN_TYPE
,
430 !TEST_CONN_BASIC_PURPOSE
)
437 #define sl_is_conn_assert(sl_input, conn) \
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; \
445 #define sl_no_conn_assert(sl_input) \
447 the_sl = (sl_input); \
448 tt_int_op(smartlist_len((the_sl)), OP_EQ, 0); \
449 smartlist_free(the_sl); the_sl = NULL; \
453 test_conn_get_rsrc(void *arg
)
455 dir_connection_t
*conn
= DOWNCAST(dir_connection_t
, arg
);
456 smartlist_t
*the_sl
= NULL
;
458 assert_connection_ok(&conn
->base_
, time(NULL
));
460 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
462 conn
->requested_resource
),
464 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
465 TEST_CONN_RSRC_PURPOSE
,
468 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
469 !conn
->base_
.purpose
,
471 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
472 !TEST_CONN_RSRC_PURPOSE
,
475 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
477 conn
->requested_resource
,
480 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
481 TEST_CONN_RSRC_PURPOSE
,
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
,
494 tt_int_op(connection_dir_count_by_purpose_and_resource(
495 conn
->base_
.purpose
, conn
->requested_resource
),
497 tt_int_op(connection_dir_count_by_purpose_and_resource(
498 TEST_CONN_RSRC_PURPOSE
, TEST_CONN_RSRC
),
500 tt_int_op(connection_dir_count_by_purpose_and_resource(
501 !conn
->base_
.purpose
, ""),
503 tt_int_op(connection_dir_count_by_purpose_and_resource(
504 !TEST_CONN_RSRC_PURPOSE
, TEST_CONN_RSRC_2
),
507 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
508 conn
->base_
.purpose
, conn
->requested_resource
,
511 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
512 TEST_CONN_RSRC_PURPOSE
, TEST_CONN_RSRC
, TEST_CONN_STATE
),
514 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
515 !conn
->base_
.purpose
, "", !conn
->base_
.state
),
517 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
518 !TEST_CONN_RSRC_PURPOSE
, TEST_CONN_RSRC_2
, !TEST_CONN_STATE
),
522 smartlist_free(the_sl
);
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
)
542 const char *res
= networkstatus_get_flavor_name(usable_flavor
);
543 const char *other_res
= networkstatus_get_flavor_name(other_flavor
);
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
),
552 tt_int_op(connection_dir_count_by_purpose_and_resource(
553 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
564 tt_int_op(connection_dir_count_by_purpose_and_resource(
565 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
577 tt_int_op(connection_dir_count_by_purpose_and_resource(
578 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
590 tt_int_op(connection_dir_count_by_purpose_and_resource(
591 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
602 tt_int_op(connection_dir_count_by_purpose_and_resource(
603 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
614 tt_int_op(connection_dir_count_by_purpose_and_resource(
615 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
626 tt_int_op(connection_dir_count_by_purpose_and_resource(
627 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
638 tt_int_op(connection_dir_count_by_purpose_and_resource(
639 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
652 tt_int_op(connection_dir_count_by_purpose_and_resource(
653 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
664 tt_int_op(connection_dir_count_by_purpose_and_resource(
665 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
680 tt_int_op(connection_dir_count_by_purpose_and_resource(
681 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
692 tt_int_op(connection_dir_count_by_purpose_and_resource(
693 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
706 tt_int_op(connection_dir_count_by_purpose_and_resource(
707 TEST_CONN_RSRC_PURPOSE
, other_res
),
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
),
723 tt_int_op(connection_dir_count_by_purpose_and_resource(
724 TEST_CONN_RSRC_PURPOSE
, other_res
),
728 /* the teardown function removes all the connections in the global list*/;
732 test_conn_https_proxy_connect(void *arg
)
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");
746 UNMOCK(connection_or_change_state
);
750 static int handshake_start_called
= 0;
753 handshake_start(or_connection_t
*conn
, int receiving
)
759 handshake_start_called
= 1;
764 test_conn_haproxy_proxy_connect(void *arg
)
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);
784 UNMOCK(connection_or_change_state
);
785 UNMOCK(connection_tls_start_handshake
);
789 static node_t test_node
;
792 mock_node_get_mutable_by_id(const char *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;
807 static const node_t
*
808 mock_node_get_by_id(const char *digest
)
811 memset(test_node
.identity
, 'c', sizeof(test_node
.identity
));
815 /* Test whether we correctly track failed connections between relays. */
817 test_failed_orconn_tracker(void *arg
)
822 time_t now
= 1281533250; /* 2010-08-11 13:27:30 UTC */
825 update_approx_time(now
);
827 /* Prepare the OR connection that will be used in this test */
828 or_connection_t or_conn
;
829 memset(&or_conn
, 0, sizeof(or_conn
));
830 tt_int_op(AF_INET
,OP_EQ
, tor_addr_parse(&or_conn
.canonical_orport
.addr
,
832 tt_int_op(AF_INET
,OP_EQ
, tor_addr_parse(&or_conn
.base_
.addr
, "18.0.0.1"));
833 or_conn
.base_
.port
= 1;
834 memset(or_conn
.identity_digest
, 'c', sizeof(or_conn
.identity_digest
));
836 /* Check whether we can connect with an empty failure cache:
837 * this should succeed */
838 can_connect
= should_connect_to_relay(&or_conn
);
839 tt_int_op(can_connect
, OP_EQ
, 1);
841 /* Now add the destination to the failure cache */
842 note_or_connect_failed(&or_conn
);
844 /* Check again: now it shouldn't connect */
845 can_connect
= should_connect_to_relay(&or_conn
);
846 tt_int_op(can_connect
, OP_EQ
, 0);
848 /* Move time forward and check again: the cache should have been cleared and
849 * now it should connect */
851 update_approx_time(now
);
852 can_connect
= should_connect_to_relay(&or_conn
);
853 tt_int_op(can_connect
, OP_EQ
, 1);
855 /* Now mock the node_get_*by_id() functions to start using the node subsystem
857 MOCK(node_get_by_id
, mock_node_get_by_id
);
858 MOCK(node_get_mutable_by_id
, mock_node_get_mutable_by_id
);
860 /* Since we just started using the node subsystem it will allow connections
862 can_connect
= should_connect_to_relay(&or_conn
);
863 tt_int_op(can_connect
, OP_EQ
, 1);
865 /* Mark it as failed */
866 note_or_connect_failed(&or_conn
);
868 /* Check that it shouldn't connect now */
869 can_connect
= should_connect_to_relay(&or_conn
);
870 tt_int_op(can_connect
, OP_EQ
, 0);
872 /* Move time forward and check again: now it should connect */
874 update_approx_time(now
);
875 can_connect
= should_connect_to_relay(&or_conn
);
876 tt_int_op(can_connect
, OP_EQ
, 1);
883 test_conn_describe(void *arg
)
886 or_options_t
*options
= get_options_mutable();
887 options
->SafeLogging_
= SAFELOG_SCRUB_ALL
;
889 // Let's start with a listener connection since they're simple.
890 connection_t
*conn
= connection_new(CONN_TYPE_OR_LISTENER
, AF_INET
);
891 tor_addr_parse(&conn
->addr
, "44.22.11.11");
893 tt_str_op(connection_describe(conn
), OP_EQ
,
894 "OR listener connection (ready) on 44.22.11.11:80");
895 // If the address is unspec, we should still work.
896 tor_addr_make_unspec(&conn
->addr
);
897 tt_str_op(connection_describe(conn
), OP_EQ
,
898 "OR listener connection (ready) on <unset>:80");
899 // Try making the address null.
900 tor_addr_make_null(&conn
->addr
, AF_INET
);
901 tt_str_op(connection_describe(conn
), OP_EQ
,
902 "OR listener connection (ready) on 0.0.0.0:80");
903 // What if the address is uninitialized? (This can happen if we log about the
904 // connection before we set the address.)
905 memset(&conn
->addr
, 0, sizeof(conn
->addr
));
906 tt_str_op(connection_describe(conn
), OP_EQ
,
907 "OR listener connection (ready) on <unset>:80");
908 connection_free_minimal(conn
);
910 // Try a unix socket.
911 conn
= connection_new(CONN_TYPE_CONTROL_LISTENER
, AF_UNIX
);
912 conn
->address
= tor_strdup("/a/path/that/could/exist");
913 tt_str_op(connection_describe(conn
), OP_EQ
,
914 "Control listener connection (ready) on /a/path/that/could/exist");
915 connection_free_minimal(conn
);
917 // Try an IPv6 address.
918 conn
= connection_new(CONN_TYPE_AP_LISTENER
, AF_INET6
);
919 tor_addr_parse(&conn
->addr
, "ff00::3");
921 tt_str_op(connection_describe(conn
), OP_EQ
,
922 "Socks listener connection (ready) on [ff00::3]:9050");
923 connection_free_minimal(conn
);
925 // Now let's mess with exit connections. They have some special issues.
926 options
->SafeLogging_
= SAFELOG_SCRUB_NONE
;
927 conn
= connection_new(CONN_TYPE_EXIT
, AF_INET
);
928 // If address and state are unset, we should say SOMETHING.
929 tt_str_op(connection_describe(conn
), OP_EQ
,
930 "Exit connection (uninitialized) to <unset> (DNS lookup pending)");
931 // Now suppose that the address is set but we haven't resolved the hostname.
933 conn
->address
= tor_strdup("www.torproject.org");
934 conn
->state
= EXIT_CONN_STATE_RESOLVING
;
935 tt_str_op(connection_describe(conn
), OP_EQ
,
936 "Exit connection (waiting for dest info) to "
937 "www.torproject.org:443 (DNS lookup pending)");
938 // Now give it a hostname!
939 tor_addr_parse(&conn
->addr
, "192.168.8.8");
940 conn
->state
= EXIT_CONN_STATE_OPEN
;
941 tt_str_op(connection_describe(conn
), OP_EQ
,
942 "Exit connection (open) to 192.168.8.8:443");
943 // But what if safelogging is on?
944 options
->SafeLogging_
= SAFELOG_SCRUB_RELAY
;
945 tt_str_op(connection_describe(conn
), OP_EQ
,
946 "Exit connection (open) to [scrubbed]");
947 connection_free_minimal(conn
);
949 // Now at last we look at OR addresses, which are complicated.
950 conn
= connection_new(CONN_TYPE_OR
, AF_INET6
);
951 conn
->state
= OR_CONN_STATE_OPEN
;
953 tor_addr_parse(&conn
->addr
, "[ffff:3333:1111::2]");
954 // This should get scrubbed, since the lack of a set ID means we might be
955 // talking to a client.
956 tt_str_op(connection_describe(conn
), OP_EQ
,
957 "OR connection (open) with [scrubbed]");
958 // But now suppose we aren't safelogging? We'll get the address then.
959 options
->SafeLogging_
= SAFELOG_SCRUB_NONE
;
960 tt_str_op(connection_describe(conn
), OP_EQ
,
961 "OR connection (open) with [ffff:3333:1111::2]:8080");
962 // Suppose we have an ID, so we know it isn't a client.
963 TO_OR_CONN(conn
)->identity_digest
[3] = 7;
964 options
->SafeLogging_
= SAFELOG_SCRUB_RELAY
; // back to safelogging.
965 tt_str_op(connection_describe(conn
), OP_EQ
,
966 "OR connection (open) with [ffff:3333:1111::2]:8080 "
967 "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
968 // Add a 'canonical address' that is the same as the one we have.
969 tor_addr_parse(&TO_OR_CONN(conn
)->canonical_orport
.addr
,
970 "[ffff:3333:1111::2]");
971 TO_OR_CONN(conn
)->canonical_orport
.port
= 8080;
972 tt_str_op(connection_describe(conn
), OP_EQ
,
973 "OR connection (open) with [ffff:3333:1111::2]:8080 "
974 "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
975 // Add a different 'canonical address'
976 tor_addr_parse(&TO_OR_CONN(conn
)->canonical_orport
.addr
,
977 "[ffff:3333:1111::8]");
978 tt_str_op(connection_describe(conn
), OP_EQ
,
979 "OR connection (open) with [ffff:3333:1111::2]:8080 "
980 "ID=<none> RSA_ID=0000000700000000000000000000000000000000 "
981 "canonical_addr=[ffff:3333:1111::8]:8080");
983 // Clear identity_digest so that free_minimal won't complain.
984 memset(TO_OR_CONN(conn
)->identity_digest
, 0, DIGEST_LEN
);
987 connection_free_minimal(conn
);
991 #define CONNECTION_TESTCASE(name, fork, setup) \
992 { #name, test_conn_##name, fork, &setup, NULL }
995 /* where arg is an expression (constant, variable, compound expression) */
996 #define CONNECTION_TESTCASE_ARG(name, extra, fork, setup, arg) \
997 { STR(name)"/"extra, \
1002 #endif /* !defined(COCCI) */
1004 static const unsigned int PROXY_CONNECT_ARG
= PROXY_CONNECT
;
1005 static const unsigned int PROXY_HAPROXY_ARG
= PROXY_HAPROXY
;
1007 struct testcase_t connection_tests
[] = {
1008 CONNECTION_TESTCASE(get_basic
, TT_FORK
, test_conn_get_basic_st
),
1009 CONNECTION_TESTCASE(get_rsrc
, TT_FORK
, test_conn_get_rsrc_st
),
1011 CONNECTION_TESTCASE_ARG(download_status
, "microdesc", TT_FORK
,
1012 test_conn_download_status_st
, "microdesc"),
1013 CONNECTION_TESTCASE_ARG(download_status
, "ns", TT_FORK
,
1014 test_conn_download_status_st
, "ns"),
1016 CONNECTION_TESTCASE_ARG(https_proxy_connect
, "https", TT_FORK
,
1017 test_conn_proxy_connect_st
, &PROXY_CONNECT_ARG
),
1018 CONNECTION_TESTCASE_ARG(haproxy_proxy_connect
, "haproxy", TT_FORK
,
1019 test_conn_proxy_connect_st
, &PROXY_HAPROXY_ARG
),
1021 //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
1022 { "failed_orconn_tracker", test_failed_orconn_tracker
, TT_FORK
, NULL
, NULL
},
1023 { "describe", test_conn_describe
, TT_FORK
, NULL
, NULL
},