1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #define CIRCUITBUILD_PRIVATE
8 #include "core/or/or.h"
10 #include "test/test_helpers.h"
11 #include "test/log_test_helpers.h"
12 #include "app/config/config.h"
13 #include "core/or/circuitbuild.h"
14 #include "core/or/circuitlist.h"
16 #include "core/or/extend_info_st.h"
18 /* Dummy nodes smartlist for testing */
19 static smartlist_t dummy_nodes
;
20 /* Dummy exit extend_info for testing */
21 static extend_info_t dummy_ei
;
24 mock_count_acceptable_nodes(smartlist_t
*nodes
, int direct
)
28 return direct
? 1 : DEFAULT_ROUTE_LEN
+ 1;
31 /* Test route lengths when the caller of new_route_len() doesn't
34 test_new_route_len_noexit(void *arg
)
39 MOCK(count_acceptable_nodes
, mock_count_acceptable_nodes
);
41 r
= new_route_len(CIRCUIT_PURPOSE_C_GENERAL
, NULL
, &dummy_nodes
);
42 tt_int_op(DEFAULT_ROUTE_LEN
, OP_EQ
, r
);
44 r
= new_route_len(CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
, NULL
, &dummy_nodes
);
45 tt_int_op(DEFAULT_ROUTE_LEN
, OP_EQ
, r
);
47 r
= new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND
, NULL
, &dummy_nodes
);
48 tt_int_op(DEFAULT_ROUTE_LEN
, OP_EQ
, r
);
51 UNMOCK(count_acceptable_nodes
);
54 /* Test route lengths where someone else chose the "exit" node, which
55 * require an extra hop for safety. */
57 test_new_route_len_unsafe_exit(void *arg
)
62 MOCK(count_acceptable_nodes
, mock_count_acceptable_nodes
);
64 /* connecting to hidden service directory */
65 r
= new_route_len(CIRCUIT_PURPOSE_C_GENERAL
, &dummy_ei
, &dummy_nodes
);
66 tt_int_op(DEFAULT_ROUTE_LEN
+ 1, OP_EQ
, r
);
68 /* client connecting to introduction point */
69 r
= new_route_len(CIRCUIT_PURPOSE_C_INTRODUCING
, &dummy_ei
, &dummy_nodes
);
70 tt_int_op(DEFAULT_ROUTE_LEN
+ 1, OP_EQ
, r
);
72 /* hidden service connecting to rendezvous point */
73 r
= new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND
, &dummy_ei
, &dummy_nodes
);
74 tt_int_op(DEFAULT_ROUTE_LEN
+ 1, OP_EQ
, r
);
77 UNMOCK(count_acceptable_nodes
);
80 /* Test route lengths where we chose the "exit" node, which don't
81 * require an extra hop for safety. */
83 test_new_route_len_safe_exit(void *arg
)
88 MOCK(count_acceptable_nodes
, mock_count_acceptable_nodes
);
90 /* hidden service connecting to introduction point */
91 r
= new_route_len(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
, &dummy_ei
,
93 tt_int_op(DEFAULT_ROUTE_LEN
, OP_EQ
, r
);
95 /* router testing its own reachability */
96 r
= new_route_len(CIRCUIT_PURPOSE_TESTING
, &dummy_ei
, &dummy_nodes
);
97 tt_int_op(DEFAULT_ROUTE_LEN
, OP_EQ
, r
);
100 UNMOCK(count_acceptable_nodes
);
103 /* Make sure a non-fatal assertion fails when new_route_len() gets an
104 * unexpected circuit purpose. */
106 test_new_route_len_unhandled_exit(void *arg
)
111 MOCK(count_acceptable_nodes
, mock_count_acceptable_nodes
);
113 tor_capture_bugs_(1);
114 setup_full_capture_of_logs(LOG_WARN
);
115 r
= new_route_len(CIRCUIT_PURPOSE_CONTROLLER
, &dummy_ei
, &dummy_nodes
);
116 tt_int_op(DEFAULT_ROUTE_LEN
+ 1, OP_EQ
, r
);
117 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ
, 1);
118 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ
,
119 "!(exit_ei && !known_purpose)");
120 expect_single_log_msg_containing("Unhandled purpose");
121 expect_single_log_msg_containing("with a chosen exit; assuming routelen");
122 teardown_capture_of_logs();
123 tor_end_capture_bugs_();
126 UNMOCK(count_acceptable_nodes
);
129 struct testcase_t circuitbuild_tests
[] = {
130 { "noexit", test_new_route_len_noexit
, 0, NULL
, NULL
},
131 { "safe_exit", test_new_route_len_safe_exit
, 0, NULL
, NULL
},
132 { "unsafe_exit", test_new_route_len_unsafe_exit
, 0, NULL
, NULL
},
133 { "unhandled_exit", test_new_route_len_unhandled_exit
, 0, NULL
, NULL
},