Merge branch 'maint-0.4.8'
[tor.git] / src / test / test_connection.c
blobed94fe8aaa4e482b9548ca85f98e3ffccf21957e
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"
25 #include "lib/evloop/compat_libevent.h"
27 #include "test/test_connection.h"
28 #include "test/test_helpers.h"
30 #include "feature/dircommon/dir_connection_st.h"
31 #include "core/or/entry_connection_st.h"
32 #include "feature/nodelist/node_st.h"
33 #include "core/or/or_connection_st.h"
34 #include "feature/nodelist/routerinfo_st.h"
35 #include "core/or/socks_request_st.h"
37 static void * test_conn_get_basic_setup(const struct testcase_t *tc);
38 static int test_conn_get_basic_teardown(const struct testcase_t *tc,
39 void *arg);
41 static void * test_conn_get_rsrc_setup(const struct testcase_t *tc);
42 static int test_conn_get_rsrc_teardown(const struct testcase_t *tc,
43 void *arg);
45 /* Arbitrary choice - IPv4 Directory Connection to localhost */
46 #define TEST_CONN_TYPE (CONN_TYPE_DIR)
47 /* We assume every machine has IPv4 localhost, is that ok? */
48 #define TEST_CONN_ADDRESS "127.0.0.1"
49 #define TEST_CONN_PORT (12345)
50 #define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345"
51 #define TEST_CONN_FAMILY (AF_INET)
52 #define TEST_CONN_STATE (DIR_CONN_STATE_MIN_)
53 #define TEST_CONN_ADDRESS_2 "127.0.0.2"
55 #define TEST_CONN_BASIC_PURPOSE (DIR_PURPOSE_MIN_)
57 #define TEST_CONN_REND_ADDR "cfs3rltphxxvabci"
58 #define TEST_CONN_REND_PURPOSE (DIR_PURPOSE_FETCH_RENDDESC_V2)
59 #define TEST_CONN_REND_PURPOSE_SUCCESSFUL (DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2)
60 #define TEST_CONN_REND_TYPE_2 (CONN_TYPE_AP)
61 #define TEST_CONN_REND_ADDR_2 "icbavxxhptlr3sfc"
63 #define TEST_CONN_RSRC (networkstatus_get_flavor_name(FLAV_MICRODESC))
64 #define TEST_CONN_RSRC_PURPOSE (DIR_PURPOSE_FETCH_CONSENSUS)
65 #define TEST_CONN_RSRC_STATE_SUCCESSFUL (DIR_CONN_STATE_CLIENT_FINISHED)
66 #define TEST_CONN_RSRC_2 (networkstatus_get_flavor_name(FLAV_NS))
68 #define TEST_CONN_DL_STATE (DIR_CONN_STATE_CLIENT_READING)
70 /* see AP_CONN_STATE_IS_UNATTACHED() */
71 #define TEST_CONN_UNATTACHED_STATE (AP_CONN_STATE_CIRCUIT_WAIT)
72 #define TEST_CONN_ATTACHED_STATE (AP_CONN_STATE_CONNECT_WAIT)
74 void
75 test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr)
77 int rv = 0;
79 tt_assert(addr);
81 rv = tor_addr_lookup(address, family, addr);
82 /* XXXX - should we retry on transient failure? */
83 tt_int_op(rv, OP_EQ, 0);
84 tt_assert(tor_addr_is_loopback(addr));
85 tt_assert(tor_addr_is_v4(addr));
87 return;
89 done:
90 tor_addr_make_null(addr, TEST_CONN_FAMILY);
93 static void *
94 test_conn_get_basic_setup(const struct testcase_t *tc)
96 (void)tc;
97 return test_conn_get_connection(TEST_CONN_STATE, TEST_CONN_TYPE,
98 TEST_CONN_BASIC_PURPOSE);
101 static int
102 test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg)
104 (void)tc;
105 connection_t *conn = arg;
107 tt_assert(conn);
108 assert_connection_ok(conn, time(NULL));
110 /* teardown the connection as fast as possible */
111 if (conn->linked_conn) {
112 assert_connection_ok(conn->linked_conn, time(NULL));
114 /* We didn't call tor_libevent_initialize(), so event_base was NULL,
115 * so we can't rely on connection_unregister_events() use of event_del().
117 tor_event_free(conn->linked_conn->read_event);
118 tor_event_free(conn->linked_conn->write_event);
120 if (!conn->linked_conn->marked_for_close) {
121 connection_close_immediate(conn->linked_conn);
122 if (CONN_IS_EDGE(conn->linked_conn)) {
123 /* Suppress warnings about all the stuff we didn't do */
124 TO_EDGE_CONN(conn->linked_conn)->edge_has_sent_end = 1;
125 TO_EDGE_CONN(conn->linked_conn)->end_reason =
126 END_STREAM_REASON_INTERNAL;
127 if (conn->linked_conn->type == CONN_TYPE_AP) {
128 TO_ENTRY_CONN(conn->linked_conn)->socks_request->has_finished = 1;
131 connection_mark_for_close(conn->linked_conn);
134 close_closeable_connections();
137 /* We didn't set the events up properly, so we can't use event_del() in
138 * close_closeable_connections() > connection_free()
139 * > connection_unregister_events() */
140 tor_event_free(conn->read_event);
141 tor_event_free(conn->write_event);
143 if (!conn->marked_for_close) {
144 connection_close_immediate(conn);
145 if (CONN_IS_EDGE(conn)) {
146 /* Suppress warnings about all the stuff we didn't do */
147 TO_EDGE_CONN(conn)->edge_has_sent_end = 1;
148 TO_EDGE_CONN(conn)->end_reason = END_STREAM_REASON_INTERNAL;
149 if (conn->type == CONN_TYPE_AP) {
150 TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
153 connection_mark_for_close(conn);
156 close_closeable_connections();
158 /* The unit test will fail if we return 0 */
159 return 1;
161 /* When conn == NULL, we can't cleanup anything */
162 done:
163 return 0;
166 static dir_connection_t *
167 test_conn_download_status_add_a_connection(const char *resource)
169 dir_connection_t *conn = DOWNCAST(dir_connection_t,
170 test_conn_get_connection(
171 TEST_CONN_STATE,
172 TEST_CONN_TYPE,
173 TEST_CONN_RSRC_PURPOSE));
175 tt_assert(conn);
176 assert_connection_ok(&conn->base_, time(NULL));
178 /* Replace the existing resource with the one we want */
179 if (resource) {
180 if (conn->requested_resource) {
181 tor_free(conn->requested_resource);
183 conn->requested_resource = tor_strdup(resource);
184 assert_connection_ok(&conn->base_, time(NULL));
187 return conn;
189 done:
190 test_conn_get_rsrc_teardown(NULL, conn);
191 return NULL;
194 static void *
195 test_conn_get_rsrc_setup(const struct testcase_t *tc)
197 (void)tc;
198 return test_conn_download_status_add_a_connection(TEST_CONN_RSRC);
201 static int
202 test_conn_get_rsrc_teardown(const struct testcase_t *tc, void *arg)
204 int rv = 0;
206 connection_t *conn = (connection_t *)arg;
207 tt_assert(conn);
208 assert_connection_ok(conn, time(NULL));
210 if (conn->type == CONN_TYPE_DIR) {
211 dir_connection_t *dir_conn = DOWNCAST(dir_connection_t, arg);
213 tt_assert(dir_conn);
214 assert_connection_ok(&dir_conn->base_, time(NULL));
216 /* avoid a last-ditch attempt to refetch the consensus */
217 dir_conn->base_.state = TEST_CONN_RSRC_STATE_SUCCESSFUL;
218 assert_connection_ok(&dir_conn->base_, time(NULL));
221 /* connection_free_() cleans up requested_resource */
222 rv = test_conn_get_basic_teardown(tc, conn);
224 done:
225 return rv;
228 static void *
229 test_conn_download_status_setup(const struct testcase_t *tc)
231 return (void*)tc;
234 static int
235 test_conn_download_status_teardown(const struct testcase_t *tc, void *arg)
237 (void)arg;
238 int rv = 0;
240 /* Ignore arg, and just loop through the connection array */
241 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
242 if (conn) {
243 assert_connection_ok(conn, time(NULL));
245 /* connection_free_() cleans up requested_resource */
246 rv = test_conn_get_rsrc_teardown(tc, conn);
247 tt_int_op(rv, OP_EQ, 1);
249 } SMARTLIST_FOREACH_END(conn);
251 done:
252 return rv;
255 static void *
256 test_conn_proxy_connect_setup(const struct testcase_t *tc)
258 return test_conn_get_proxy_or_connection(*(unsigned int *)tc->setup_data);
261 static int
262 test_conn_proxy_connect_teardown(const struct testcase_t *tc, void *arg)
264 (void)tc;
265 or_connection_t *conn = arg;
267 tt_assert(conn);
268 assert_connection_ok(&conn->base_, time(NULL));
270 done:
271 return 1;
274 /* Like connection_ap_make_link(), but does much less */
275 static connection_t *
276 test_conn_get_linked_connection(connection_t *l_conn, uint8_t state)
278 tt_assert(l_conn);
279 assert_connection_ok(l_conn, time(NULL));
281 /* AP connections don't seem to have purposes */
282 connection_t *conn = test_conn_get_connection(state, CONN_TYPE_AP,
285 tt_assert(conn);
286 assert_connection_ok(conn, time(NULL));
288 conn->linked = 1;
289 l_conn->linked = 1;
290 conn->linked_conn = l_conn;
291 l_conn->linked_conn = conn;
292 /* we never opened a real socket, so we can just overwrite it */
293 conn->s = TOR_INVALID_SOCKET;
294 l_conn->s = TOR_INVALID_SOCKET;
296 assert_connection_ok(conn, time(NULL));
297 assert_connection_ok(l_conn, time(NULL));
299 return conn;
301 done:
302 test_conn_download_status_teardown(NULL, NULL);
303 return NULL;
306 static struct testcase_setup_t test_conn_get_basic_st = {
307 test_conn_get_basic_setup, test_conn_get_basic_teardown
310 static struct testcase_setup_t test_conn_get_rsrc_st = {
311 test_conn_get_rsrc_setup, test_conn_get_rsrc_teardown
314 static struct testcase_setup_t test_conn_download_status_st = {
315 test_conn_download_status_setup, test_conn_download_status_teardown
318 static struct testcase_setup_t test_conn_proxy_connect_st = {
319 test_conn_proxy_connect_setup, test_conn_proxy_connect_teardown
322 static void
323 test_conn_get_basic(void *arg)
325 connection_t *conn = (connection_t*)arg;
326 tor_addr_t addr, addr2;
328 tt_assert(conn);
329 assert_connection_ok(conn, time(NULL));
331 test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &addr);
332 tt_assert(!tor_addr_is_null(&addr));
333 test_conn_lookup_addr_helper(TEST_CONN_ADDRESS_2, TEST_CONN_FAMILY, &addr2);
334 tt_assert(!tor_addr_is_null(&addr2));
336 /* Check that we get this connection back when we search for it by
337 * its attributes, but get NULL when we supply a different value. */
339 tt_assert(connection_get_by_global_id(conn->global_identifier) == conn);
340 tt_ptr_op(connection_get_by_global_id(!conn->global_identifier), OP_EQ,
341 NULL);
343 tt_assert(connection_get_by_type(conn->type) == conn);
344 tt_assert(connection_get_by_type(TEST_CONN_TYPE) == conn);
345 tt_ptr_op(connection_get_by_type(!conn->type), OP_EQ, NULL);
346 tt_ptr_op(connection_get_by_type(!TEST_CONN_TYPE), OP_EQ, NULL);
348 tt_assert(connection_get_by_type_state(conn->type, conn->state)
349 == conn);
350 tt_assert(connection_get_by_type_state(TEST_CONN_TYPE, TEST_CONN_STATE)
351 == conn);
352 tt_assert(connection_get_by_type_state(!conn->type, !conn->state)
353 == NULL);
354 tt_assert(connection_get_by_type_state(!TEST_CONN_TYPE, !TEST_CONN_STATE)
355 == NULL);
357 /* Match on the connection fields themselves */
358 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
359 &conn->addr,
360 conn->port,
361 conn->purpose)
362 == conn);
363 /* Match on the original inputs to the connection */
364 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE,
365 &conn->addr,
366 conn->port,
367 conn->purpose)
368 == conn);
369 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
370 &addr,
371 conn->port,
372 conn->purpose)
373 == conn);
374 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
375 &conn->addr,
376 TEST_CONN_PORT,
377 conn->purpose)
378 == conn);
379 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
380 &conn->addr,
381 conn->port,
382 TEST_CONN_BASIC_PURPOSE)
383 == conn);
384 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE,
385 &addr,
386 TEST_CONN_PORT,
387 TEST_CONN_BASIC_PURPOSE)
388 == conn);
389 /* Then try each of the not-matching combinations */
390 tt_assert(connection_get_by_type_addr_port_purpose(!conn->type,
391 &conn->addr,
392 conn->port,
393 conn->purpose)
394 == NULL);
395 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
396 &addr2,
397 conn->port,
398 conn->purpose)
399 == NULL);
400 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
401 &conn->addr,
402 !conn->port,
403 conn->purpose)
404 == NULL);
405 tt_assert(connection_get_by_type_addr_port_purpose(conn->type,
406 &conn->addr,
407 conn->port,
408 !conn->purpose)
409 == NULL);
410 /* Then try everything not-matching */
411 tt_assert(connection_get_by_type_addr_port_purpose(!conn->type,
412 &addr2,
413 !conn->port,
414 !conn->purpose)
415 == NULL);
416 tt_assert(connection_get_by_type_addr_port_purpose(!TEST_CONN_TYPE,
417 &addr2,
418 !TEST_CONN_PORT,
419 !TEST_CONN_BASIC_PURPOSE)
420 == NULL);
422 done:
426 #define sl_is_conn_assert(sl_input, conn) \
427 do { \
428 the_sl = (sl_input); \
429 tt_int_op(smartlist_len((the_sl)), OP_EQ, 1); \
430 tt_assert(smartlist_get((the_sl), 0) == (conn)); \
431 smartlist_free(the_sl); the_sl = NULL; \
432 } while (0)
434 #define sl_no_conn_assert(sl_input) \
435 do { \
436 the_sl = (sl_input); \
437 tt_int_op(smartlist_len((the_sl)), OP_EQ, 0); \
438 smartlist_free(the_sl); the_sl = NULL; \
439 } while (0)
441 static void
442 test_conn_get_rsrc(void *arg)
444 dir_connection_t *conn = DOWNCAST(dir_connection_t, arg);
445 smartlist_t *the_sl = NULL;
446 tt_assert(conn);
447 assert_connection_ok(&conn->base_, time(NULL));
449 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
450 conn->base_.purpose,
451 conn->requested_resource),
452 conn);
453 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource(
454 TEST_CONN_RSRC_PURPOSE,
455 TEST_CONN_RSRC),
456 conn);
457 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
458 !conn->base_.purpose,
459 ""));
460 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource(
461 !TEST_CONN_RSRC_PURPOSE,
462 TEST_CONN_RSRC_2));
464 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
465 conn->base_.purpose,
466 conn->requested_resource,
467 conn->base_.state),
468 conn);
469 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state(
470 TEST_CONN_RSRC_PURPOSE,
471 TEST_CONN_RSRC,
472 TEST_CONN_STATE),
473 conn);
474 sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state(
475 !conn->base_.purpose,
477 !conn->base_.state));
478 sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state(
479 !TEST_CONN_RSRC_PURPOSE,
480 TEST_CONN_RSRC_2,
481 !TEST_CONN_STATE));
483 tt_int_op(connection_dir_count_by_purpose_and_resource(
484 conn->base_.purpose, conn->requested_resource),
485 OP_EQ, 1);
486 tt_int_op(connection_dir_count_by_purpose_and_resource(
487 TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC),
488 OP_EQ, 1);
489 tt_int_op(connection_dir_count_by_purpose_and_resource(
490 !conn->base_.purpose, ""),
491 OP_EQ, 0);
492 tt_int_op(connection_dir_count_by_purpose_and_resource(
493 !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2),
494 OP_EQ, 0);
496 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
497 conn->base_.purpose, conn->requested_resource,
498 conn->base_.state),
499 OP_EQ, 1);
500 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
501 TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC, TEST_CONN_STATE),
502 OP_EQ, 1);
503 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
504 !conn->base_.purpose, "", !conn->base_.state),
505 OP_EQ, 0);
506 tt_int_op(connection_dir_count_by_purpose_resource_and_state(
507 !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2, !TEST_CONN_STATE),
508 OP_EQ, 0);
510 done:
511 smartlist_free(the_sl);
514 static void
515 test_conn_download_status(void *arg)
517 dir_connection_t *conn = NULL;
518 dir_connection_t *conn2 = NULL;
519 dir_connection_t *conn4 = NULL;
520 connection_t *ap_conn = NULL;
522 const struct testcase_t *tc = arg;
523 consensus_flavor_t usable_flavor =
524 networkstatus_parse_flavor_name((const char*) tc->setup_data);
526 /* The "other flavor" trick only works if there are two flavors */
527 tor_assert(N_CONSENSUS_FLAVORS == 2);
528 consensus_flavor_t other_flavor = ((usable_flavor == FLAV_NS)
529 ? FLAV_MICRODESC
530 : FLAV_NS);
531 const char *res = networkstatus_get_flavor_name(usable_flavor);
532 const char *other_res = networkstatus_get_flavor_name(other_flavor);
534 /* no connections */
535 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
536 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
538 tt_int_op(connection_dir_count_by_purpose_and_resource(
539 TEST_CONN_RSRC_PURPOSE, res),
540 OP_EQ, 0);
541 tt_int_op(connection_dir_count_by_purpose_and_resource(
542 TEST_CONN_RSRC_PURPOSE, other_res),
543 OP_EQ, 0);
545 /* one connection, not downloading */
546 conn = test_conn_download_status_add_a_connection(res);
547 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
548 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
550 tt_int_op(connection_dir_count_by_purpose_and_resource(
551 TEST_CONN_RSRC_PURPOSE, res),
552 OP_EQ, 1);
553 tt_int_op(connection_dir_count_by_purpose_and_resource(
554 TEST_CONN_RSRC_PURPOSE, other_res),
555 OP_EQ, 0);
557 /* one connection, downloading but not linked (not possible on a client,
558 * but possible on a relay) */
559 conn->base_.state = TEST_CONN_DL_STATE;
560 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
561 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
563 tt_int_op(connection_dir_count_by_purpose_and_resource(
564 TEST_CONN_RSRC_PURPOSE, res),
565 OP_EQ, 1);
566 tt_int_op(connection_dir_count_by_purpose_and_resource(
567 TEST_CONN_RSRC_PURPOSE, other_res),
568 OP_EQ, 0);
570 /* one connection, downloading and linked, but not yet attached */
571 ap_conn = test_conn_get_linked_connection(TO_CONN(conn),
572 TEST_CONN_UNATTACHED_STATE);
573 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
574 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
576 tt_int_op(connection_dir_count_by_purpose_and_resource(
577 TEST_CONN_RSRC_PURPOSE, res),
578 OP_EQ, 1);
579 tt_int_op(connection_dir_count_by_purpose_and_resource(
580 TEST_CONN_RSRC_PURPOSE, other_res),
581 OP_EQ, 0);
583 /* one connection, downloading and linked and attached */
584 ap_conn->state = TEST_CONN_ATTACHED_STATE;
585 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
586 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
588 tt_int_op(connection_dir_count_by_purpose_and_resource(
589 TEST_CONN_RSRC_PURPOSE, res),
590 OP_EQ, 1);
591 tt_int_op(connection_dir_count_by_purpose_and_resource(
592 TEST_CONN_RSRC_PURPOSE, other_res),
593 OP_EQ, 0);
595 /* one connection, linked and attached but not downloading */
596 conn->base_.state = TEST_CONN_STATE;
597 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
598 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
600 tt_int_op(connection_dir_count_by_purpose_and_resource(
601 TEST_CONN_RSRC_PURPOSE, res),
602 OP_EQ, 1);
603 tt_int_op(connection_dir_count_by_purpose_and_resource(
604 TEST_CONN_RSRC_PURPOSE, other_res),
605 OP_EQ, 0);
607 /* two connections, both not downloading */
608 conn2 = test_conn_download_status_add_a_connection(res);
609 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
610 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
612 tt_int_op(connection_dir_count_by_purpose_and_resource(
613 TEST_CONN_RSRC_PURPOSE, res),
614 OP_EQ, 2);
615 tt_int_op(connection_dir_count_by_purpose_and_resource(
616 TEST_CONN_RSRC_PURPOSE, other_res),
617 OP_EQ, 0);
619 /* two connections, one downloading */
620 conn->base_.state = TEST_CONN_DL_STATE;
621 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
622 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
624 tt_int_op(connection_dir_count_by_purpose_and_resource(
625 TEST_CONN_RSRC_PURPOSE, res),
626 OP_EQ, 2);
627 tt_int_op(connection_dir_count_by_purpose_and_resource(
628 TEST_CONN_RSRC_PURPOSE, other_res),
629 OP_EQ, 0);
630 conn->base_.state = TEST_CONN_STATE;
632 /* more connections, all not downloading */
633 /* ignore the return value, it's free'd using the connection list */
634 (void)test_conn_download_status_add_a_connection(res);
635 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0);
636 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
638 tt_int_op(connection_dir_count_by_purpose_and_resource(
639 TEST_CONN_RSRC_PURPOSE, res),
640 OP_EQ, 3);
641 tt_int_op(connection_dir_count_by_purpose_and_resource(
642 TEST_CONN_RSRC_PURPOSE, other_res),
643 OP_EQ, 0);
645 /* more connections, one downloading */
646 conn->base_.state = TEST_CONN_DL_STATE;
647 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
648 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
650 tt_int_op(connection_dir_count_by_purpose_and_resource(
651 TEST_CONN_RSRC_PURPOSE, res),
652 OP_EQ, 3);
653 tt_int_op(connection_dir_count_by_purpose_and_resource(
654 TEST_CONN_RSRC_PURPOSE, other_res),
655 OP_EQ, 0);
657 /* more connections, two downloading (should never happen, but needs
658 * to be tested for completeness) */
659 conn2->base_.state = TEST_CONN_DL_STATE;
660 /* ignore the return value, it's free'd using the connection list */
661 (void)test_conn_get_linked_connection(TO_CONN(conn2),
662 TEST_CONN_ATTACHED_STATE);
663 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
664 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
666 tt_int_op(connection_dir_count_by_purpose_and_resource(
667 TEST_CONN_RSRC_PURPOSE, res),
668 OP_EQ, 3);
669 tt_int_op(connection_dir_count_by_purpose_and_resource(
670 TEST_CONN_RSRC_PURPOSE, other_res),
671 OP_EQ, 0);
672 conn->base_.state = TEST_CONN_STATE;
674 /* more connections, a different one downloading */
675 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
676 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
678 tt_int_op(connection_dir_count_by_purpose_and_resource(
679 TEST_CONN_RSRC_PURPOSE, res),
680 OP_EQ, 3);
681 tt_int_op(connection_dir_count_by_purpose_and_resource(
682 TEST_CONN_RSRC_PURPOSE, other_res),
683 OP_EQ, 0);
685 /* a connection for the other flavor (could happen if a client is set to
686 * cache directory documents), one preferred flavor downloading
688 conn4 = test_conn_download_status_add_a_connection(other_res);
689 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
690 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
692 tt_int_op(connection_dir_count_by_purpose_and_resource(
693 TEST_CONN_RSRC_PURPOSE, res),
694 OP_EQ, 3);
695 tt_int_op(connection_dir_count_by_purpose_and_resource(
696 TEST_CONN_RSRC_PURPOSE, other_res),
697 OP_EQ, 1);
699 /* a connection for the other flavor (could happen if a client is set to
700 * cache directory documents), both flavors downloading
702 conn4->base_.state = TEST_CONN_DL_STATE;
703 /* ignore the return value, it's free'd using the connection list */
704 (void)test_conn_get_linked_connection(TO_CONN(conn4),
705 TEST_CONN_ATTACHED_STATE);
706 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1);
707 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ,
709 tt_int_op(connection_dir_count_by_purpose_and_resource(
710 TEST_CONN_RSRC_PURPOSE, res),
711 OP_EQ, 3);
712 tt_int_op(connection_dir_count_by_purpose_and_resource(
713 TEST_CONN_RSRC_PURPOSE, other_res),
714 OP_EQ, 1);
716 done:
717 /* the teardown function removes all the connections in the global list*/;
720 static void
721 test_conn_https_proxy_connect(void *arg)
723 size_t sz;
724 char *buf = NULL;
725 or_connection_t *conn = arg;
727 MOCK(connection_or_change_state, mock_connection_or_change_state);
729 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HTTPS_WANT_CONNECT_OK);
731 buf = buf_get_contents(conn->base_.outbuf, &sz);
732 tt_str_op(buf, OP_EQ, "CONNECT 127.0.0.1:12345 HTTP/1.0\r\n\r\n");
734 done:
735 UNMOCK(connection_or_change_state);
736 tor_free(buf);
739 static int handshake_start_called = 0;
741 static int
742 handshake_start(or_connection_t *conn, int receiving)
744 (void)receiving;
746 tor_assert(conn);
748 handshake_start_called = 1;
749 return 0;
752 static void
753 test_conn_haproxy_proxy_connect(void *arg)
755 size_t sz;
756 char *buf = NULL;
757 or_connection_t *conn = arg;
759 MOCK(connection_or_change_state, mock_connection_or_change_state);
760 MOCK(connection_tls_start_handshake, handshake_start);
762 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HAPROXY_WAIT_FOR_FLUSH);
764 buf = buf_get_contents(conn->base_.outbuf, &sz);
765 tt_str_op(buf, OP_EQ, "PROXY TCP4 0.0.0.0 127.0.0.1 0 12345\r\n");
767 connection_or_finished_flushing(conn);
769 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_CONNECTED);
770 tt_int_op(handshake_start_called, OP_EQ, 1);
772 done:
773 UNMOCK(connection_or_change_state);
774 UNMOCK(connection_tls_start_handshake);
775 tor_free(buf);
778 static node_t test_node;
780 static node_t *
781 mock_node_get_mutable_by_id(const char *digest)
783 (void) digest;
784 static routerinfo_t node_ri;
785 memset(&node_ri, 0, sizeof(node_ri));
787 test_node.ri = &node_ri;
788 memset(test_node.identity, 'c', sizeof(test_node.identity));
790 tor_addr_parse(&node_ri.ipv4_addr, "18.0.0.1");
791 node_ri.ipv4_orport = 1;
793 return &test_node;
796 static const node_t *
797 mock_node_get_by_id(const char *digest)
799 (void) digest;
800 memset(test_node.identity, 'c', sizeof(test_node.identity));
801 return &test_node;
804 /* Test whether we correctly track failed connections between relays. */
805 static void
806 test_failed_orconn_tracker(void *arg)
808 (void) arg;
810 int can_connect;
811 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
812 (void) now;
814 update_approx_time(now);
816 /* Prepare the OR connection that will be used in this test */
817 or_connection_t or_conn;
818 memset(&or_conn, 0, sizeof(or_conn));
819 tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.canonical_orport.addr,
820 "18.0.0.1"));
821 tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1"));
822 or_conn.base_.port = 1;
823 memset(or_conn.identity_digest, 'c', sizeof(or_conn.identity_digest));
825 /* Check whether we can connect with an empty failure cache:
826 * this should succeed */
827 can_connect = should_connect_to_relay(&or_conn);
828 tt_int_op(can_connect, OP_EQ, 1);
830 /* Now add the destination to the failure cache */
831 note_or_connect_failed(&or_conn);
833 /* Check again: now it shouldn't connect */
834 can_connect = should_connect_to_relay(&or_conn);
835 tt_int_op(can_connect, OP_EQ, 0);
837 /* Move time forward and check again: the cache should have been cleared and
838 * now it should connect */
839 now += 3600;
840 update_approx_time(now);
841 can_connect = should_connect_to_relay(&or_conn);
842 tt_int_op(can_connect, OP_EQ, 1);
844 /* Now mock the node_get_*by_id() functions to start using the node subsystem
845 * optimization. */
846 MOCK(node_get_by_id, mock_node_get_by_id);
847 MOCK(node_get_mutable_by_id, mock_node_get_mutable_by_id);
849 /* Since we just started using the node subsystem it will allow connections
850 * now */
851 can_connect = should_connect_to_relay(&or_conn);
852 tt_int_op(can_connect, OP_EQ, 1);
854 /* Mark it as failed */
855 note_or_connect_failed(&or_conn);
857 /* Check that it shouldn't connect now */
858 can_connect = should_connect_to_relay(&or_conn);
859 tt_int_op(can_connect, OP_EQ, 0);
861 /* Move time forward and check again: now it should connect */
862 now += 3600;
863 update_approx_time(now);
864 can_connect = should_connect_to_relay(&or_conn);
865 tt_int_op(can_connect, OP_EQ, 1);
867 done:
871 static void
872 test_conn_describe(void *arg)
874 (void)arg;
875 or_options_t *options = get_options_mutable();
876 options->SafeLogging_ = SAFELOG_SCRUB_ALL;
878 // Let's start with a listener connection since they're simple.
879 connection_t *conn = connection_new(CONN_TYPE_OR_LISTENER, AF_INET);
880 tor_addr_parse(&conn->addr, "44.22.11.11");
881 conn->port = 80;
882 tt_str_op(connection_describe(conn), OP_EQ,
883 "OR listener connection (ready) on 44.22.11.11:80");
884 // If the address is unspec, we should still work.
885 tor_addr_make_unspec(&conn->addr);
886 tt_str_op(connection_describe(conn), OP_EQ,
887 "OR listener connection (ready) on <unset>:80");
888 // Try making the address null.
889 tor_addr_make_null(&conn->addr, AF_INET);
890 tt_str_op(connection_describe(conn), OP_EQ,
891 "OR listener connection (ready) on 0.0.0.0:80");
892 // What if the address is uninitialized? (This can happen if we log about the
893 // connection before we set the address.)
894 memset(&conn->addr, 0, sizeof(conn->addr));
895 tt_str_op(connection_describe(conn), OP_EQ,
896 "OR listener connection (ready) on <unset>:80");
897 connection_free_minimal(conn);
899 // Try a unix socket.
900 conn = connection_new(CONN_TYPE_CONTROL_LISTENER, AF_UNIX);
901 conn->address = tor_strdup("/a/path/that/could/exist");
902 tt_str_op(connection_describe(conn), OP_EQ,
903 "Control listener connection (ready) on /a/path/that/could/exist");
904 connection_free_minimal(conn);
906 // Try an IPv6 address.
907 conn = connection_new(CONN_TYPE_AP_LISTENER, AF_INET6);
908 tor_addr_parse(&conn->addr, "ff00::3");
909 conn->port = 9050;
910 tt_str_op(connection_describe(conn), OP_EQ,
911 "Socks listener connection (ready) on [ff00::3]:9050");
912 connection_free_minimal(conn);
914 // Now let's mess with exit connections. They have some special issues.
915 options->SafeLogging_ = SAFELOG_SCRUB_NONE;
916 conn = connection_new(CONN_TYPE_EXIT, AF_INET);
917 // If address and state are unset, we should say SOMETHING.
918 tt_str_op(connection_describe(conn), OP_EQ,
919 "Exit connection (uninitialized) to <unset> (DNS lookup pending)");
920 // Now suppose that the address is set but we haven't resolved the hostname.
921 conn->port = 443;
922 conn->address = tor_strdup("www.torproject.org");
923 conn->state = EXIT_CONN_STATE_RESOLVING;
924 tt_str_op(connection_describe(conn), OP_EQ,
925 "Exit connection (waiting for dest info) to "
926 "www.torproject.org:443 (DNS lookup pending)");
927 // Now give it a hostname!
928 tor_addr_parse(&conn->addr, "192.168.8.8");
929 conn->state = EXIT_CONN_STATE_OPEN;
930 tt_str_op(connection_describe(conn), OP_EQ,
931 "Exit connection (open) to 192.168.8.8:443");
932 // But what if safelogging is on?
933 options->SafeLogging_ = SAFELOG_SCRUB_RELAY;
934 tt_str_op(connection_describe(conn), OP_EQ,
935 "Exit connection (open) to [scrubbed]");
936 connection_free_minimal(conn);
938 // Now at last we look at OR addresses, which are complicated.
939 conn = connection_new(CONN_TYPE_OR, AF_INET6);
940 conn->state = OR_CONN_STATE_OPEN;
941 conn->port = 8080;
942 tor_addr_parse(&conn->addr, "[ffff:3333:1111::2]");
943 // This should get scrubbed, since the lack of a set ID means we might be
944 // talking to a client.
945 tt_str_op(connection_describe(conn), OP_EQ,
946 "OR connection (open) with [scrubbed]");
947 // But now suppose we aren't safelogging? We'll get the address then.
948 options->SafeLogging_ = SAFELOG_SCRUB_NONE;
949 tt_str_op(connection_describe(conn), OP_EQ,
950 "OR connection (open) with [ffff:3333:1111::2]:8080");
951 // Suppose we have an ID, so we know it isn't a client.
952 TO_OR_CONN(conn)->identity_digest[3] = 7;
953 options->SafeLogging_ = SAFELOG_SCRUB_RELAY; // back to safelogging.
954 tt_str_op(connection_describe(conn), OP_EQ,
955 "OR connection (open) with [ffff:3333:1111::2]:8080 "
956 "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
957 // Add a 'canonical address' that is the same as the one we have.
958 tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr,
959 "[ffff:3333:1111::2]");
960 TO_OR_CONN(conn)->canonical_orport.port = 8080;
961 tt_str_op(connection_describe(conn), OP_EQ,
962 "OR connection (open) with [ffff:3333:1111::2]:8080 "
963 "ID=<none> RSA_ID=0000000700000000000000000000000000000000");
964 // Add a different 'canonical address'
965 tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr,
966 "[ffff:3333:1111::8]");
967 tt_str_op(connection_describe(conn), OP_EQ,
968 "OR connection (open) with [ffff:3333:1111::2]:8080 "
969 "ID=<none> RSA_ID=0000000700000000000000000000000000000000 "
970 "canonical_addr=[ffff:3333:1111::8]:8080");
972 // Clear identity_digest so that free_minimal won't complain.
973 memset(TO_OR_CONN(conn)->identity_digest, 0, DIGEST_LEN);
975 done:
976 connection_free_minimal(conn);
979 #ifndef COCCI
980 #define CONNECTION_TESTCASE(name, fork, setup) \
981 { #name, test_conn_##name, fork, &setup, NULL }
983 #define STR(x) #x
984 /* where arg is an expression (constant, variable, compound expression) */
985 #define CONNECTION_TESTCASE_ARG(name, extra, fork, setup, arg) \
986 { STR(name)"/"extra, \
987 test_conn_##name, \
988 (fork), \
989 &(setup), \
990 (void *)(arg) }
991 #endif /* !defined(COCCI) */
993 static const unsigned int PROXY_CONNECT_ARG = PROXY_CONNECT;
994 static const unsigned int PROXY_HAPROXY_ARG = PROXY_HAPROXY;
996 struct testcase_t connection_tests[] = {
997 CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st),
998 CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st),
1000 CONNECTION_TESTCASE_ARG(download_status, "microdesc", TT_FORK,
1001 test_conn_download_status_st, "microdesc"),
1002 CONNECTION_TESTCASE_ARG(download_status, "ns", TT_FORK,
1003 test_conn_download_status_st, "ns"),
1005 CONNECTION_TESTCASE_ARG(https_proxy_connect, "https", TT_FORK,
1006 test_conn_proxy_connect_st, &PROXY_CONNECT_ARG),
1007 CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, "haproxy", TT_FORK,
1008 test_conn_proxy_connect_st, &PROXY_HAPROXY_ARG),
1010 //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
1011 { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
1012 { "describe", test_conn_describe, TT_FORK, NULL, NULL },
1013 END_OF_TESTCASES