Remove unused function: dns_randfn_() in dns.c.
[tor.git] / src / test / test_router.c
blobe0d3adfdbd7d8867f543ecdedd5f4523b64e5d26
1 /* Copyright (c) 2017-2019, The Tor Project, Inc. */
2 /* Copyright (c) 2017, isis agora lovecruft */
3 /* See LICENSE for licensing information */
5 /**
6 * \file test_router.c
7 * \brief Unittests for code in router.c
8 **/
10 #define CONFIG_PRIVATE
11 #define CONNECTION_PRIVATE
12 #include "core/or/or.h"
13 #include "app/config/config.h"
14 #include "core/mainloop/mainloop.h"
15 #include "core/mainloop/connection.h"
16 #include "feature/hibernate/hibernate.h"
17 #include "feature/nodelist/routerinfo_st.h"
18 #include "feature/nodelist/routerlist.h"
19 #include "feature/relay/router.h"
20 #include "feature/stats/rephist.h"
21 #include "lib/crypt_ops/crypto_curve25519.h"
22 #include "lib/crypt_ops/crypto_ed25519.h"
23 #include "lib/encoding/confline.h"
25 #include "core/or/listener_connection_st.h"
27 /* Test suite stuff */
28 #include "test/test.h"
29 #include "test/log_test_helpers.h"
31 NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
33 static routerinfo_t* mock_routerinfo;
35 static const routerinfo_t*
36 NS(router_get_my_routerinfo)(void)
38 crypto_pk_t* ident_key;
39 crypto_pk_t* tap_key;
40 time_t now;
42 if (!mock_routerinfo) {
43 /* Mock the published timestamp, otherwise router_dump_router_to_string()
44 * will poop its pants. */
45 time(&now);
47 /* We'll need keys, or router_dump_router_to_string() would return NULL. */
48 ident_key = pk_generate(0);
49 tap_key = pk_generate(0);
51 tor_assert(ident_key != NULL);
52 tor_assert(tap_key != NULL);
54 mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
55 mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
56 mock_routerinfo->addr = 123456789;
57 mock_routerinfo->or_port = 443;
58 mock_routerinfo->platform = tor_strdup("unittest");
59 mock_routerinfo->cache_info.published_on = now;
60 mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
61 router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->onion_pkey,
62 &mock_routerinfo->onion_pkey_len);
63 mock_routerinfo->bandwidthrate = 9001;
64 mock_routerinfo->bandwidthburst = 9002;
65 crypto_pk_free(ident_key);
66 crypto_pk_free(tap_key);
69 return mock_routerinfo;
72 /* If no distribution option was set, then check_bridge_distribution_setting()
73 * should have set it to "any". */
74 static void
75 test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
77 const char* needle = "bridge-distribution-request any";
78 or_options_t* options = get_options_mutable();
79 routerinfo_t* router = NULL;
80 curve25519_keypair_t ntor_keypair;
81 ed25519_keypair_t signing_keypair;
82 char* desc = NULL;
83 char* found = NULL;
84 (void)arg;
86 NS_MOCK(router_get_my_routerinfo);
88 options->ORPort_set = 1;
89 options->BridgeRelay = 1;
91 /* Generate keys which router_dump_router_to_string() expects to exist. */
92 tt_int_op(0, ==, curve25519_keypair_generate(&ntor_keypair, 0));
93 tt_int_op(0, ==, ed25519_keypair_generate(&signing_keypair, 0));
95 /* Set up part of our routerinfo_t so that we don't trigger any other
96 * assertions in router_dump_router_to_string(). */
97 router = (routerinfo_t*)router_get_my_routerinfo();
98 tt_ptr_op(router, !=, NULL);
100 router->onion_curve25519_pkey = &ntor_keypair.pubkey;
102 /* Generate our server descriptor and ensure that the substring
103 * "bridge-distribution-request any" occurs somewhere within it. */
104 crypto_pk_t *onion_pkey = router_get_rsa_onion_pkey(router->onion_pkey,
105 router->onion_pkey_len);
106 desc = router_dump_router_to_string(router,
107 router->identity_pkey,
108 onion_pkey,
109 &ntor_keypair,
110 &signing_keypair);
111 crypto_pk_free(onion_pkey);
112 tt_ptr_op(desc, !=, NULL);
113 found = strstr(desc, needle);
114 tt_ptr_op(found, !=, NULL);
116 done:
117 NS_UNMOCK(router_get_my_routerinfo);
119 tor_free(desc);
122 static routerinfo_t *mock_router_get_my_routerinfo_result = NULL;
124 static const routerinfo_t *
125 mock_router_get_my_routerinfo(void)
127 return mock_router_get_my_routerinfo_result;
130 static long
131 mock_get_uptime_3h(void)
133 return 3*60*60;
136 static long
137 mock_get_uptime_1d(void)
139 return 24*60*60;
142 static int
143 mock_rep_hist_bandwidth_assess(void)
145 return 20001;
148 static int
149 mock_we_are_not_hibernating(void)
151 return 0;
154 static int
155 mock_we_are_hibernating(void)
157 return 0;
160 static void
161 test_router_check_descriptor_bandwidth_changed(void *arg)
163 (void)arg;
164 routerinfo_t routerinfo;
165 memset(&routerinfo, 0, sizeof(routerinfo));
166 mock_router_get_my_routerinfo_result = NULL;
168 MOCK(we_are_hibernating, mock_we_are_not_hibernating);
169 MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
170 mock_router_get_my_routerinfo_result = &routerinfo;
172 /* When uptime is less than 24h, no previous bandwidth, no last_changed
173 * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
174 routerinfo.bandwidthcapacity = 0;
175 MOCK(get_uptime, mock_get_uptime_3h);
176 setup_full_capture_of_logs(LOG_INFO);
177 check_descriptor_bandwidth_changed(time(NULL));
178 expect_log_msg_not_containing(
179 "Measured bandwidth has changed; rebuilding descriptor.");
180 teardown_capture_of_logs();
182 /* When uptime is less than 24h, previous bandwidth,
183 * last_changed more than 3h ago
184 * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
185 routerinfo.bandwidthcapacity = 10000;
186 setup_full_capture_of_logs(LOG_INFO);
187 check_descriptor_bandwidth_changed(time(NULL));
188 expect_log_msg_containing(
189 "Measured bandwidth has changed; rebuilding descriptor.");
190 teardown_capture_of_logs();
192 /* When uptime is less than 24h, previous bandwidth,
193 * last_changed more than 3h ago, and hibernating
194 * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
196 UNMOCK(we_are_hibernating);
197 MOCK(we_are_hibernating, mock_we_are_hibernating);
198 routerinfo.bandwidthcapacity = 10000;
199 setup_full_capture_of_logs(LOG_INFO);
200 check_descriptor_bandwidth_changed(time(NULL));
201 expect_log_msg_not_containing(
202 "Measured bandwidth has changed; rebuilding descriptor.");
203 teardown_capture_of_logs();
204 UNMOCK(we_are_hibernating);
205 MOCK(we_are_hibernating, mock_we_are_not_hibernating);
207 /* When uptime is less than 24h, last_changed is not more than 3h ago
208 * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
209 setup_full_capture_of_logs(LOG_INFO);
210 check_descriptor_bandwidth_changed(time(NULL));
211 expect_log_msg_not_containing(
212 "Measured bandwidth has changed; rebuilding descriptor.");
213 teardown_capture_of_logs();
215 /* When uptime is less than 24h and bandwidthcapacity does not change
216 * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
217 MOCK(rep_hist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
218 setup_full_capture_of_logs(LOG_INFO);
219 check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
220 expect_log_msg_containing(
221 "Measured bandwidth has changed; rebuilding descriptor.");
222 UNMOCK(get_uptime);
223 UNMOCK(rep_hist_bandwidth_assess);
224 teardown_capture_of_logs();
226 /* When uptime is more than 24h */
227 MOCK(get_uptime, mock_get_uptime_1d);
228 setup_full_capture_of_logs(LOG_INFO);
229 check_descriptor_bandwidth_changed(time(NULL));
230 expect_log_msg_not_containing(
231 "Measured bandwidth has changed; rebuilding descriptor.");
232 teardown_capture_of_logs();
234 done:
235 UNMOCK(get_uptime);
236 UNMOCK(router_get_my_routerinfo);
237 UNMOCK(we_are_hibernating);
240 static smartlist_t *fake_connection_array = NULL;
241 static smartlist_t *
242 mock_get_connection_array(void)
244 return fake_connection_array;
247 static void
248 test_router_get_advertised_or_port(void *arg)
250 (void)arg;
251 int r, w=0, n=0;
252 char *msg=NULL;
253 or_options_t *opts = options_new();
254 listener_connection_t *listener = NULL;
255 tor_addr_port_t ipv6;
257 // Test one failing case of router_get_advertised_ipv6_or_ap().
258 router_get_advertised_ipv6_or_ap(opts, &ipv6);
259 tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
261 // And one failing case of router_get_advertised_or_port().
262 tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
263 tt_int_op(0, OP_EQ, router_get_advertised_or_port(opts));
265 // Set up a couple of configured ports.
266 config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:auto");
267 config_line_append(&opts->ORPort_lines, "ORPort", "5.6.7.8:9999");
268 r = parse_ports(opts, 0, &msg, &n, &w);
269 tt_assert(r == 0);
271 // There are no listeners, so the "auto" case will turn up no results.
272 tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
273 router_get_advertised_ipv6_or_ap(opts, &ipv6);
274 tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
276 // This will return the matching value from the configured port.
277 tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
278 tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
280 // Now set up a dummy listener.
281 MOCK(get_connection_array, mock_get_connection_array);
282 fake_connection_array = smartlist_new();
283 listener = listener_connection_new(CONN_TYPE_OR_LISTENER, AF_INET6);
284 TO_CONN(listener)->port = 54321;
285 smartlist_add(fake_connection_array, TO_CONN(listener));
287 // We should get a port this time.
288 tt_int_op(54321, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
290 // Test one succeeding case of router_get_advertised_ipv6_or_ap().
291 router_get_advertised_ipv6_or_ap(opts, &ipv6);
292 tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ,
293 "[1234::5678]:54321");
295 // This will return the matching value from the configured port.
296 tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
297 tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
299 done:
300 or_options_free(opts);
301 config_free_all();
302 smartlist_free(fake_connection_array);
303 connection_free_minimal(TO_CONN(listener));
304 UNMOCK(get_connection_array);
307 static void
308 test_router_get_advertised_or_port_localhost(void *arg)
310 (void)arg;
311 int r, w=0, n=0;
312 char *msg=NULL;
313 or_options_t *opts = options_new();
314 tor_addr_port_t ipv6;
316 // Set up a couple of configured ports on localhost.
317 config_line_append(&opts->ORPort_lines, "ORPort", "[::1]:9999");
318 config_line_append(&opts->ORPort_lines, "ORPort", "127.0.0.1:8888");
319 r = parse_ports(opts, 0, &msg, &n, &w);
320 tt_assert(r == 0);
322 // We should refuse to advertise them, since we have default dirauths.
323 router_get_advertised_ipv6_or_ap(opts, &ipv6);
324 tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
325 // But the lower-level function should still report the correct value
326 tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
328 // The IPv4 checks are done in resolve_my_address(), which doesn't use
329 // ORPorts so we can't test them here. (See #33681.) Both these lower-level
330 // functions should still report the correct value.
331 tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
332 tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
334 // Now try with a fake authority set up.
335 config_line_append(&opts->DirAuthorities, "DirAuthority",
336 "127.0.0.1:1066 "
337 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
339 tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
340 router_get_advertised_ipv6_or_ap(opts, &ipv6);
341 tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::1]:9999");
343 tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
344 tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
346 done:
347 or_options_free(opts);
348 config_free_all();
351 #define ROUTER_TEST(name, flags) \
352 { #name, test_router_ ## name, flags, NULL, NULL }
354 struct testcase_t router_tests[] = {
355 ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
356 ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
357 ROUTER_TEST(get_advertised_or_port, TT_FORK),
358 ROUTER_TEST(get_advertised_or_port_localhost, TT_FORK),
359 END_OF_TESTCASES