1 /* Copyright (c) 2010-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
5 #include "core/or/or.h"
8 #define RENDCACHE_PRIVATE
9 #include "feature/rend/rendcache.h"
10 #include "feature/relay/router.h"
11 #include "feature/nodelist/routerlist.h"
12 #include "app/config/config.h"
13 #include "feature/hs/hs_common.h"
15 #include "core/or/extend_info_st.h"
16 #include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
17 #include "feature/rend/rend_intro_point_st.h"
18 #include "feature/rend/rend_service_descriptor_st.h"
19 #include "feature/nodelist/routerinfo_st.h"
21 #include "test/rend_test_helpers.h"
22 #include "test/log_test_helpers.h"
24 static const int RECENT_TIME
= -10;
25 static const int TIME_IN_THE_PAST
= -(REND_CACHE_MAX_AGE
+ \
26 REND_CACHE_MAX_SKEW
+ 60);
27 static const int TIME_IN_THE_FUTURE
= REND_CACHE_MAX_SKEW
+ 60;
30 test_rend_cache_lookup_entry(void *data
)
33 rend_data_t
*mock_rend_query
= NULL
;
34 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
35 rend_cache_entry_t
*entry
= NULL
;
36 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
37 char *service_id
= NULL
;
42 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
44 ret
= rend_cache_lookup_entry("abababababababab", 0, NULL
);
45 tt_int_op(ret
, OP_EQ
, -ENOENT
);
47 ret
= rend_cache_lookup_entry("invalid query", 2, NULL
);
48 tt_int_op(ret
, OP_EQ
, -EINVAL
);
50 ret
= rend_cache_lookup_entry("abababababababab", 2, NULL
);
51 tt_int_op(ret
, OP_EQ
, -ENOENT
);
53 ret
= rend_cache_lookup_entry("abababababababab", 4224, NULL
);
54 tt_int_op(ret
, OP_EQ
, -ENOENT
);
56 mock_rend_query
= mock_rend_data(service_id
);
57 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
59 rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
, desc_id_base32
,
60 mock_rend_query
, NULL
);
62 ret
= rend_cache_lookup_entry(service_id
, 2, NULL
);
63 tt_int_op(ret
, OP_EQ
, 0);
65 ret
= rend_cache_lookup_entry(service_id
, 2, &entry
);
66 tt_int_op(ret
, OP_EQ
, 0);
68 tt_int_op(entry
->len
, OP_EQ
, strlen(desc_holder
->desc_str
));
69 tt_str_op(entry
->desc
, OP_EQ
, desc_holder
->desc_str
);
72 rend_encoded_v2_service_descriptor_free(desc_holder
);
74 rend_cache_free_all();
75 rend_data_free(mock_rend_query
);
79 test_rend_cache_store_v2_desc_as_client(void *data
)
82 rend_data_t
*mock_rend_query
;
83 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
84 rend_cache_entry_t
*entry
= NULL
;
85 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
86 char *service_id
= NULL
;
87 char client_cookie
[REND_DESC_COOKIE_LEN
];
92 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
95 mock_rend_query
= mock_rend_data(service_id
);
96 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
98 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
99 desc_id_base32
, mock_rend_query
,
102 tt_int_op(ret
, OP_EQ
, 0);
104 tt_int_op(entry
->len
, OP_EQ
, strlen(desc_holder
->desc_str
));
105 tt_str_op(entry
->desc
, OP_EQ
, desc_holder
->desc_str
);
107 // Test various failure modes
109 // TODO: a too long desc_id_base32 argument crashes the function
110 /* ret = rend_cache_store_v2_desc_as_client( */
111 /* desc_holder->desc_str, */
112 /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */
113 /* &mock_rend_query, NULL); */
114 /* tt_int_op(ret, OP_EQ, -1); */
116 // Test bad base32 failure
117 // This causes an assertion failure if we're running with assertions.
118 // But when building without asserts, we can test it.
119 #ifdef DISABLE_ASSERTS_IN_UNIT_TESTS
120 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
121 "!xqunszqnaolrrfmtzgaki7mxelgvkj", mock_rend_query
, NULL
);
122 tt_int_op(ret
, OP_EQ
, -1);
125 // Test invalid descriptor
126 ret
= rend_cache_store_v2_desc_as_client("invalid descriptor",
127 "3xqunszqnaolrrfmtzgaki7mxelgvkje", mock_rend_query
, NULL
);
128 tt_int_op(ret
, OP_EQ
, -1);
130 // TODO: it doesn't seem to be possible to test invalid service ID condition.
131 // that means it is likely not possible to have that condition without
132 // earlier conditions failing first (such as signature checking of the desc)
134 rend_cache_free_all();
136 // Test mismatch between service ID and onion address
138 strncpy(TO_REND_DATA_V2(mock_rend_query
)->onion_address
, "abc",
139 REND_SERVICE_ID_LEN_BASE32
+1);
140 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
142 mock_rend_query
, NULL
);
143 tt_int_op(ret
, OP_EQ
, -1);
144 rend_cache_free_all();
145 rend_data_free(mock_rend_query
);
147 // Test incorrect descriptor ID
149 mock_rend_query
= mock_rend_data(service_id
);
150 char orig
= desc_id_base32
[0];
151 if (desc_id_base32
[0] == 'a')
152 desc_id_base32
[0] = 'b';
154 desc_id_base32
[0] = 'a';
155 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
156 desc_id_base32
, mock_rend_query
,
158 tt_int_op(ret
, OP_EQ
, -1);
159 desc_id_base32
[0] = orig
;
160 rend_cache_free_all();
162 // Test too old descriptor
164 rend_encoded_v2_service_descriptor_free(desc_holder
);
165 tor_free(service_id
);
166 rend_data_free(mock_rend_query
);
168 generate_desc(TIME_IN_THE_PAST
, &desc_holder
, &service_id
, 3);
169 mock_rend_query
= mock_rend_data(service_id
);
170 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
173 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
175 mock_rend_query
, NULL
);
176 tt_int_op(ret
, OP_EQ
, -1);
177 rend_cache_free_all();
179 // Test too new descriptor (in the future)
181 rend_encoded_v2_service_descriptor_free(desc_holder
);
182 tor_free(service_id
);
183 rend_data_free(mock_rend_query
);
185 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
186 mock_rend_query
= mock_rend_data(service_id
);
187 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
190 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
191 desc_id_base32
, mock_rend_query
,
193 tt_int_op(ret
, OP_EQ
, -1);
194 rend_cache_free_all();
196 // Test when a descriptor is already in the cache
198 rend_encoded_v2_service_descriptor_free(desc_holder
);
199 tor_free(service_id
);
200 rend_data_free(mock_rend_query
);
202 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
203 mock_rend_query
= mock_rend_data(service_id
);
204 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
207 rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
, desc_id_base32
,
208 mock_rend_query
, NULL
);
209 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
210 desc_id_base32
, mock_rend_query
,
212 tt_int_op(ret
, OP_EQ
, 0);
214 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
215 desc_id_base32
, mock_rend_query
,
217 tt_int_op(ret
, OP_EQ
, 0);
219 rend_cache_free_all();
221 // Test unsuccessful decrypting of introduction points
223 rend_encoded_v2_service_descriptor_free(desc_holder
);
224 tor_free(service_id
);
225 rend_data_free(mock_rend_query
);
227 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
228 mock_rend_query
= mock_rend_data(service_id
);
229 TO_REND_DATA_V2(mock_rend_query
)->auth_type
= REND_BASIC_AUTH
;
230 client_cookie
[0] = 'A';
231 memcpy(TO_REND_DATA_V2(mock_rend_query
)->descriptor_cookie
, client_cookie
,
232 REND_DESC_COOKIE_LEN
);
233 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
235 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
236 desc_id_base32
, mock_rend_query
,
238 tt_int_op(ret
, OP_EQ
, 0);
239 rend_cache_free_all();
241 // Test successful run when we have REND_BASIC_AUTH but not cookie
243 rend_encoded_v2_service_descriptor_free(desc_holder
);
244 tor_free(service_id
);
245 rend_data_free(mock_rend_query
);
247 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
248 mock_rend_query
= mock_rend_data(service_id
);
249 TO_REND_DATA_V2(mock_rend_query
)->auth_type
= REND_BASIC_AUTH
;
250 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
252 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
253 desc_id_base32
, mock_rend_query
,
255 tt_int_op(ret
, OP_EQ
, 0);
257 rend_cache_free_all();
259 // Test when we have no introduction points
261 rend_encoded_v2_service_descriptor_free(desc_holder
);
262 tor_free(service_id
);
263 rend_data_free(mock_rend_query
);
265 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 0);
266 mock_rend_query
= mock_rend_data(service_id
);
267 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
269 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
270 desc_id_base32
, mock_rend_query
,
272 tt_int_op(ret
, OP_EQ
, -1);
273 rend_cache_free_all();
275 // Test when we have too many intro points
277 rend_encoded_v2_service_descriptor_free(desc_holder
);
278 tor_free(service_id
);
279 rend_data_free(mock_rend_query
);
281 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, MAX_INTRO_POINTS
+1);
282 mock_rend_query
= mock_rend_data(service_id
);
283 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
285 ret
= rend_cache_store_v2_desc_as_client(desc_holder
->desc_str
,
286 desc_id_base32
, mock_rend_query
,
288 tt_int_op(ret
, OP_EQ
, -1);
291 rend_encoded_v2_service_descriptor_free(desc_holder
);
292 tor_free(service_id
);
293 rend_cache_free_all();
294 rend_data_free(mock_rend_query
);
298 test_rend_cache_store_v2_desc_as_client_with_different_time(void *data
)
301 rend_data_t
*mock_rend_query
;
302 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
303 rend_service_descriptor_t
*generated
= NULL
;
304 smartlist_t
*descs
= smartlist_new();
306 char *service_id
= NULL
;
307 rend_encoded_v2_service_descriptor_t
*desc_holder_newer
;
308 rend_encoded_v2_service_descriptor_t
*desc_holder_older
;
313 create_descriptor(&generated
, &service_id
, 3);
315 generated
->timestamp
= t
+ RECENT_TIME
;
316 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
317 REND_NO_AUTH
, NULL
, NULL
);
318 desc_holder_newer
= ((rend_encoded_v2_service_descriptor_t
*)
319 smartlist_get(descs
, 0));
320 smartlist_set(descs
, 0, NULL
);
322 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
323 rend_encoded_v2_service_descriptor_free(d
));
324 smartlist_free(descs
);
325 descs
= smartlist_new();
327 generated
->timestamp
= (t
+ RECENT_TIME
) - 20;
328 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
329 REND_NO_AUTH
, NULL
, NULL
);
330 desc_holder_older
= ((rend_encoded_v2_service_descriptor_t
*)
331 smartlist_get(descs
, 0));
332 smartlist_set(descs
, 0, NULL
);
335 // Test when a descriptor is already in the cache and it is newer than the
337 mock_rend_query
= mock_rend_data(service_id
);
338 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
339 desc_holder_newer
->desc_id
, DIGEST_LEN
);
340 rend_cache_store_v2_desc_as_client(desc_holder_newer
->desc_str
,
341 desc_id_base32
, mock_rend_query
, NULL
);
342 ret
= rend_cache_store_v2_desc_as_client(desc_holder_older
->desc_str
,
343 desc_id_base32
, mock_rend_query
,
345 tt_int_op(ret
, OP_EQ
, 0);
347 rend_cache_free_all();
349 // Test when an old descriptor is in the cache and we submit a newer one
351 rend_cache_store_v2_desc_as_client(desc_holder_older
->desc_str
,
352 desc_id_base32
, mock_rend_query
, NULL
);
353 ret
= rend_cache_store_v2_desc_as_client(desc_holder_newer
->desc_str
,
354 desc_id_base32
, mock_rend_query
,
356 tt_int_op(ret
, OP_EQ
, 0);
359 rend_encoded_v2_service_descriptor_free(desc_holder_newer
);
360 rend_encoded_v2_service_descriptor_free(desc_holder_older
);
361 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
362 rend_encoded_v2_service_descriptor_free(d
));
363 smartlist_free(descs
);
364 rend_service_descriptor_free(generated
);
365 tor_free(service_id
);
366 rend_cache_free_all();
367 rend_data_free(mock_rend_query
);
370 static const routerinfo_t
*rcache_lookup_v2_as_dir_get_my_routerinfo(void);
372 static routerinfo_t
*mock_routerinfo
;
374 static const routerinfo_t
*
375 rcache_lookup_v2_as_dir_get_my_routerinfo(void)
377 if (!mock_routerinfo
) {
378 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
381 return mock_routerinfo
;
385 test_rend_cache_lookup_v2_desc_as_dir(void *data
)
388 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
389 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
390 char *service_id
= NULL
;
391 const char *ret_desc
= NULL
;
395 MOCK(router_get_my_routerinfo
,
396 rcache_lookup_v2_as_dir_get_my_routerinfo
);
400 // Test invalid base32
401 ret
= rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL
);
402 tt_int_op(ret
, OP_EQ
, -1);
404 // Test non-existent descriptor but well formed
405 ret
= rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje",
407 tt_int_op(ret
, OP_EQ
, 0);
409 // Test existing descriptor
410 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
411 rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
412 base32_encode(desc_id_base32
, sizeof(desc_id_base32
), desc_holder
->desc_id
,
414 ret
= rend_cache_lookup_v2_desc_as_dir(desc_id_base32
, &ret_desc
);
415 tt_int_op(ret
, OP_EQ
, 1);
419 UNMOCK(router_get_my_routerinfo
);
420 tor_free(mock_routerinfo
);
421 rend_cache_free_all();
422 rend_encoded_v2_service_descriptor_free(desc_holder
);
423 tor_free(service_id
);
426 static const routerinfo_t
*rcache_store_v2_as_dir_get_my_routerinfo(void);
428 static const routerinfo_t
*
429 rcache_store_v2_as_dir_get_my_routerinfo(void)
431 return mock_routerinfo
;
435 test_rend_cache_store_v2_desc_as_dir(void *data
)
439 rend_encoded_v2_service_descriptor_t
*desc_holder
= NULL
;
440 char *service_id
= NULL
;
442 MOCK(router_get_my_routerinfo
,
443 rcache_store_v2_as_dir_get_my_routerinfo
);
447 // Test when we can't parse the descriptor
448 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
449 ret
= rend_cache_store_v2_desc_as_dir("unparseable");
450 tt_int_op(ret
, OP_EQ
, -1);
452 // Test when we have an old descriptor
453 generate_desc(TIME_IN_THE_PAST
, &desc_holder
, &service_id
, 3);
454 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
455 tt_int_op(ret
, OP_EQ
, 0);
457 rend_encoded_v2_service_descriptor_free(desc_holder
);
458 tor_free(service_id
);
460 // Test when we have a descriptor in the future
461 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
462 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
463 tt_int_op(ret
, OP_EQ
, 0);
465 rend_encoded_v2_service_descriptor_free(desc_holder
);
466 tor_free(service_id
);
468 // Test when two descriptors
469 generate_desc(TIME_IN_THE_FUTURE
, &desc_holder
, &service_id
, 3);
470 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
471 tt_int_op(ret
, OP_EQ
, 0);
473 rend_encoded_v2_service_descriptor_free(desc_holder
);
474 tor_free(service_id
);
476 // Test when asking for hidden service statistics HiddenServiceStatistics
478 generate_desc(RECENT_TIME
, &desc_holder
, &service_id
, 3);
479 get_options_mutable()->HiddenServiceStatistics
= 1;
480 ret
= rend_cache_store_v2_desc_as_dir(desc_holder
->desc_str
);
481 tt_int_op(ret
, OP_EQ
, 0);
484 UNMOCK(router_get_my_routerinfo
);
485 rend_encoded_v2_service_descriptor_free(desc_holder
);
486 tor_free(service_id
);
487 rend_cache_free_all();
488 tor_free(mock_routerinfo
);
492 test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data
)
497 rend_service_descriptor_t
*generated
= NULL
;
498 smartlist_t
*descs
= smartlist_new();
500 char *service_id
= NULL
;
501 rend_encoded_v2_service_descriptor_t
*desc_holder_newer
;
502 rend_encoded_v2_service_descriptor_t
*desc_holder_older
;
504 MOCK(router_get_my_routerinfo
,
505 rcache_store_v2_as_dir_get_my_routerinfo
);
511 create_descriptor(&generated
, &service_id
, 3);
512 generated
->timestamp
= t
+ RECENT_TIME
;
513 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
514 REND_NO_AUTH
, NULL
, NULL
);
515 desc_holder_newer
= ((rend_encoded_v2_service_descriptor_t
*)
516 smartlist_get(descs
, 0));
517 smartlist_set(descs
, 0, NULL
);
518 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
519 rend_encoded_v2_service_descriptor_free(d
));
520 smartlist_free(descs
);
521 descs
= smartlist_new();
523 generated
->timestamp
= (t
+ RECENT_TIME
) - 20;
524 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
525 REND_NO_AUTH
, NULL
, NULL
);
526 desc_holder_older
= ((rend_encoded_v2_service_descriptor_t
*)
527 smartlist_get(descs
, 0));
528 smartlist_set(descs
, 0, NULL
);
530 // Test when we have a newer descriptor stored
531 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
532 rend_cache_store_v2_desc_as_dir(desc_holder_newer
->desc_str
);
533 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_older
->desc_str
);
534 tt_int_op(ret
, OP_EQ
, 0);
536 // Test when we have an old descriptor stored
538 rend_cache_store_v2_desc_as_dir(desc_holder_older
->desc_str
);
539 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_newer
->desc_str
);
540 tt_int_op(ret
, OP_EQ
, 0);
543 UNMOCK(router_get_my_routerinfo
);
544 rend_cache_free_all();
545 rend_service_descriptor_free(generated
);
546 tor_free(service_id
);
547 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
548 rend_encoded_v2_service_descriptor_free(d
));
549 smartlist_free(descs
);
550 rend_encoded_v2_service_descriptor_free(desc_holder_newer
);
551 rend_encoded_v2_service_descriptor_free(desc_holder_older
);
552 tor_free(mock_routerinfo
);
556 test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data
)
561 rend_service_descriptor_t
*generated
= NULL
;
562 smartlist_t
*descs
= smartlist_new();
564 char *service_id
= NULL
;
565 rend_encoded_v2_service_descriptor_t
*desc_holder_one
= NULL
;
566 rend_encoded_v2_service_descriptor_t
*desc_holder_two
= NULL
;
568 MOCK(router_get_my_routerinfo
,
569 rcache_store_v2_as_dir_get_my_routerinfo
);
575 create_descriptor(&generated
, &service_id
, 3);
576 generated
->timestamp
= t
+ RECENT_TIME
;
577 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
578 REND_NO_AUTH
, NULL
, NULL
);
579 desc_holder_one
= ((rend_encoded_v2_service_descriptor_t
*)
580 smartlist_get(descs
, 0));
581 smartlist_set(descs
, 0, NULL
);
583 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
584 rend_encoded_v2_service_descriptor_free(d
));
585 smartlist_free(descs
);
586 descs
= smartlist_new();
588 generated
->timestamp
= t
+ RECENT_TIME
;
589 generated
->protocols
= 41;
590 rend_encode_v2_descriptors(descs
, generated
, t
+ RECENT_TIME
, 0,
591 REND_NO_AUTH
, NULL
, NULL
);
592 desc_holder_two
= ((rend_encoded_v2_service_descriptor_t
*)
593 smartlist_get(descs
, 0));
594 smartlist_set(descs
, 0, NULL
);
596 // Test when we have another descriptor stored, with a different descriptor
597 mock_routerinfo
= tor_malloc(sizeof(routerinfo_t
));
598 rend_cache_store_v2_desc_as_dir(desc_holder_one
->desc_str
);
599 ret
= rend_cache_store_v2_desc_as_dir(desc_holder_two
->desc_str
);
600 tt_int_op(ret
, OP_EQ
, 0);
603 UNMOCK(router_get_my_routerinfo
);
604 rend_cache_free_all();
605 rend_service_descriptor_free(generated
);
606 tor_free(service_id
);
607 SMARTLIST_FOREACH(descs
, rend_encoded_v2_service_descriptor_t
*, d
,
608 rend_encoded_v2_service_descriptor_free(d
));
609 smartlist_free(descs
);
610 rend_encoded_v2_service_descriptor_free(desc_holder_one
);
611 rend_encoded_v2_service_descriptor_free(desc_holder_two
);
615 test_rend_cache_init(void *data
)
619 tt_assert_msg(!rend_cache
, "rend_cache should be NULL when starting");
620 tt_assert_msg(!rend_cache_v2_dir
, "rend_cache_v2_dir should be NULL "
622 tt_assert_msg(!rend_cache_failure
, "rend_cache_failure should be NULL when "
627 tt_assert_msg(rend_cache
, "rend_cache should not be NULL after initing");
628 tt_assert_msg(rend_cache_v2_dir
, "rend_cache_v2_dir should not be NULL "
630 tt_assert_msg(rend_cache_failure
, "rend_cache_failure should not be NULL "
633 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
634 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
635 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
638 rend_cache_free_all();
642 test_rend_cache_decrement_allocation(void *data
)
646 // Test when the cache has enough allocations
647 rend_cache_total_allocation
= 10;
648 rend_cache_decrement_allocation(3);
649 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 7);
651 // Test when there are not enough allocations
652 rend_cache_total_allocation
= 1;
653 setup_full_capture_of_logs(LOG_WARN
);
654 rend_cache_decrement_allocation(2);
655 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 0);
656 expect_single_log_msg_containing(
657 "Underflow in rend_cache_decrement_allocation");
658 teardown_capture_of_logs();
661 rend_cache_decrement_allocation(2);
662 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 0);
665 teardown_capture_of_logs();
669 test_rend_cache_increment_allocation(void *data
)
673 // Test when the cache is not overflowing
674 rend_cache_total_allocation
= 5;
675 rend_cache_increment_allocation(3);
676 tt_int_op(rend_cache_total_allocation
, OP_EQ
, 8);
678 // Test when there are too many allocations
679 rend_cache_total_allocation
= SIZE_MAX
-1;
680 setup_full_capture_of_logs(LOG_WARN
);
681 rend_cache_increment_allocation(2);
682 tt_u64_op(rend_cache_total_allocation
, OP_EQ
, SIZE_MAX
);
683 expect_single_log_msg_containing(
684 "Overflow in rend_cache_increment_allocation");
685 teardown_capture_of_logs();
688 rend_cache_increment_allocation(2);
689 tt_u64_op(rend_cache_total_allocation
, OP_EQ
, SIZE_MAX
);
692 teardown_capture_of_logs();
696 test_rend_cache_failure_intro_entry_new(void *data
)
699 rend_cache_failure_intro_t
*entry
;
700 rend_intro_point_failure_t failure
;
704 failure
= INTRO_POINT_FAILURE_TIMEOUT
;
706 entry
= rend_cache_failure_intro_entry_new(failure
);
708 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_TIMEOUT
);
709 tt_int_op(entry
->created_ts
, OP_GE
, now
-5);
710 tt_int_op(entry
->created_ts
, OP_LE
, now
+5);
717 test_rend_cache_failure_intro_lookup(void *data
)
721 rend_cache_failure_t
*failure
;
722 rend_cache_failure_intro_t
*ip
;
723 rend_cache_failure_intro_t
*entry
;
724 const char key_ip_one
[DIGEST_LEN
] = "ip1";
725 const char key_ip_two
[DIGEST_LEN
] = "ip2";
726 const char key_foo
[DIGEST_LEN
] = "foo1";
730 failure
= rend_cache_failure_entry_new();
731 ip
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
732 digestmap_set(failure
->intro_failures
, key_ip_one
, ip
);
733 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
736 ret
= cache_failure_intro_lookup((const uint8_t *) key_foo
, "foo2", NULL
);
737 tt_int_op(ret
, OP_EQ
, 0);
739 // Test found with no intro failures in it
740 ret
= cache_failure_intro_lookup((const uint8_t *) key_ip_two
, "foo1", NULL
);
741 tt_int_op(ret
, OP_EQ
, 0);
744 ret
= cache_failure_intro_lookup((const uint8_t *) key_ip_one
, "foo1", NULL
);
745 tt_int_op(ret
, OP_EQ
, 1);
747 // Test found and asking for entry
748 cache_failure_intro_lookup((const uint8_t *) key_ip_one
, "foo1", &entry
);
750 tt_assert(entry
== ip
);
753 rend_cache_free_all();
757 test_rend_cache_clean(void *data
)
759 rend_cache_entry_t
*one
, *two
;
760 rend_service_descriptor_t
*desc_one
, *desc_two
;
761 strmap_iter_t
*iter
= NULL
;
769 // Test with empty rendcache
770 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
771 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
773 // Test with two old entries
774 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
775 two
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
776 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
777 desc_two
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
778 one
->parsed
= desc_one
;
779 two
->parsed
= desc_two
;
781 desc_one
->timestamp
= time(NULL
) + TIME_IN_THE_PAST
;
782 desc_two
->timestamp
= (time(NULL
) + TIME_IN_THE_PAST
) - 10;
783 desc_one
->pk
= pk_generate(0);
784 desc_two
->pk
= pk_generate(1);
786 strmap_set_lc(rend_cache
, "foo1", one
);
787 rend_cache_increment_allocation(rend_cache_entry_allocation(one
));
788 strmap_set_lc(rend_cache
, "foo2", two
);
789 rend_cache_increment_allocation(rend_cache_entry_allocation(two
));
791 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
792 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 0);
794 // Test with one old entry and one newer entry
795 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
796 two
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
797 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
798 desc_two
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
799 one
->parsed
= desc_one
;
800 two
->parsed
= desc_two
;
802 desc_one
->timestamp
= (time(NULL
) + TIME_IN_THE_PAST
) - 10;
803 desc_two
->timestamp
= time(NULL
) - 100;
804 desc_one
->pk
= pk_generate(0);
805 desc_two
->pk
= pk_generate(1);
807 rend_cache_increment_allocation(rend_cache_entry_allocation(one
));
808 strmap_set_lc(rend_cache
, "foo1", one
);
809 rend_cache_increment_allocation(rend_cache_entry_allocation(two
));
810 strmap_set_lc(rend_cache
, "foo2", two
);
812 rend_cache_clean(time(NULL
), REND_CACHE_TYPE_CLIENT
);
813 tt_int_op(strmap_size(rend_cache
), OP_EQ
, 1);
815 iter
= strmap_iter_init(rend_cache
);
816 strmap_iter_get(iter
, &key
, &val
);
817 tt_str_op(key
, OP_EQ
, "foo2");
820 rend_cache_free_all();
824 test_rend_cache_failure_entry_new(void *data
)
826 rend_cache_failure_t
*failure
;
830 failure
= rend_cache_failure_entry_new();
832 tt_int_op(digestmap_size(failure
->intro_failures
), OP_EQ
, 0);
835 rend_cache_failure_entry_free(failure
);
839 test_rend_cache_failure_entry_free(void *data
)
843 // Test that it can deal with a NULL argument
844 rend_cache_failure_entry_free_(NULL
);
851 test_rend_cache_failure_clean(void *data
)
853 rend_cache_failure_t
*failure
;
854 rend_cache_failure_intro_t
*ip_one
, *ip_two
;
856 const char key_one
[DIGEST_LEN
] = "ip1";
857 const char key_two
[DIGEST_LEN
] = "ip2";
863 // Test with empty failure cache
864 rend_cache_failure_clean(time(NULL
));
865 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
867 // Test with one empty failure entry
868 failure
= rend_cache_failure_entry_new();
869 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
870 rend_cache_failure_clean(time(NULL
));
871 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
873 // Test with one new intro point
874 failure
= rend_cache_failure_entry_new();
875 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
876 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
877 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
878 rend_cache_failure_clean(time(NULL
));
879 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 1);
881 // Test with one old intro point
882 rend_cache_failure_purge();
883 failure
= rend_cache_failure_entry_new();
884 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
885 ip_one
->created_ts
= time(NULL
) - 7*60;
886 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
887 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
888 rend_cache_failure_clean(time(NULL
));
889 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
891 // Test with one old intro point and one new one
892 rend_cache_failure_purge();
893 failure
= rend_cache_failure_entry_new();
894 ip_one
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
895 ip_one
->created_ts
= time(NULL
) - 7*60;
896 digestmap_set(failure
->intro_failures
, key_one
, ip_one
);
897 ip_two
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
898 ip_two
->created_ts
= time(NULL
) - 2*60;
899 digestmap_set(failure
->intro_failures
, key_two
, ip_two
);
900 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
901 rend_cache_failure_clean(time(NULL
));
902 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 1);
903 tt_int_op(digestmap_size(failure
->intro_failures
), OP_EQ
, 1);
906 rend_cache_free_all();
910 test_rend_cache_failure_remove(void *data
)
912 rend_service_descriptor_t
*desc
;
917 // Test that it deals well with a NULL desc
918 rend_cache_failure_remove(NULL
);
920 // Test a descriptor that isn't in the cache
921 desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
922 desc
->pk
= pk_generate(0);
923 rend_cache_failure_remove(desc
);
925 // There seems to not exist any way of getting rend_cache_failure_remove()
926 // to fail because of a problem with rend_get_service_id from here
927 rend_cache_free_all();
929 rend_service_descriptor_free(desc
);
935 test_rend_cache_free_all(void *data
)
937 rend_cache_failure_t
*failure
;
938 rend_cache_entry_t
*one
;
939 rend_service_descriptor_t
*desc_one
;
945 failure
= rend_cache_failure_entry_new();
946 strmap_set_lc(rend_cache_failure
, "foo1", failure
);
948 one
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
949 desc_one
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
950 one
->parsed
= desc_one
;
951 desc_one
->timestamp
= time(NULL
) + TIME_IN_THE_PAST
;
952 desc_one
->pk
= pk_generate(0);
953 rend_cache_increment_allocation(rend_cache_entry_allocation(one
));
954 strmap_set_lc(rend_cache
, "foo1", one
);
956 rend_cache_free_all();
958 tt_ptr_op(rend_cache
, OP_EQ
, NULL
);
959 tt_ptr_op(rend_cache_v2_dir
, OP_EQ
, NULL
);
960 tt_ptr_op(rend_cache_failure
, OP_EQ
, NULL
);
961 tt_assert(!rend_cache_total_allocation
);
964 rend_cache_free_all();
968 test_rend_cache_entry_free(void *data
)
971 rend_cache_entry_t
*e
;
973 // Handles NULL correctly
974 rend_cache_entry_free_(NULL
);
976 // Handles NULL descriptor correctly
977 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
978 rend_cache_increment_allocation(rend_cache_entry_allocation(e
));
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_increment_allocation(rend_cache_entry_allocation(e
));
985 rend_cache_entry_free(e
);
992 test_rend_cache_purge(void *data
)
996 // Deals with a NULL rend_cache
998 tt_assert(rend_cache
);
999 tt_assert(strmap_size(rend_cache
) == 0);
1001 // Deals with existing rend_cache
1002 rend_cache_free_all();
1004 tt_assert(rend_cache
);
1005 tt_assert(strmap_size(rend_cache
) == 0);
1008 tt_assert(rend_cache
);
1009 tt_assert(strmap_size(rend_cache
) == 0);
1012 rend_cache_free_all();
1016 test_rend_cache_failure_intro_add(void *data
)
1019 rend_cache_failure_t
*fail_entry
;
1020 rend_cache_failure_intro_t
*entry
;
1021 const char identity
[DIGEST_LEN
] = "foo1";
1025 // Adds non-existing entry
1026 cache_failure_intro_add((const uint8_t *) identity
, "foo2",
1027 INTRO_POINT_FAILURE_TIMEOUT
);
1028 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1029 tt_assert(fail_entry
);
1030 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1031 entry
= digestmap_get(fail_entry
->intro_failures
, identity
);
1034 // Adds existing entry
1035 cache_failure_intro_add((const uint8_t *) identity
, "foo2",
1036 INTRO_POINT_FAILURE_TIMEOUT
);
1037 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1038 tt_assert(fail_entry
);
1039 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1040 entry
= digestmap_get(fail_entry
->intro_failures
, identity
);
1044 rend_cache_free_all();
1048 test_rend_cache_intro_failure_note(void *data
)
1051 rend_cache_failure_t
*fail_entry
;
1052 rend_cache_failure_intro_t
*entry
;
1053 const char key
[DIGEST_LEN
] = "foo1";
1058 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT
,
1059 (const uint8_t *) key
, "foo2");
1060 fail_entry
= strmap_get_lc(rend_cache_failure
, "foo2");
1061 tt_assert(fail_entry
);
1062 tt_int_op(digestmap_size(fail_entry
->intro_failures
), OP_EQ
, 1);
1063 entry
= digestmap_get(fail_entry
->intro_failures
, key
);
1065 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_TIMEOUT
);
1068 rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE
,
1069 (const uint8_t *) key
, "foo2");
1070 tt_int_op(entry
->failure_type
, OP_EQ
, INTRO_POINT_FAILURE_UNREACHABLE
);
1073 rend_cache_free_all();
1077 test_rend_cache_clean_v2_descs_as_dir(void *data
)
1079 rend_cache_entry_t
*e
;
1081 rend_service_descriptor_t
*desc
;
1083 cutoff
= now
- (REND_CACHE_MAX_AGE
+ REND_CACHE_MAX_SKEW
);
1084 const char key
[DIGEST_LEN
] = "abcde";
1090 // Test running with an empty cache
1091 rend_cache_clean_v2_descs_as_dir(cutoff
);
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 rend_cache_increment_allocation(rend_cache_entry_allocation(e
));
1102 digestmap_set(rend_cache_v2_dir
, key
, e
);
1104 /* Set the cutoff to minus 10 seconds. */
1105 rend_cache_clean_v2_descs_as_dir(cutoff
- 10);
1106 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 1);
1108 // Test with one old entry
1109 desc
->timestamp
= cutoff
- 1000;
1110 rend_cache_clean_v2_descs_as_dir(cutoff
);
1111 tt_int_op(digestmap_size(rend_cache_v2_dir
), OP_EQ
, 0);
1114 rend_cache_free_all();
1118 test_rend_cache_entry_allocation(void *data
)
1123 rend_cache_entry_t
*e
= NULL
;
1125 // Handles a null argument
1126 ret
= rend_cache_entry_allocation(NULL
);
1127 tt_int_op(ret
, OP_EQ
, 0);
1129 // Handles a non-null argument
1130 e
= tor_malloc_zero(sizeof(rend_cache_entry_t
));
1131 ret
= rend_cache_entry_allocation(e
);
1132 tt_int_op(ret
, OP_GT
, sizeof(rend_cache_entry_t
));
1139 test_rend_cache_failure_intro_entry_free(void *data
)
1142 rend_cache_failure_intro_t
*entry
;
1144 // Handles a null argument
1145 rend_cache_failure_intro_entry_free_(NULL
);
1147 // Handles a non-null argument
1148 entry
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
1149 rend_cache_failure_intro_entry_free(entry
);
1153 test_rend_cache_failure_purge(void *data
)
1157 // Handles a null failure cache
1158 strmap_free(rend_cache_failure
, rend_cache_failure_entry_free_void
);
1159 rend_cache_failure
= NULL
;
1161 rend_cache_failure_purge();
1163 tt_ptr_op(rend_cache_failure
, OP_NE
, NULL
);
1164 tt_int_op(strmap_size(rend_cache_failure
), OP_EQ
, 0);
1167 rend_cache_free_all();
1171 test_rend_cache_validate_intro_point_failure(void *data
)
1174 rend_service_descriptor_t
*desc
= NULL
;
1175 char *service_id
= NULL
;
1176 rend_intro_point_t
*intro
= NULL
;
1177 const char *identity
= NULL
;
1178 rend_cache_failure_t
*failure
;
1179 rend_cache_failure_intro_t
*ip
;
1183 create_descriptor(&desc
, &service_id
, 3);
1184 desc
->timestamp
= time(NULL
) + RECENT_TIME
;
1186 intro
= (rend_intro_point_t
*)smartlist_get(desc
->intro_nodes
, 0);
1187 identity
= intro
->extend_info
->identity_digest
;
1189 failure
= rend_cache_failure_entry_new();
1190 ip
= rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT
);
1191 digestmap_set(failure
->intro_failures
, identity
, ip
);
1192 strmap_set_lc(rend_cache_failure
, service_id
, failure
);
1194 // Test when we have an intro point in our cache
1195 validate_intro_point_failure(desc
, service_id
);
1196 tt_int_op(smartlist_len(desc
->intro_nodes
), OP_EQ
, 2);
1199 rend_cache_free_all();
1200 rend_service_descriptor_free(desc
);
1201 tor_free(service_id
);
1204 struct testcase_t rend_cache_tests
[] = {
1205 { "init", test_rend_cache_init
, 0, NULL
, NULL
},
1206 { "decrement_allocation", test_rend_cache_decrement_allocation
, 0,
1208 { "increment_allocation", test_rend_cache_increment_allocation
, 0,
1210 { "clean", test_rend_cache_clean
, TT_FORK
, NULL
, NULL
},
1211 { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir
, 0,
1213 { "entry_allocation", test_rend_cache_entry_allocation
, 0, NULL
, NULL
},
1214 { "entry_free", test_rend_cache_entry_free
, 0, NULL
, NULL
},
1215 { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free
, 0,
1217 { "free_all", test_rend_cache_free_all
, 0, NULL
, NULL
},
1218 { "purge", test_rend_cache_purge
, 0, NULL
, NULL
},
1219 { "failure_clean", test_rend_cache_failure_clean
, 0, NULL
, NULL
},
1220 { "failure_entry_new", test_rend_cache_failure_entry_new
, 0, NULL
, NULL
},
1221 { "failure_entry_free", test_rend_cache_failure_entry_free
, 0, NULL
, NULL
},
1222 { "failure_intro_add", test_rend_cache_failure_intro_add
, 0, NULL
, NULL
},
1223 { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new
, 0,
1225 { "failure_intro_lookup", test_rend_cache_failure_intro_lookup
, 0,
1227 { "failure_purge", test_rend_cache_failure_purge
, 0, NULL
, NULL
},
1228 { "failure_remove", test_rend_cache_failure_remove
, 0, NULL
, NULL
},
1229 { "intro_failure_note", test_rend_cache_intro_failure_note
, 0, NULL
, NULL
},
1230 { "lookup", test_rend_cache_lookup_entry
, 0, NULL
, NULL
},
1231 { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir
, 0,
1233 { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client
, 0,
1235 { "store_v2_desc_as_client_with_different_time",
1236 test_rend_cache_store_v2_desc_as_client_with_different_time
, 0,
1238 { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir
, 0,
1240 { "store_v2_desc_as_dir_with_different_time",
1241 test_rend_cache_store_v2_desc_as_dir_with_different_time
, 0, NULL
, NULL
},
1242 { "store_v2_desc_as_dir_with_different_content",
1243 test_rend_cache_store_v2_desc_as_dir_with_different_content
, 0,
1245 { "validate_intro_point_failure",
1246 test_rend_cache_validate_intro_point_failure
, 0, NULL
, NULL
},