1 /* Copyright (c) 2010-2016, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
8 #define RENDCACHE_PRIVATE
11 #include "routerlist.h"
13 #include <openssl/rsa.h>
14 #include "rend_test_helpers.h"
15 #include "log_test_helpers.h"
17 #define NS_MODULE rend_cache
19 static const int RECENT_TIME
= -10;
20 static const int TIME_IN_THE_PAST
= -(REND_CACHE_MAX_AGE
+ \
21 REND_CACHE_MAX_SKEW
+ 60);
22 static const int TIME_IN_THE_FUTURE
= REND_CACHE_MAX_SKEW
+ 60;
25 mock_rend_data(const char *onion_address
)
27 rend_data_t
*rend_query
= tor_malloc_zero(sizeof(rend_data_t
));
29 strlcpy(rend_query
->onion_address
, onion_address
,
30 sizeof(rend_query
->onion_address
));
31 rend_query
->auth_type
= REND_NO_AUTH
;
32 rend_query
->hsdirs_fp
= smartlist_new();
33 smartlist_add(rend_query
->hsdirs_fp
, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa",
40 test_rend_cache_lookup_entry(void *data
)
43 rend_data_t
*mock_rend_query
= NULL
;
44 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
45 rend_cache_entry_t
*entry
= NULL
;
46 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
47 char *service_id
= NULL
;
52 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
54 ret
= rend_cache_lookup_entry("abababababababab", 0, NULL
);
55 tt_int_op(ret
, OP_EQ
, -ENOENT
);
57 ret
= rend_cache_lookup_entry("invalid query", 2, NULL
);
58 tt_int_op(ret
, OP_EQ
, -EINVAL
);
60 ret
= rend_cache_lookup_entry("abababababababab", 2, NULL
);
61 tt_int_op(ret
, OP_EQ
, -ENOENT
);
63 ret
= rend_cache_lookup_entry("abababababababab", 4224, NULL
);
64 tt_int_op(ret
, OP_EQ
, -ENOENT
);
66 mock_rend_query
= mock_rend_data(service_id
);
67 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
69 rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
, desc_id_base32
,
70 mock_rend_query
, NULL
);
72 ret
= rend_cache_lookup_entry(service_id
, 2, NULL
);
73 tt_int_op(ret
, OP_EQ
, 0);
75 ret
= rend_cache_lookup_entry(service_id
, 2, &entry
);
77 tt_int_op(entry
->len
, OP_EQ
, strlen(desc_holder
->desc_str
));
78 tt_str_op(entry
->desc
, OP_EQ
, desc_holder
->desc_str
);
81 rend_encoded_v2_service_descriptor_free(desc_holder
);
83 rend_cache_free_all();
84 rend_data_free(mock_rend_query
);
88 test_rend_cache_store_v2_desc_as_client(void *data
)
91 rend_data_t
*mock_rend_query
;
92 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
93 rend_cache_entry_t
*entry
= NULL
;
94 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
95 char *service_id
= NULL
;
96 char client_cookie
[REND_DESC_COOKIE_LEN
];
101 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
104 mock_rend_query
= mock_rend_data(service_id
);
105 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
107 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
108 desc_id_base32
, mock_rend_query
,
111 tt_int_op(ret
, OP_EQ
, 0);
113 tt_int_op(entry
->len
, OP_EQ
, strlen(desc_holder
->desc_str
));
114 tt_str_op(entry
->desc
, OP_EQ
, desc_holder
->desc_str
);
116 // Test various failure modes
118 // TODO: a too long desc_id_base32 argument crashes the function
119 /* ret = rend_cache_store_v2_desc_as_client( */
120 /* desc_holder->desc_str, */
121 /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */
122 /* &mock_rend_query, NULL); */
123 /* tt_int_op(ret, OP_EQ, -1); */
125 // Test bad base32 failure
126 // This causes an assertion failure if we're running with assertions.
127 // But when building without asserts, we can test it.
128 #ifdef DISABLE_ASSERTS_IN_UNIT_TESTS
129 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
130 "!xqunszqnaolrrfmtzgaki7mxelgvkj", mock_rend_query
, NULL
);
131 tt_int_op(ret
, OP_EQ
, -1);
134 // Test invalid descriptor
135 ret
= rend_cache_store_v2_desc_as_client("invalid descriptor",
136 "3xqunszqnaolrrfmtzgaki7mxelgvkje", mock_rend_query
, NULL
);
137 tt_int_op(ret
, OP_EQ
, -1);
139 // TODO: it doesn't seem to be possible to test invalid service ID condition.
140 // that means it is likely not possible to have that condition without
141 // earlier conditions failing first (such as signature checking of the desc)
143 rend_cache_free_all();
145 // Test mismatch between service ID and onion address
147 strncpy(mock_rend_query
->onion_address
, "abc", REND_SERVICE_ID_LEN_BASE32
+1);
148 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
150 mock_rend_query
, NULL
);
151 tt_int_op(ret
, OP_EQ
, -1);
152 rend_cache_free_all();
153 rend_data_free(mock_rend_query
);
155 // Test incorrect descriptor ID
157 mock_rend_query
= mock_rend_data(service_id
);
159 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
160 desc_id_base32
, mock_rend_query
,
162 tt_int_op(ret
, OP_EQ
, -1);
164 rend_cache_free_all();
166 // Test too old descriptor
168 rend_encoded_v2_service_descriptor_free(desc_holder
);
169 tor_free(service_id
);
170 rend_data_free(mock_rend_query
);
172 generate_desc(TIME_IN_THE_PAST
, &desc_holder
, &service_id
, 3);
173 mock_rend_query
= mock_rend_data(service_id
);
174 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
177 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
179 mock_rend_query
, NULL
);
180 tt_int_op(ret
, OP_EQ
, -1);
181 rend_cache_free_all();
183 // Test too new descriptor (in the future)
185 rend_encoded_v2_service_descriptor_free(desc_holder
);
186 tor_free(service_id
);
187 rend_data_free(mock_rend_query
);
189 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
190 mock_rend_query
= mock_rend_data(service_id
);
191 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
194 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
195 desc_id_base32
, mock_rend_query
,
197 tt_int_op(ret
, OP_EQ
, -1);
198 rend_cache_free_all();
200 // Test when a descriptor is already in the cache
202 rend_encoded_v2_service_descriptor_free(desc_holder
);
203 tor_free(service_id
);
204 rend_data_free(mock_rend_query
);
206 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
207 mock_rend_query
= mock_rend_data(service_id
);
208 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
211 rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
, desc_id_base32
,
212 mock_rend_query
, NULL
);
213 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
214 desc_id_base32
, mock_rend_query
,
216 tt_int_op(ret
, OP_EQ
, 0);
218 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
219 desc_id_base32
, mock_rend_query
,
221 tt_int_op(ret
, OP_EQ
, 0);
223 rend_cache_free_all();
225 // Test unsuccessful decrypting of introduction points
227 rend_encoded_v2_service_descriptor_free(desc_holder
);
228 tor_free(service_id
);
229 rend_data_free(mock_rend_query
);
231 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
232 mock_rend_query
= mock_rend_data(service_id
);
233 mock_rend_query
->auth_type
= REND_BASIC_AUTH
;
234 client_cookie
[0] = 'A';
235 memcpy(mock_rend_query
->descriptor_cookie
, client_cookie
,
236 REND_DESC_COOKIE_LEN
);
237 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
239 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
240 desc_id_base32
, mock_rend_query
,
242 tt_int_op(ret
, OP_EQ
, 0);
243 rend_cache_free_all();
245 // Test successful run when we have REND_BASIC_AUTH but not cookie
247 rend_encoded_v2_service_descriptor_free(desc_holder
);
248 tor_free(service_id
);
249 rend_data_free(mock_rend_query
);
251 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
252 mock_rend_query
= mock_rend_data(service_id
);
253 mock_rend_query
->auth_type
= REND_BASIC_AUTH
;
254 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
256 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
257 desc_id_base32
, mock_rend_query
,
259 tt_int_op(ret
, OP_EQ
, 0);
261 rend_cache_free_all();
263 // Test when we have no introduction points
265 rend_encoded_v2_service_descriptor_free(desc_holder
);
266 tor_free(service_id
);
267 rend_data_free(mock_rend_query
);
269 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 0);
270 mock_rend_query
= mock_rend_data(service_id
);
271 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
273 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
274 desc_id_base32
, mock_rend_query
,
276 tt_int_op(ret
, OP_EQ
, -1);
277 rend_cache_free_all();
279 // Test when we have too many intro points
281 rend_encoded_v2_service_descriptor_free(desc_holder
);
282 tor_free(service_id
);
283 rend_data_free(mock_rend_query
);
285 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, MAX_INTRO_POINTS
+1);
286 mock_rend_query
= mock_rend_data(service_id
);
287 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
289 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
290 desc_id_base32
, mock_rend_query
,
292 tt_int_op(ret
, OP_EQ
, -1);
295 rend_encoded_v2_service_descriptor_free(desc_holder
);
296 tor_free(service_id
);
297 rend_cache_free_all();
298 rend_data_free(mock_rend_query
);
302 test_rend_cache_store_v2_desc_as_client_with_different_time(void *data
)
305 rend_data_t
*mock_rend_query
;
306 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
307 rend_service_descriptor_t
*generated
= NULL
;
308 smartlist_t
*descs
= smartlist_new();
310 char *service_id
= NULL
;
311 rend_encoded_v2_service_descriptor_t
*desc_holder_newer
;
312 rend_encoded_v2_service_descriptor_t
*desc_holder_older
;
317 create_descriptor(&generated
, &service_id
, 3);
319 generated
->timestamp
= t
+ RECENT_TIME
;
320 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
321 REND_NO_AUTH
, NULL
, NULL
);
322 desc_holder_newer
= ((rend_encoded_v2_service_descriptor_t
*)
323 smartlist_get(descs
, 0));
324 smartlist_set(descs
, 0, NULL
);
326 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
327 rend_encoded_v2_service_descriptor_free(d
));
328 smartlist_free(descs
);
329 descs
= smartlist_new();
331 generated
->timestamp
= (t
+ RECENT_TIME
) - 20;
332 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
333 REND_NO_AUTH
, NULL
, NULL
);
334 desc_holder_older
= ((rend_encoded_v2_service_descriptor_t
*)
335 smartlist_get(descs
, 0));
336 smartlist_set(descs
, 0, NULL
);
339 // Test when a descriptor is already in the cache and it is newer than the
341 mock_rend_query
= mock_rend_data(service_id
);
342 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
343 desc_holder_newer
->desc_id
, DIGEST_LEN
);
344 rend_cache_store_v2_desc_as_client(desc_holder_newer
->desc_str
,
345 desc_id_base32
, mock_rend_query
, NULL
);
346 ret
= rend_cache_store_v2_desc_as_client(desc_holder_older
->desc_str
,
347 desc_id_base32
, mock_rend_query
,
349 tt_int_op(ret
, OP_EQ
, 0);
351 rend_cache_free_all();
353 // Test when an old descriptor is in the cache and we submit a newer one
355 rend_cache_store_v2_desc_as_client(desc_holder_older
->desc_str
,
356 desc_id_base32
, mock_rend_query
, NULL
);
357 ret
= rend_cache_store_v2_desc_as_client(desc_holder_newer
->desc_str
,
358 desc_id_base32
, mock_rend_query
,
360 tt_int_op(ret
, OP_EQ
, 0);
363 rend_encoded_v2_service_descriptor_free(desc_holder_newer
);
364 rend_encoded_v2_service_descriptor_free(desc_holder_older
);
365 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
366 rend_encoded_v2_service_descriptor_free(d
));
367 smartlist_free(descs
);
368 rend_service_descriptor_free(generated
);
369 tor_free(service_id
);
370 rend_cache_free_all();
371 rend_data_free(mock_rend_query
);
374 #define NS_SUBMODULE lookup_v2_desc_as_dir
375 NS_DECL(const routerinfo_t
*, router_get_my_routerinfo
, (void));
377 static routerinfo_t
*mock_routerinfo
;
379 static const routerinfo_t
*
380 NS(router_get_my_routerinfo
)(void)
382 if (!mock_routerinfo
) {
383 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
386 return mock_routerinfo
;
390 test_rend_cache_lookup_v2_desc_as_dir(void *data
)
393 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
394 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
395 char *service_id
= NULL
;
396 const char *ret_desc
= NULL
;
400 NS_MOCK(router_get_my_routerinfo
);
404 // Test invalid base32
405 ret
= rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL
);
406 tt_int_op(ret
, OP_EQ
, -1);
408 // Test non-existent descriptor but well formed
409 ret
= rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje",
411 tt_int_op(ret
, OP_EQ
, 0);
413 // Test existing descriptor
414 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
415 rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
416 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
418 ret
= rend_cache_lookup_v2_desc_as_dir(desc_id_base32
, &ret_desc
);
419 tt_int_op(ret
, OP_EQ
, 1);
423 NS_UNMOCK(router_get_my_routerinfo
);
424 tor_free(mock_routerinfo
);
425 rend_cache_free_all();
426 rend_encoded_v2_service_descriptor_free(desc_holder
);
427 tor_free(service_id
);
432 #define NS_SUBMODULE store_v2_desc_as_dir
433 NS_DECL(const routerinfo_t
*, router_get_my_routerinfo
, (void));
435 static const routerinfo_t
*
436 NS(router_get_my_routerinfo
)(void)
438 return mock_routerinfo
;
442 test_rend_cache_store_v2_desc_as_dir(void *data
)
446 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
447 char *service_id
= NULL
;
449 NS_MOCK(router_get_my_routerinfo
);
453 // Test when we can't parse the descriptor
454 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
455 ret
= rend_cache_store_v2_desc_as_dir("unparseable");
456 tt_int_op(ret
, OP_EQ
, -1);
458 // Test when we have an old descriptor
459 generate_desc(TIME_IN_THE_PAST
, &desc_holder
, &service_id
, 3);
460 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
461 tt_int_op(ret
, OP_EQ
, 0);
463 rend_encoded_v2_service_descriptor_free(desc_holder
);
464 tor_free(service_id
);
466 // Test when we have a descriptor in the future
467 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
468 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
469 tt_int_op(ret
, OP_EQ
, 0);
471 rend_encoded_v2_service_descriptor_free(desc_holder
);
472 tor_free(service_id
);
474 // Test when two descriptors
475 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
476 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
477 tt_int_op(ret
, OP_EQ
, 0);
479 rend_encoded_v2_service_descriptor_free(desc_holder
);
480 tor_free(service_id
);
482 // Test when asking for hidden service statistics HiddenServiceStatistics
484 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
485 get_options_mutable()->HiddenServiceStatistics
= 1;
486 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
487 tt_int_op(ret
, OP_EQ
, 0);
490 NS_UNMOCK(router_get_my_routerinfo
);
491 rend_encoded_v2_service_descriptor_free(desc_holder
);
492 tor_free(service_id
);
493 rend_cache_free_all();
494 tor_free(mock_routerinfo
);
498 test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data
)
503 rend_service_descriptor_t
*generated
= NULL
;
504 smartlist_t
*descs
= smartlist_new();
506 char *service_id
= NULL
;
507 rend_encoded_v2_service_descriptor_t
*desc_holder_newer
;
508 rend_encoded_v2_service_descriptor_t
*desc_holder_older
;
510 NS_MOCK(router_get_my_routerinfo
);
516 create_descriptor(&generated
, &service_id
, 3);
517 generated
->timestamp
= t
+ RECENT_TIME
;
518 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
519 REND_NO_AUTH
, NULL
, NULL
);
520 desc_holder_newer
= ((rend_encoded_v2_service_descriptor_t
*)
521 smartlist_get(descs
, 0));
522 smartlist_set(descs
, 0, NULL
);
523 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
524 rend_encoded_v2_service_descriptor_free(d
));
525 smartlist_free(descs
);
526 descs
= smartlist_new();
528 generated
->timestamp
= (t
+ RECENT_TIME
) - 20;
529 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
530 REND_NO_AUTH
, NULL
, NULL
);
531 desc_holder_older
= ((rend_encoded_v2_service_descriptor_t
*)
532 smartlist_get(descs
, 0));
533 smartlist_set(descs
, 0, NULL
);
535 // Test when we have a newer descriptor stored
536 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
537 rend_cache_store_v2_desc_as_dir(desc_holder_newer
->desc_str
);
538 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_older
->desc_str
);
539 tt_int_op(ret
, OP_EQ
, 0);
541 // Test when we have an old descriptor stored
543 rend_cache_store_v2_desc_as_dir(desc_holder_older
->desc_str
);
544 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_newer
->desc_str
);
545 tt_int_op(ret
, OP_EQ
, 0);
548 NS_UNMOCK(router_get_my_routerinfo
);
549 rend_cache_free_all();
550 rend_service_descriptor_free(generated
);
551 tor_free(service_id
);
552 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
553 rend_encoded_v2_service_descriptor_free(d
));
554 smartlist_free(descs
);
555 rend_encoded_v2_service_descriptor_free(desc_holder_newer
);
556 rend_encoded_v2_service_descriptor_free(desc_holder_older
);
557 tor_free(mock_routerinfo
);
561 test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data
)
566 rend_service_descriptor_t
*generated
= NULL
;
567 smartlist_t
*descs
= smartlist_new();
569 char *service_id
= NULL
;
570 rend_encoded_v2_service_descriptor_t
*desc_holder_one
= NULL
;
571 rend_encoded_v2_service_descriptor_t
*desc_holder_two
= NULL
;
573 NS_MOCK(router_get_my_routerinfo
);
579 create_descriptor(&generated
, &service_id
, 3);
580 generated
->timestamp
= t
+ RECENT_TIME
;
581 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
582 REND_NO_AUTH
, NULL
, NULL
);
583 desc_holder_one
= ((rend_encoded_v2_service_descriptor_t
*)
584 smartlist_get(descs
, 0));
585 smartlist_set(descs
, 0, NULL
);
587 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
588 rend_encoded_v2_service_descriptor_free(d
));
589 smartlist_free(descs
);
590 descs
= smartlist_new();
592 generated
->timestamp
= t
+ RECENT_TIME
;
593 generated
->protocols
= 41;
594 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
595 REND_NO_AUTH
, NULL
, NULL
);
596 desc_holder_two
= ((rend_encoded_v2_service_descriptor_t
*)
597 smartlist_get(descs
, 0));
598 smartlist_set(descs
, 0, NULL
);
600 // Test when we have another descriptor stored, with a different descriptor
601 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
602 rend_cache_store_v2_desc_as_dir(desc_holder_one
->desc_str
);
603 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_two
->desc_str
);
604 tt_int_op(ret
, OP_EQ
, 0);
607 NS_UNMOCK(router_get_my_routerinfo
);
608 rend_cache_free_all();
609 rend_service_descriptor_free(generated
);
610 tor_free(service_id
);
611 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
612 rend_encoded_v2_service_descriptor_free(d
));
613 smartlist_free(descs
);
614 rend_encoded_v2_service_descriptor_free(desc_holder_one
);
615 rend_encoded_v2_service_descriptor_free(desc_holder_two
);
621 test_rend_cache_init(void *data
)
625 tt_assert_msg(!rend_cache
, "rend_cache should be NULL when starting");
626 tt_assert_msg(!rend_cache_v2_dir
, "rend_cache_v2_dir should be NULL "
628 tt_assert_msg(!rend_cache_failure
, "rend_cache_failure should be NULL when "
633 tt_assert_msg(rend_cache
, "rend_cache should not be NULL after initing");
634 tt_assert_msg(rend_cache_v2_dir
, "rend_cache_v2_dir should not be NULL "
636 tt_assert_msg(rend_cache_failure
, "rend_cache_failure should not be NULL "
639 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
640 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
641 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
644 rend_cache_free_all();
648 test_rend_cache_decrement_allocation(void *data
)
652 // Test when the cache has enough allocations
653 rend_cache_total_allocation
= 10;
654 rend_cache_decrement_allocation(3);
655 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 7);
657 // Test when there are not enough allocations
658 rend_cache_total_allocation
= 1;
659 setup_full_capture_of_logs(LOG_WARN
);
660 rend_cache_decrement_allocation(2);
661 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 0);
662 expect_single_log_msg_containing(
663 "Underflow in rend_cache_decrement_allocation");
664 teardown_capture_of_logs();
667 rend_cache_decrement_allocation(2);
668 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 0);
671 teardown_capture_of_logs();
675 test_rend_cache_increment_allocation(void *data
)
679 // Test when the cache is not overflowing
680 rend_cache_total_allocation
= 5;
681 rend_cache_increment_allocation(3);
682 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 8);
684 // Test when there are too many allocations
685 rend_cache_total_allocation
= SIZE_MAX
-1;
686 setup_full_capture_of_logs(LOG_WARN
);
687 rend_cache_increment_allocation(2);
688 tt_u64_op(rend_cache_total_allocation
, OP_EQ
, SIZE_MAX
);
689 expect_single_log_msg_containing(
690 "Overflow in rend_cache_increment_allocation");
691 teardown_capture_of_logs();
694 rend_cache_increment_allocation(2);
695 tt_u64_op(rend_cache_total_allocation
, OP_EQ
, SIZE_MAX
);
698 teardown_capture_of_logs();
702 test_rend_cache_failure_intro_entry_new(void *data
)
705 rend_cache_failure_intro_t
*entry
;
706 rend_intro_point_failure_t failure
;
710 failure
= INTRO_POINT_FAILURE_TIMEOUT
;
712 entry
= rend_cache_failure_intro_entry_new(failure
);
714 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_TIMEOUT
);
715 tt_int_op(entry
->created_ts
, OP_GE
, now
-5);
716 tt_int_op(entry
->created_ts
, OP_LE
, now
+5);
723 test_rend_cache_failure_intro_lookup(void *data
)
727 rend_cache_failure_t
*failure
;
728 rend_cache_failure_intro_t
*ip
;
729 rend_cache_failure_intro_t
*entry
;
730 const char key_ip_one
[DIGEST_LEN
] = "ip1";
731 const char key_ip_two
[DIGEST_LEN
] = "ip2";
732 const char key_foo
[DIGEST_LEN
] = "foo1";
736 failure
= rend_cache_failure_entry_new();
737 ip
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
738 digestmap_set(failure
->intro_failures
, key_ip_one
, ip
);
739 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
742 ret
= cache_failure_intro_lookup((const uint8_t *) key_foo
, "foo2", NULL
);
743 tt_int_op(ret
, OP_EQ
, 0);
745 // Test found with no intro failures in it
746 ret
= cache_failure_intro_lookup((const uint8_t *) key_ip_two
, "foo1", NULL
);
747 tt_int_op(ret
, OP_EQ
, 0);
750 ret
= cache_failure_intro_lookup((const uint8_t *) key_ip_one
, "foo1", NULL
);
751 tt_int_op(ret
, OP_EQ
, 1);
753 // Test found and asking for entry
754 cache_failure_intro_lookup((const uint8_t *) key_ip_one
, "foo1", &entry
);
756 tt_assert(entry
== ip
);
759 rend_cache_free_all();
763 test_rend_cache_clean(void *data
)
765 rend_cache_entry_t
*one
, *two
;
766 rend_service_descriptor_t
*desc_one
, *desc_two
;
767 strmap_iter_t
*iter
= NULL
;
775 // Test with empty rendcache
776 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
777 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
779 // Test with two old entries
780 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
781 two
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
782 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
783 desc_two
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
784 one
->parsed
= desc_one
;
785 two
->parsed
= desc_two
;
787 desc_one
->timestamp
= time(NULL
) + TIME_IN_THE_PAST
;
788 desc_two
->timestamp
= (time(NULL
) + TIME_IN_THE_PAST
) - 10;
789 desc_one
->pk
= pk_generate(0);
790 desc_two
->pk
= pk_generate(1);
792 strmap_set_lc(rend_cache
, "foo1", one
);
793 strmap_set_lc(rend_cache
, "foo2", two
);
795 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
796 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
798 // Test with one old entry and one newer entry
799 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
800 two
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
801 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
802 desc_two
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
803 one
->parsed
= desc_one
;
804 two
->parsed
= desc_two
;
806 desc_one
->timestamp
= (time(NULL
) + TIME_IN_THE_PAST
) - 10;
807 desc_two
->timestamp
= time(NULL
) - 100;
808 desc_one
->pk
= pk_generate(0);
809 desc_two
->pk
= pk_generate(1);
811 strmap_set_lc(rend_cache
, "foo1", one
);
812 strmap_set_lc(rend_cache
, "foo2", two
);
814 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
815 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 1);
817 iter
= strmap_iter_init(rend_cache
);
818 strmap_iter_get(iter
, &key
, &val
);
819 tt_str_op(key
, OP_EQ
, "foo2");
822 rend_cache_free_all();
826 test_rend_cache_failure_entry_new(void *data
)
828 rend_cache_failure_t
*failure
;
832 failure
= rend_cache_failure_entry_new();
834 tt_int_op(digestmap_size(failure
->intro_failures
), OP_EQ
, 0);
837 rend_cache_failure_entry_free(failure
);
841 test_rend_cache_failure_entry_free(void *data
)
845 // Test that it can deal with a NULL argument
846 rend_cache_failure_entry_free(NULL
);
853 test_rend_cache_failure_clean(void *data
)
855 rend_cache_failure_t
*failure
;
856 rend_cache_failure_intro_t
*ip_one
, *ip_two
;
858 const char key_one
[DIGEST_LEN
] = "ip1";
859 const char key_two
[DIGEST_LEN
] = "ip2";
865 // Test with empty failure cache
866 rend_cache_failure_clean(time(NULL
));
867 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
869 // Test with one empty failure entry
870 failure
= rend_cache_failure_entry_new();
871 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
872 rend_cache_failure_clean(time(NULL
));
873 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
875 // Test with one new intro point
876 failure
= rend_cache_failure_entry_new();
877 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
878 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
879 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
880 rend_cache_failure_clean(time(NULL
));
881 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 1);
883 // Test with one old intro point
884 rend_cache_failure_purge();
885 failure
= rend_cache_failure_entry_new();
886 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
887 ip_one
->created_ts
= time(NULL
) - 7*60;
888 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
889 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
890 rend_cache_failure_clean(time(NULL
));
891 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
893 // Test with one old intro point and one new one
894 rend_cache_failure_purge();
895 failure
= rend_cache_failure_entry_new();
896 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
897 ip_one
->created_ts
= time(NULL
) - 7*60;
898 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
899 ip_two
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
900 ip_two
->created_ts
= time(NULL
) - 2*60;
901 digestmap_set(failure
->intro_failures
, key_two
, ip_two
);
902 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
903 rend_cache_failure_clean(time(NULL
));
904 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 1);
905 tt_int_op(digestmap_size(failure
->intro_failures
), OP_EQ
, 1);
908 rend_cache_free_all();
912 test_rend_cache_failure_remove(void *data
)
914 rend_service_descriptor_t
*desc
;
919 // Test that it deals well with a NULL desc
920 rend_cache_failure_remove(NULL
);
922 // Test a descriptor that isn't in the cache
923 desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
924 desc
->pk
= pk_generate(0);
925 rend_cache_failure_remove(desc
);
927 // There seems to not exist any way of getting rend_cache_failure_remove()
928 // to fail because of a problem with rend_get_service_id from here
929 rend_cache_free_all();
931 rend_service_descriptor_free(desc
);
937 test_rend_cache_free_all(void *data
)
939 rend_cache_failure_t
*failure
;
940 rend_cache_entry_t
*one
;
941 rend_service_descriptor_t
*desc_one
;
947 failure
= rend_cache_failure_entry_new();
948 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
950 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
951 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
952 one
->parsed
= desc_one
;
953 desc_one
->timestamp
= time(NULL
) + TIME_IN_THE_PAST
;
954 desc_one
->pk
= pk_generate(0);
955 strmap_set_lc(rend_cache
, "foo1", one
);
957 rend_cache_free_all();
959 tt_assert(!rend_cache
);
960 tt_assert(!rend_cache_v2_dir
);
961 tt_assert(!rend_cache_failure
);
962 tt_assert(!rend_cache_total_allocation
);
965 rend_cache_free_all();
969 test_rend_cache_entry_free(void *data
)
972 rend_cache_entry_t
*e
;
974 // Handles NULL correctly
975 rend_cache_entry_free(NULL
);
977 // Handles NULL descriptor correctly
978 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
979 rend_cache_entry_free(e
);
981 // Handles non-NULL descriptor correctly
982 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
983 e
->desc
= tor_malloc(10);
984 rend_cache_entry_free(e
);
991 test_rend_cache_purge(void *data
)
995 // Deals with a NULL rend_cache
997 tt_assert(rend_cache
);
998 tt_assert(strmap_size(rend_cache
) == 0);
1000 // Deals with existing rend_cache
1001 rend_cache_free_all();
1003 tt_assert(rend_cache
);
1004 tt_assert(strmap_size(rend_cache
) == 0);
1007 tt_assert(rend_cache
);
1008 tt_assert(strmap_size(rend_cache
) == 0);
1011 rend_cache_free_all();
1015 test_rend_cache_failure_intro_add(void *data
)
1018 rend_cache_failure_t
*fail_entry
;
1019 rend_cache_failure_intro_t
*entry
;
1020 const char identity
[DIGEST_LEN
] = "foo1";
1024 // Adds non-existing entry
1025 cache_failure_intro_add((const uint8_t *) identity
, "foo2",
1026 INTRO_POINT_FAILURE_TIMEOUT
);
1027 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1028 tt_assert(fail_entry
);
1029 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1030 entry
= digestmap_get(fail_entry
->intro_failures
, identity
);
1033 // Adds existing entry
1034 cache_failure_intro_add((const uint8_t *) identity
, "foo2",
1035 INTRO_POINT_FAILURE_TIMEOUT
);
1036 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1037 tt_assert(fail_entry
);
1038 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1039 entry
= digestmap_get(fail_entry
->intro_failures
, identity
);
1043 rend_cache_free_all();
1047 test_rend_cache_intro_failure_note(void *data
)
1050 rend_cache_failure_t
*fail_entry
;
1051 rend_cache_failure_intro_t
*entry
;
1052 const char key
[DIGEST_LEN
] = "foo1";
1057 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT
,
1058 (const uint8_t *) key
, "foo2");
1059 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1060 tt_assert(fail_entry
);
1061 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1062 entry
= digestmap_get(fail_entry
->intro_failures
, key
);
1064 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_TIMEOUT
);
1067 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE
,
1068 (const uint8_t *) key
, "foo2");
1069 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_UNREACHABLE
);
1072 rend_cache_free_all();
1075 #define NS_SUBMODULE clean_v2_descs_as_dir
1078 test_rend_cache_clean_v2_descs_as_dir(void *data
)
1080 rend_cache_entry_t
*e
;
1082 rend_service_descriptor_t
*desc
;
1084 const char key
[DIGEST_LEN
] = "abcde";
1090 // Test running with an empty cache
1091 rend_cache_clean_v2_descs_as_dir(now
, 0);
1092 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
1094 // Test with only one new entry
1095 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
1096 e
->last_served
= now
;
1097 desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
1098 desc
->timestamp
= now
;
1099 desc
->pk
= pk_generate(0);
1101 digestmap_set(rend_cache_v2_dir
, key
, e
);
1103 rend_cache_clean_v2_descs_as_dir(now
, 0);
1104 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 1);
1106 // Test with one old entry
1107 desc
->timestamp
= now
- (REND_CACHE_MAX_AGE
+ REND_CACHE_MAX_SKEW
+ 1000);
1108 rend_cache_clean_v2_descs_as_dir(now
, 0);
1109 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
1111 // Test with one entry that has an old last served
1112 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
1113 e
->last_served
= now
- (REND_CACHE_MAX_AGE
+ REND_CACHE_MAX_SKEW
+ 1000);
1114 desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
1115 desc
->timestamp
= now
;
1116 desc
->pk
= pk_generate(0);
1118 digestmap_set(rend_cache_v2_dir
, key
, e
);
1120 rend_cache_clean_v2_descs_as_dir(now
, 0);
1121 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
1123 // Test a run through asking for a large force_remove
1124 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
1125 e
->last_served
= now
;
1126 desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
1127 desc
->timestamp
= now
;
1128 desc
->pk
= pk_generate(0);
1130 digestmap_set(rend_cache_v2_dir
, key
, e
);
1132 rend_cache_clean_v2_descs_as_dir(now
, 20000);
1133 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 1);
1136 rend_cache_free_all();
1142 test_rend_cache_entry_allocation(void *data
)
1147 rend_cache_entry_t
*e
= NULL
;
1149 // Handles a null argument
1150 ret
= rend_cache_entry_allocation(NULL
);
1151 tt_int_op(ret
, OP_EQ
, 0);
1153 // Handles a non-null argument
1154 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
1155 ret
= rend_cache_entry_allocation(e
);
1156 tt_int_op(ret
, OP_GT
, sizeof(rend_cache_entry_t
));
1163 test_rend_cache_failure_intro_entry_free(void *data
)
1166 rend_cache_failure_intro_t
*entry
;
1168 // Handles a null argument
1169 rend_cache_failure_intro_entry_free(NULL
);
1171 // Handles a non-null argument
1172 entry
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
1173 rend_cache_failure_intro_entry_free(entry
);
1177 test_rend_cache_failure_purge(void *data
)
1181 // Handles a null failure cache
1182 strmap_free(rend_cache_failure
, rend_cache_failure_entry_free_
);
1183 rend_cache_failure
= NULL
;
1185 rend_cache_failure_purge();
1187 tt_ptr_op(rend_cache_failure
, OP_NE
, NULL
);
1188 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
1191 rend_cache_free_all();
1195 test_rend_cache_validate_intro_point_failure(void *data
)
1198 rend_service_descriptor_t
*desc
= NULL
;
1199 char *service_id
= NULL
;
1200 rend_intro_point_t
*intro
= NULL
;
1201 const char *identity
= NULL
;
1202 rend_cache_failure_t
*failure
;
1203 rend_cache_failure_intro_t
*ip
;
1207 create_descriptor(&desc
, &service_id
, 3);
1208 desc
->timestamp
= time(NULL
) + RECENT_TIME
;
1210 intro
= (rend_intro_point_t
*)smartlist_get(desc
->intro_nodes
, 0);
1211 identity
= intro
->extend_info
->identity_digest
;
1213 failure
= rend_cache_failure_entry_new();
1214 ip
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
1215 digestmap_set(failure
->intro_failures
, identity
, ip
);
1216 strmap_set_lc(rend_cache_failure
, service_id
, failure
);
1218 // Test when we have an intro point in our cache
1219 validate_intro_point_failure(desc
, service_id
);
1220 tt_int_op(smartlist_len(desc
->intro_nodes
), OP_EQ
, 2);
1223 rend_cache_free_all();
1224 rend_service_descriptor_free(desc
);
1225 tor_free(service_id
);
1228 struct testcase_t rend_cache_tests
[] = {
1229 { "init", test_rend_cache_init
, 0, NULL
, NULL
},
1230 { "decrement_allocation", test_rend_cache_decrement_allocation
, 0,
1232 { "increment_allocation", test_rend_cache_increment_allocation
, 0,
1234 { "clean", test_rend_cache_clean
, TT_FORK
, NULL
, NULL
},
1235 { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir
, 0,
1237 { "entry_allocation", test_rend_cache_entry_allocation
, 0, NULL
, NULL
},
1238 { "entry_free", test_rend_cache_entry_free
, 0, NULL
, NULL
},
1239 { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free
, 0,
1241 { "free_all", test_rend_cache_free_all
, 0, NULL
, NULL
},
1242 { "purge", test_rend_cache_purge
, 0, NULL
, NULL
},
1243 { "failure_clean", test_rend_cache_failure_clean
, 0, NULL
, NULL
},
1244 { "failure_entry_new", test_rend_cache_failure_entry_new
, 0, NULL
, NULL
},
1245 { "failure_entry_free", test_rend_cache_failure_entry_free
, 0, NULL
, NULL
},
1246 { "failure_intro_add", test_rend_cache_failure_intro_add
, 0, NULL
, NULL
},
1247 { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new
, 0,
1249 { "failure_intro_lookup", test_rend_cache_failure_intro_lookup
, 0,
1251 { "failure_purge", test_rend_cache_failure_purge
, 0, NULL
, NULL
},
1252 { "failure_remove", test_rend_cache_failure_remove
, 0, NULL
, NULL
},
1253 { "intro_failure_note", test_rend_cache_intro_failure_note
, 0, NULL
, NULL
},
1254 { "lookup", test_rend_cache_lookup_entry
, 0, NULL
, NULL
},
1255 { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir
, 0,
1257 { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client
, 0,
1259 { "store_v2_desc_as_client_with_different_time",
1260 test_rend_cache_store_v2_desc_as_client_with_different_time
, 0,
1262 { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir
, 0,
1264 { "store_v2_desc_as_dir_with_different_time",
1265 test_rend_cache_store_v2_desc_as_dir_with_different_time
, 0, NULL
, NULL
},
1266 { "store_v2_desc_as_dir_with_different_content",
1267 test_rend_cache_store_v2_desc_as_dir_with_different_content
, 0,
1269 { "validate_intro_point_failure",
1270 test_rend_cache_validate_intro_point_failure
, 0, NULL
, NULL
},