1 /* Copyright (c) 2014-2016, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
8 #define DIRVOTE_PRIVATE
9 #define NETWORKSTATUS_PRIVATE
10 #define ROUTERLIST_PRIVATE
11 #define TOR_UNIT_TESTING
14 #include "connection.h"
15 #include "container.h"
16 #include "directory.h"
18 #include "microdesc.h"
19 #include "networkstatus.h"
23 #include "routerlist.h"
24 #include "routerparse.h"
25 #include "shared_random.h"
27 #include "test_dir_common.h"
29 void construct_consensus(char **consensus_text_md
);
31 static authority_cert_t
*mock_cert
;
33 static authority_cert_t
*
34 get_my_v3_authority_cert_m(void)
36 tor_assert(mock_cert
);
40 /* 4 digests + 3 sep + pre + post + NULL */
41 static char output
[4*BASE64_DIGEST256_LEN
+3+2+2+1];
44 mock_get_from_dirserver(uint8_t dir_purpose
, uint8_t router_purpose
,
45 const char *resource
, int pds_flags
,
46 download_want_authority_t want_authority
)
53 strlcpy(output
, resource
, sizeof(output
));
59 test_routerlist_initiate_descriptor_downloads(void *arg
)
61 const char *prose
= "unhurried and wise, we perceive.";
62 smartlist_t
*digests
= smartlist_new();
65 for (int i
= 0; i
< 20; i
++) {
66 smartlist_add(digests
, (char*)prose
);
69 MOCK(directory_get_from_dirserver
, mock_get_from_dirserver
);
70 initiate_descriptor_downloads(NULL
, DIR_PURPOSE_FETCH_MICRODESC
,
72 UNMOCK(directory_get_from_dirserver
);
74 tt_str_op(output
, OP_EQ
, "d/"
75 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
76 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
77 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
78 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4"
82 smartlist_free(digests
);
88 mock_initiate_descriptor_downloads(const routerstatus_t
*source
,
89 int purpose
, smartlist_t
*digests
,
90 int lo
, int hi
, int pds_flags
)
102 test_routerlist_launch_descriptor_downloads(void *arg
)
104 smartlist_t
*downloadable
= smartlist_new();
105 time_t now
= time(NULL
);
109 for (int i
= 0; i
< 100; i
++) {
110 cp
= tor_malloc(DIGEST256_LEN
);
112 crypto_rand(cp
, DIGEST256_LEN
);
113 smartlist_add(downloadable
, cp
);
116 MOCK(initiate_descriptor_downloads
, mock_initiate_descriptor_downloads
);
117 launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC
, downloadable
,
119 tt_int_op(3, ==, count
);
120 UNMOCK(initiate_descriptor_downloads
);
123 SMARTLIST_FOREACH(downloadable
, char *, cp1
, tor_free(cp1
));
124 smartlist_free(downloadable
);
128 construct_consensus(char **consensus_text_md
)
130 networkstatus_t
*vote
= NULL
;
131 networkstatus_t
*v1
= NULL
, *v2
= NULL
, *v3
= NULL
;
132 networkstatus_voter_info_t
*voter
= NULL
;
133 authority_cert_t
*cert1
=NULL
, *cert2
=NULL
, *cert3
=NULL
;
134 crypto_pk_t
*sign_skey_1
=NULL
, *sign_skey_2
=NULL
, *sign_skey_3
=NULL
;
135 crypto_pk_t
*sign_skey_leg
=NULL
;
136 time_t now
= time(NULL
);
137 smartlist_t
*votes
= NULL
;
140 tt_assert(!dir_common_authority_pk_init(&cert1
, &cert2
, &cert3
,
141 &sign_skey_1
, &sign_skey_2
,
143 sign_skey_leg
= pk_generate(4);
145 dir_common_construct_vote_1(&vote
, cert1
, sign_skey_1
,
146 &dir_common_gen_routerstatus_for_v3ns
,
147 &v1
, &n_vrs
, now
, 1);
148 networkstatus_vote_free(vote
);
150 tt_int_op(n_vrs
, ==, 4);
151 tt_int_op(smartlist_len(v1
->routerstatus_list
), ==, 4);
153 dir_common_construct_vote_2(&vote
, cert2
, sign_skey_2
,
154 &dir_common_gen_routerstatus_for_v3ns
,
155 &v2
, &n_vrs
, now
, 1);
156 networkstatus_vote_free(vote
);
158 tt_int_op(n_vrs
, ==, 4);
159 tt_int_op(smartlist_len(v2
->routerstatus_list
), ==, 4);
161 dir_common_construct_vote_3(&vote
, cert3
, sign_skey_3
,
162 &dir_common_gen_routerstatus_for_v3ns
,
163 &v3
, &n_vrs
, now
, 1);
166 tt_int_op(n_vrs
, ==, 4);
167 tt_int_op(smartlist_len(v3
->routerstatus_list
), ==, 4);
168 networkstatus_vote_free(vote
);
169 votes
= smartlist_new();
170 smartlist_add(votes
, v1
);
171 smartlist_add(votes
, v2
);
172 smartlist_add(votes
, v3
);
174 *consensus_text_md
= networkstatus_compute_consensus(votes
, 3,
177 "AAAAAAAAAAAAAAAAAAAA",
181 tt_assert(*consensus_text_md
);
185 networkstatus_vote_free(v1
);
186 networkstatus_vote_free(v2
);
187 networkstatus_vote_free(v3
);
188 smartlist_free(votes
);
189 authority_cert_free(cert1
);
190 authority_cert_free(cert2
);
191 authority_cert_free(cert3
);
192 crypto_pk_free(sign_skey_1
);
193 crypto_pk_free(sign_skey_2
);
194 crypto_pk_free(sign_skey_3
);
195 crypto_pk_free(sign_skey_leg
);
198 static int mock_usable_consensus_flavor_value
= FLAV_NS
;
201 mock_usable_consensus_flavor(void)
203 return mock_usable_consensus_flavor_value
;
207 test_router_pick_directory_server_impl(void *arg
)
211 networkstatus_t
*con_md
= NULL
;
212 char *consensus_text_md
= NULL
;
213 int flags
= PDS_IGNORE_FASCISTFIREWALL
|PDS_RETRY_IF_NO_SERVERS
;
214 or_options_t
*options
= get_options_mutable();
215 const routerstatus_t
*rs
= NULL
;
216 options
->UseMicrodescriptors
= 1;
217 char *router1_id
= NULL
, *router2_id
= NULL
, *router3_id
= NULL
;
218 node_t
*node_router1
= NULL
, *node_router2
= NULL
, *node_router3
= NULL
;
219 config_line_t
*policy_line
= NULL
;
220 time_t now
= time(NULL
);
221 int tmp_dirport1
, tmp_dirport3
;
225 MOCK(usable_consensus_flavor
, mock_usable_consensus_flavor
);
227 /* With no consensus, we must be bootstrapping, regardless of time or flavor
229 mock_usable_consensus_flavor_value
= FLAV_NS
;
230 tt_assert(networkstatus_consensus_is_bootstrapping(now
));
231 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2000));
232 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2*24*60*60));
233 tt_assert(networkstatus_consensus_is_bootstrapping(now
- 2*24*60*60));
235 mock_usable_consensus_flavor_value
= FLAV_MICRODESC
;
236 tt_assert(networkstatus_consensus_is_bootstrapping(now
));
237 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2000));
238 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2*24*60*60));
239 tt_assert(networkstatus_consensus_is_bootstrapping(now
- 2*24*60*60));
241 /* Init SR subsystem. */
242 MOCK(get_my_v3_authority_cert
, get_my_v3_authority_cert_m
);
243 mock_cert
= authority_cert_parse_from_string(AUTHORITY_CERT_1
, NULL
);
245 UNMOCK(get_my_v3_authority_cert
);
247 /* No consensus available, fail early */
248 rs
= router_pick_directory_server_impl(V3_DIRINFO
, (const int) 0, NULL
);
249 tt_assert(rs
== NULL
);
251 construct_consensus(&consensus_text_md
);
252 tt_assert(consensus_text_md
);
253 con_md
= networkstatus_parse_vote_from_string(consensus_text_md
, NULL
,
256 tt_int_op(con_md
->flavor
,==, FLAV_MICRODESC
);
257 tt_assert(con_md
->routerstatus_list
);
258 tt_int_op(smartlist_len(con_md
->routerstatus_list
), ==, 3);
259 tt_assert(!networkstatus_set_current_consensus_from_ns(con_md
,
262 /* If the consensus time or flavor doesn't match, we are still
264 mock_usable_consensus_flavor_value
= FLAV_NS
;
265 tt_assert(networkstatus_consensus_is_bootstrapping(now
));
266 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2000));
267 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2*24*60*60));
268 tt_assert(networkstatus_consensus_is_bootstrapping(now
- 2*24*60*60));
270 /* With a valid consensus for the current time and flavor, we stop
271 * bootstrapping, even if we have no certificates */
272 mock_usable_consensus_flavor_value
= FLAV_MICRODESC
;
273 tt_assert(!networkstatus_consensus_is_bootstrapping(now
+ 2000));
274 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md
->valid_after
));
275 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md
->valid_until
));
276 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md
->valid_until
278 /* These times are outside the test validity period */
279 tt_assert(networkstatus_consensus_is_bootstrapping(now
));
280 tt_assert(networkstatus_consensus_is_bootstrapping(now
+ 2*24*60*60));
281 tt_assert(networkstatus_consensus_is_bootstrapping(now
- 2*24*60*60));
283 nodelist_set_consensus(con_md
);
284 nodelist_assert_ok();
286 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
287 /* We should not fail now we have a consensus and routerstatus_list
288 * and nodelist are populated. */
289 tt_assert(rs
!= NULL
);
291 /* Manipulate the nodes so we get the dir server we expect */
292 router1_id
= tor_malloc(DIGEST_LEN
);
293 memset(router1_id
, TEST_DIR_ROUTER_ID_1
, DIGEST_LEN
);
294 router2_id
= tor_malloc(DIGEST_LEN
);
295 memset(router2_id
, TEST_DIR_ROUTER_ID_2
, DIGEST_LEN
);
296 router3_id
= tor_malloc(DIGEST_LEN
);
297 memset(router3_id
, TEST_DIR_ROUTER_ID_3
, DIGEST_LEN
);
299 node_router1
= node_get_mutable_by_id(router1_id
);
300 node_router2
= node_get_mutable_by_id(router2_id
);
301 node_router3
= node_get_mutable_by_id(router3_id
);
303 node_router1
->is_possible_guard
= 1;
305 node_router1
->is_running
= 0;
306 node_router3
->is_running
= 0;
307 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
308 tt_assert(rs
!= NULL
);
309 tt_assert(tor_memeq(rs
->identity_digest
, router2_id
, DIGEST_LEN
));
311 node_router1
->is_running
= 1;
312 node_router3
->is_running
= 1;
314 node_router1
->rs
->is_v2_dir
= 0;
315 node_router3
->rs
->is_v2_dir
= 0;
316 tmp_dirport1
= node_router1
->rs
->dir_port
;
317 tmp_dirport3
= node_router3
->rs
->dir_port
;
318 node_router1
->rs
->dir_port
= 0;
319 node_router3
->rs
->dir_port
= 0;
320 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
321 tt_assert(rs
!= NULL
);
322 tt_assert(tor_memeq(rs
->identity_digest
, router2_id
, DIGEST_LEN
));
324 node_router1
->rs
->is_v2_dir
= 1;
325 node_router3
->rs
->is_v2_dir
= 1;
326 node_router1
->rs
->dir_port
= tmp_dirport1
;
327 node_router3
->rs
->dir_port
= tmp_dirport3
;
329 node_router1
->is_valid
= 0;
330 node_router3
->is_valid
= 0;
331 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
332 tt_assert(rs
!= NULL
);
333 tt_assert(tor_memeq(rs
->identity_digest
, router2_id
, DIGEST_LEN
));
335 node_router1
->is_valid
= 1;
336 node_router3
->is_valid
= 1;
338 flags
|= PDS_FOR_GUARD
;
339 node_router1
->using_as_guard
= 1;
340 node_router2
->using_as_guard
= 1;
341 node_router3
->using_as_guard
= 1;
342 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
343 tt_assert(rs
== NULL
);
344 node_router1
->using_as_guard
= 0;
345 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
346 tt_assert(rs
!= NULL
);
347 tt_assert(tor_memeq(rs
->identity_digest
, router1_id
, DIGEST_LEN
));
349 node_router2
->using_as_guard
= 0;
350 node_router3
->using_as_guard
= 0;
352 /* One not valid, one guard. This should leave one remaining */
353 node_router1
->is_valid
= 0;
354 node_router2
->using_as_guard
= 1;
355 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
356 tt_assert(rs
!= NULL
);
357 tt_assert(tor_memeq(rs
->identity_digest
, router3_id
, DIGEST_LEN
));
359 node_router1
->is_valid
= 1;
360 node_router2
->using_as_guard
= 0;
362 /* Manipulate overloaded */
364 node_router2
->rs
->last_dir_503_at
= now
;
365 node_router3
->rs
->last_dir_503_at
= now
;
366 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
367 tt_assert(rs
!= NULL
);
368 tt_assert(tor_memeq(rs
->identity_digest
, router1_id
, DIGEST_LEN
));
369 node_router2
->rs
->last_dir_503_at
= 0;
370 node_router3
->rs
->last_dir_503_at
= 0;
372 /* Set a Fascist firewall */
373 flags
&= ~ PDS_IGNORE_FASCISTFIREWALL
;
374 policy_line
= tor_malloc_zero(sizeof(config_line_t
));
375 policy_line
->key
= tor_strdup("ReachableORAddresses");
376 policy_line
->value
= tor_strdup("accept *:442, reject *:*");
377 options
->ReachableORAddresses
= policy_line
;
378 policies_parse_from_options(options
);
380 node_router1
->rs
->or_port
= 444;
381 node_router2
->rs
->or_port
= 443;
382 node_router3
->rs
->or_port
= 442;
383 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
384 tt_assert(rs
!= NULL
);
385 tt_assert(tor_memeq(rs
->identity_digest
, router3_id
, DIGEST_LEN
));
386 node_router1
->rs
->or_port
= 442;
387 node_router2
->rs
->or_port
= 443;
388 node_router3
->rs
->or_port
= 444;
389 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
390 tt_assert(rs
!= NULL
);
391 tt_assert(tor_memeq(rs
->identity_digest
, router1_id
, DIGEST_LEN
));
393 /* Fascist firewall and overloaded */
394 node_router1
->rs
->or_port
= 442;
395 node_router2
->rs
->or_port
= 443;
396 node_router3
->rs
->or_port
= 442;
397 node_router3
->rs
->last_dir_503_at
= now
;
398 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
399 tt_assert(rs
!= NULL
);
400 tt_assert(tor_memeq(rs
->identity_digest
, router1_id
, DIGEST_LEN
));
401 node_router3
->rs
->last_dir_503_at
= 0;
403 /* Fascists against OR and Dir */
404 policy_line
= tor_malloc_zero(sizeof(config_line_t
));
405 policy_line
->key
= tor_strdup("ReachableAddresses");
406 policy_line
->value
= tor_strdup("accept *:80, reject *:*");
407 options
->ReachableDirAddresses
= policy_line
;
408 policies_parse_from_options(options
);
409 node_router1
->rs
->or_port
= 442;
410 node_router2
->rs
->or_port
= 441;
411 node_router3
->rs
->or_port
= 443;
412 node_router1
->rs
->dir_port
= 80;
413 node_router2
->rs
->dir_port
= 80;
414 node_router3
->rs
->dir_port
= 81;
415 node_router1
->rs
->last_dir_503_at
= now
;
416 rs
= router_pick_directory_server_impl(V3_DIRINFO
, flags
, NULL
);
417 tt_assert(rs
!= NULL
);
418 tt_assert(tor_memeq(rs
->identity_digest
, router1_id
, DIGEST_LEN
));
419 node_router1
->rs
->last_dir_503_at
= 0;
422 UNMOCK(usable_consensus_flavor
);
424 tor_free(router1_id
);
426 tor_free(router2_id
);
428 tor_free(router3_id
);
429 if (options
->ReachableORAddresses
||
430 options
->ReachableDirAddresses
)
432 tor_free(consensus_text_md
);
433 networkstatus_vote_free(con_md
);
436 static connection_t
*mocked_connection
= NULL
;
438 /* Mock connection_get_by_type_addr_port_purpose by returning
439 * mocked_connection. */
440 static connection_t
*
441 mock_connection_get_by_type_addr_port_purpose(int type
,
442 const tor_addr_t
*addr
,
443 uint16_t port
, int purpose
)
450 return mocked_connection
;
453 #define TEST_ADDR_STR "127.0.0.1"
454 #define TEST_DIR_PORT 12345
457 test_routerlist_router_is_already_dir_fetching(void *arg
)
460 tor_addr_port_t test_ap
, null_addr_ap
, zero_port_ap
;
463 tor_addr_parse(&test_ap
.addr
, TEST_ADDR_STR
);
464 test_ap
.port
= TEST_DIR_PORT
;
465 tor_addr_make_null(&null_addr_ap
.addr
, AF_INET6
);
466 null_addr_ap
.port
= TEST_DIR_PORT
;
467 tor_addr_parse(&zero_port_ap
.addr
, TEST_ADDR_STR
);
468 zero_port_ap
.port
= 0;
469 MOCK(connection_get_by_type_addr_port_purpose
,
470 mock_connection_get_by_type_addr_port_purpose
);
472 /* Test that we never get 1 from a NULL connection */
473 mocked_connection
= NULL
;
474 tt_assert(router_is_already_dir_fetching(&test_ap
, 1, 1) == 0);
475 tt_assert(router_is_already_dir_fetching(&test_ap
, 1, 0) == 0);
476 tt_assert(router_is_already_dir_fetching(&test_ap
, 0, 1) == 0);
477 /* We always expect 0 in these cases */
478 tt_assert(router_is_already_dir_fetching(&test_ap
, 0, 0) == 0);
479 tt_assert(router_is_already_dir_fetching(NULL
, 1, 1) == 0);
480 tt_assert(router_is_already_dir_fetching(&null_addr_ap
, 1, 1) == 0);
481 tt_assert(router_is_already_dir_fetching(&zero_port_ap
, 1, 1) == 0);
483 /* Test that we get 1 with a connection in the appropriate circumstances */
484 mocked_connection
= connection_new(CONN_TYPE_DIR
, AF_INET
);
485 tt_assert(router_is_already_dir_fetching(&test_ap
, 1, 1) == 1);
486 tt_assert(router_is_already_dir_fetching(&test_ap
, 1, 0) == 1);
487 tt_assert(router_is_already_dir_fetching(&test_ap
, 0, 1) == 1);
489 /* Test that we get 0 even with a connection in the appropriate
491 tt_assert(router_is_already_dir_fetching(&test_ap
, 0, 0) == 0);
492 tt_assert(router_is_already_dir_fetching(NULL
, 1, 1) == 0);
493 tt_assert(router_is_already_dir_fetching(&null_addr_ap
, 1, 1) == 0);
494 tt_assert(router_is_already_dir_fetching(&zero_port_ap
, 1, 1) == 0);
497 /* If a connection is never set up, connection_free chokes on it. */
498 if (mocked_connection
) {
499 buf_free(mocked_connection
->inbuf
);
500 buf_free(mocked_connection
->outbuf
);
502 tor_free(mocked_connection
);
503 UNMOCK(connection_get_by_type_addr_port_purpose
);
509 #define NODE(name, flags) \
510 { #name, test_routerlist_##name, (flags), NULL, NULL }
511 #define ROUTER(name,flags) \
512 { #name, test_router_##name, (flags), NULL, NULL }
514 struct testcase_t routerlist_tests
[] = {
515 NODE(initiate_descriptor_downloads
, 0),
516 NODE(launch_descriptor_downloads
, 0),
517 NODE(router_is_already_dir_fetching
, TT_FORK
),
518 ROUTER(pick_directory_server_impl
, TT_FORK
),