test_rendcache.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. /* Copyright (c) 2010-2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include "orconfig.h"
  4. #include "or.h"
  5. #include "test.h"
  6. #define RENDCACHE_PRIVATE
  7. #include "rendcache.h"
  8. #include "router.h"
  9. #include "routerlist.h"
  10. #include "config.h"
  11. #include "hs_common.h"
  12. #include <openssl/rsa.h>
  13. #include "rend_test_helpers.h"
  14. #include "log_test_helpers.h"
  15. #define NS_MODULE rend_cache
  16. static const int RECENT_TIME = -10;
  17. static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \
  18. REND_CACHE_MAX_SKEW + 60);
  19. static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 60;
  20. static rend_data_t *
  21. mock_rend_data(const char *onion_address)
  22. {
  23. rend_data_v2_t *v2_data = tor_malloc_zero(sizeof(*v2_data));
  24. rend_data_t *rend_query = &v2_data->base_;
  25. rend_query->version = 2;
  26. strlcpy(v2_data->onion_address, onion_address,
  27. sizeof(v2_data->onion_address));
  28. v2_data->auth_type = REND_NO_AUTH;
  29. rend_query->hsdirs_fp = smartlist_new();
  30. smartlist_add(rend_query->hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa",
  31. DIGEST_LEN));
  32. return rend_query;
  33. }
  34. static void
  35. test_rend_cache_lookup_entry(void *data)
  36. {
  37. int ret;
  38. rend_data_t *mock_rend_query = NULL;
  39. char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  40. rend_cache_entry_t *entry = NULL;
  41. rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
  42. char *service_id = NULL;
  43. (void)data;
  44. rend_cache_init();
  45. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  46. ret = rend_cache_lookup_entry("abababababababab", 0, NULL);
  47. tt_int_op(ret, OP_EQ, -ENOENT);
  48. ret = rend_cache_lookup_entry("invalid query", 2, NULL);
  49. tt_int_op(ret, OP_EQ, -EINVAL);
  50. ret = rend_cache_lookup_entry("abababababababab", 2, NULL);
  51. tt_int_op(ret, OP_EQ, -ENOENT);
  52. ret = rend_cache_lookup_entry("abababababababab", 4224, NULL);
  53. tt_int_op(ret, OP_EQ, -ENOENT);
  54. mock_rend_query = mock_rend_data(service_id);
  55. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  56. DIGEST_LEN);
  57. rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32,
  58. mock_rend_query, NULL);
  59. ret = rend_cache_lookup_entry(service_id, 2, NULL);
  60. tt_int_op(ret, OP_EQ, 0);
  61. ret = rend_cache_lookup_entry(service_id, 2, &entry);
  62. tt_assert(entry);
  63. tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str));
  64. tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str);
  65. done:
  66. rend_encoded_v2_service_descriptor_free(desc_holder);
  67. tor_free(service_id);
  68. rend_cache_free_all();
  69. rend_data_free(mock_rend_query);
  70. }
  71. static void
  72. test_rend_cache_store_v2_desc_as_client(void *data)
  73. {
  74. int ret;
  75. rend_data_t *mock_rend_query;
  76. char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  77. rend_cache_entry_t *entry = NULL;
  78. rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
  79. char *service_id = NULL;
  80. char client_cookie[REND_DESC_COOKIE_LEN];
  81. (void)data;
  82. rend_cache_init();
  83. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  84. // Test success
  85. mock_rend_query = mock_rend_data(service_id);
  86. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  87. DIGEST_LEN);
  88. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  89. desc_id_base32, mock_rend_query,
  90. &entry);
  91. tt_int_op(ret, OP_EQ, 0);
  92. tt_assert(entry);
  93. tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str));
  94. tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str);
  95. // Test various failure modes
  96. // TODO: a too long desc_id_base32 argument crashes the function
  97. /* ret = rend_cache_store_v2_desc_as_client( */
  98. /* desc_holder->desc_str, */
  99. /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */
  100. /* &mock_rend_query, NULL); */
  101. /* tt_int_op(ret, OP_EQ, -1); */
  102. // Test bad base32 failure
  103. // This causes an assertion failure if we're running with assertions.
  104. // But when building without asserts, we can test it.
  105. #ifdef DISABLE_ASSERTS_IN_UNIT_TESTS
  106. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  107. "!xqunszqnaolrrfmtzgaki7mxelgvkj", mock_rend_query, NULL);
  108. tt_int_op(ret, OP_EQ, -1);
  109. #endif
  110. // Test invalid descriptor
  111. ret = rend_cache_store_v2_desc_as_client("invalid descriptor",
  112. "3xqunszqnaolrrfmtzgaki7mxelgvkje", mock_rend_query, NULL);
  113. tt_int_op(ret, OP_EQ, -1);
  114. // TODO: it doesn't seem to be possible to test invalid service ID condition.
  115. // that means it is likely not possible to have that condition without
  116. // earlier conditions failing first (such as signature checking of the desc)
  117. rend_cache_free_all();
  118. // Test mismatch between service ID and onion address
  119. rend_cache_init();
  120. strncpy(TO_REND_DATA_V2(mock_rend_query)->onion_address, "abc",
  121. REND_SERVICE_ID_LEN_BASE32+1);
  122. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  123. desc_id_base32,
  124. mock_rend_query, NULL);
  125. tt_int_op(ret, OP_EQ, -1);
  126. rend_cache_free_all();
  127. rend_data_free(mock_rend_query);
  128. // Test incorrect descriptor ID
  129. rend_cache_init();
  130. mock_rend_query = mock_rend_data(service_id);
  131. desc_id_base32[0]++;
  132. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  133. desc_id_base32, mock_rend_query,
  134. NULL);
  135. tt_int_op(ret, OP_EQ, -1);
  136. desc_id_base32[0]--;
  137. rend_cache_free_all();
  138. // Test too old descriptor
  139. rend_cache_init();
  140. rend_encoded_v2_service_descriptor_free(desc_holder);
  141. tor_free(service_id);
  142. rend_data_free(mock_rend_query);
  143. generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3);
  144. mock_rend_query = mock_rend_data(service_id);
  145. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  146. DIGEST_LEN);
  147. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  148. desc_id_base32,
  149. mock_rend_query, NULL);
  150. tt_int_op(ret, OP_EQ, -1);
  151. rend_cache_free_all();
  152. // Test too new descriptor (in the future)
  153. rend_cache_init();
  154. rend_encoded_v2_service_descriptor_free(desc_holder);
  155. tor_free(service_id);
  156. rend_data_free(mock_rend_query);
  157. generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
  158. mock_rend_query = mock_rend_data(service_id);
  159. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  160. DIGEST_LEN);
  161. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  162. desc_id_base32, mock_rend_query,
  163. NULL);
  164. tt_int_op(ret, OP_EQ, -1);
  165. rend_cache_free_all();
  166. // Test when a descriptor is already in the cache
  167. rend_cache_init();
  168. rend_encoded_v2_service_descriptor_free(desc_holder);
  169. tor_free(service_id);
  170. rend_data_free(mock_rend_query);
  171. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  172. mock_rend_query = mock_rend_data(service_id);
  173. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  174. DIGEST_LEN);
  175. rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32,
  176. mock_rend_query, NULL);
  177. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  178. desc_id_base32, mock_rend_query,
  179. NULL);
  180. tt_int_op(ret, OP_EQ, 0);
  181. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  182. desc_id_base32, mock_rend_query,
  183. &entry);
  184. tt_int_op(ret, OP_EQ, 0);
  185. tt_assert(entry);
  186. rend_cache_free_all();
  187. // Test unsuccessful decrypting of introduction points
  188. rend_cache_init();
  189. rend_encoded_v2_service_descriptor_free(desc_holder);
  190. tor_free(service_id);
  191. rend_data_free(mock_rend_query);
  192. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  193. mock_rend_query = mock_rend_data(service_id);
  194. TO_REND_DATA_V2(mock_rend_query)->auth_type = REND_BASIC_AUTH;
  195. client_cookie[0] = 'A';
  196. memcpy(TO_REND_DATA_V2(mock_rend_query)->descriptor_cookie, client_cookie,
  197. REND_DESC_COOKIE_LEN);
  198. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  199. DIGEST_LEN);
  200. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  201. desc_id_base32, mock_rend_query,
  202. NULL);
  203. tt_int_op(ret, OP_EQ, 0);
  204. rend_cache_free_all();
  205. // Test successful run when we have REND_BASIC_AUTH but not cookie
  206. rend_cache_init();
  207. rend_encoded_v2_service_descriptor_free(desc_holder);
  208. tor_free(service_id);
  209. rend_data_free(mock_rend_query);
  210. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  211. mock_rend_query = mock_rend_data(service_id);
  212. TO_REND_DATA_V2(mock_rend_query)->auth_type = REND_BASIC_AUTH;
  213. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  214. DIGEST_LEN);
  215. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  216. desc_id_base32, mock_rend_query,
  217. NULL);
  218. tt_int_op(ret, OP_EQ, 0);
  219. rend_cache_free_all();
  220. // Test when we have no introduction points
  221. rend_cache_init();
  222. rend_encoded_v2_service_descriptor_free(desc_holder);
  223. tor_free(service_id);
  224. rend_data_free(mock_rend_query);
  225. generate_desc(RECENT_TIME, &desc_holder, &service_id, 0);
  226. mock_rend_query = mock_rend_data(service_id);
  227. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  228. DIGEST_LEN);
  229. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  230. desc_id_base32, mock_rend_query,
  231. NULL);
  232. tt_int_op(ret, OP_EQ, -1);
  233. rend_cache_free_all();
  234. // Test when we have too many intro points
  235. rend_cache_init();
  236. rend_encoded_v2_service_descriptor_free(desc_holder);
  237. tor_free(service_id);
  238. rend_data_free(mock_rend_query);
  239. generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1);
  240. mock_rend_query = mock_rend_data(service_id);
  241. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  242. DIGEST_LEN);
  243. ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str,
  244. desc_id_base32, mock_rend_query,
  245. NULL);
  246. tt_int_op(ret, OP_EQ, -1);
  247. done:
  248. rend_encoded_v2_service_descriptor_free(desc_holder);
  249. tor_free(service_id);
  250. rend_cache_free_all();
  251. rend_data_free(mock_rend_query);
  252. }
  253. static void
  254. test_rend_cache_store_v2_desc_as_client_with_different_time(void *data)
  255. {
  256. int ret;
  257. rend_data_t *mock_rend_query;
  258. char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  259. rend_service_descriptor_t *generated = NULL;
  260. smartlist_t *descs = smartlist_new();
  261. time_t t;
  262. char *service_id = NULL;
  263. rend_encoded_v2_service_descriptor_t *desc_holder_newer;
  264. rend_encoded_v2_service_descriptor_t *desc_holder_older;
  265. t = time(NULL);
  266. rend_cache_init();
  267. create_descriptor(&generated, &service_id, 3);
  268. generated->timestamp = t + RECENT_TIME;
  269. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  270. REND_NO_AUTH, NULL, NULL);
  271. desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)
  272. smartlist_get(descs, 0));
  273. smartlist_set(descs, 0, NULL);
  274. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  275. rend_encoded_v2_service_descriptor_free(d));
  276. smartlist_free(descs);
  277. descs = smartlist_new();
  278. generated->timestamp = (t + RECENT_TIME) - 20;
  279. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  280. REND_NO_AUTH, NULL, NULL);
  281. desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)
  282. smartlist_get(descs, 0));
  283. smartlist_set(descs, 0, NULL);
  284. (void)data;
  285. // Test when a descriptor is already in the cache and it is newer than the
  286. // one we submit
  287. mock_rend_query = mock_rend_data(service_id);
  288. base32_encode(desc_id_base32, sizeof(desc_id_base32),
  289. desc_holder_newer->desc_id, DIGEST_LEN);
  290. rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str,
  291. desc_id_base32, mock_rend_query, NULL);
  292. ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str,
  293. desc_id_base32, mock_rend_query,
  294. NULL);
  295. tt_int_op(ret, OP_EQ, 0);
  296. rend_cache_free_all();
  297. // Test when an old descriptor is in the cache and we submit a newer one
  298. rend_cache_init();
  299. rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str,
  300. desc_id_base32, mock_rend_query, NULL);
  301. ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str,
  302. desc_id_base32, mock_rend_query,
  303. NULL);
  304. tt_int_op(ret, OP_EQ, 0);
  305. done:
  306. rend_encoded_v2_service_descriptor_free(desc_holder_newer);
  307. rend_encoded_v2_service_descriptor_free(desc_holder_older);
  308. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  309. rend_encoded_v2_service_descriptor_free(d));
  310. smartlist_free(descs);
  311. rend_service_descriptor_free(generated);
  312. tor_free(service_id);
  313. rend_cache_free_all();
  314. rend_data_free(mock_rend_query);
  315. }
  316. #define NS_SUBMODULE lookup_v2_desc_as_dir
  317. NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
  318. static routerinfo_t *mock_routerinfo;
  319. static const routerinfo_t *
  320. NS(router_get_my_routerinfo)(void)
  321. {
  322. if (!mock_routerinfo) {
  323. mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
  324. }
  325. return mock_routerinfo;
  326. }
  327. static void
  328. test_rend_cache_lookup_v2_desc_as_dir(void *data)
  329. {
  330. int ret;
  331. char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  332. rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
  333. char *service_id = NULL;
  334. const char *ret_desc = NULL;
  335. (void)data;
  336. NS_MOCK(router_get_my_routerinfo);
  337. rend_cache_init();
  338. // Test invalid base32
  339. ret = rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL);
  340. tt_int_op(ret, OP_EQ, -1);
  341. // Test non-existent descriptor but well formed
  342. ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje",
  343. NULL);
  344. tt_int_op(ret, OP_EQ, 0);
  345. // Test existing descriptor
  346. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  347. rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
  348. base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
  349. DIGEST_LEN);
  350. ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc);
  351. tt_int_op(ret, OP_EQ, 1);
  352. tt_assert(ret_desc);
  353. done:
  354. NS_UNMOCK(router_get_my_routerinfo);
  355. tor_free(mock_routerinfo);
  356. rend_cache_free_all();
  357. rend_encoded_v2_service_descriptor_free(desc_holder);
  358. tor_free(service_id);
  359. }
  360. #undef NS_SUBMODULE
  361. #define NS_SUBMODULE store_v2_desc_as_dir
  362. NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
  363. static const routerinfo_t *
  364. NS(router_get_my_routerinfo)(void)
  365. {
  366. return mock_routerinfo;
  367. }
  368. static void
  369. test_rend_cache_store_v2_desc_as_dir(void *data)
  370. {
  371. (void)data;
  372. int ret;
  373. rend_encoded_v2_service_descriptor_t *desc_holder = NULL;
  374. char *service_id = NULL;
  375. NS_MOCK(router_get_my_routerinfo);
  376. rend_cache_init();
  377. // Test when we can't parse the descriptor
  378. mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
  379. ret = rend_cache_store_v2_desc_as_dir("unparseable");
  380. tt_int_op(ret, OP_EQ, -1);
  381. // Test when we have an old descriptor
  382. generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3);
  383. ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
  384. tt_int_op(ret, OP_EQ, 0);
  385. rend_encoded_v2_service_descriptor_free(desc_holder);
  386. tor_free(service_id);
  387. // Test when we have a descriptor in the future
  388. generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
  389. ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
  390. tt_int_op(ret, OP_EQ, 0);
  391. rend_encoded_v2_service_descriptor_free(desc_holder);
  392. tor_free(service_id);
  393. // Test when two descriptors
  394. generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3);
  395. ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
  396. tt_int_op(ret, OP_EQ, 0);
  397. rend_encoded_v2_service_descriptor_free(desc_holder);
  398. tor_free(service_id);
  399. // Test when asking for hidden service statistics HiddenServiceStatistics
  400. rend_cache_purge();
  401. generate_desc(RECENT_TIME, &desc_holder, &service_id, 3);
  402. get_options_mutable()->HiddenServiceStatistics = 1;
  403. ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str);
  404. tt_int_op(ret, OP_EQ, 0);
  405. done:
  406. NS_UNMOCK(router_get_my_routerinfo);
  407. rend_encoded_v2_service_descriptor_free(desc_holder);
  408. tor_free(service_id);
  409. rend_cache_free_all();
  410. tor_free(mock_routerinfo);
  411. }
  412. static void
  413. test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data)
  414. {
  415. (void)data;
  416. int ret;
  417. rend_service_descriptor_t *generated = NULL;
  418. smartlist_t *descs = smartlist_new();
  419. time_t t;
  420. char *service_id = NULL;
  421. rend_encoded_v2_service_descriptor_t *desc_holder_newer;
  422. rend_encoded_v2_service_descriptor_t *desc_holder_older;
  423. NS_MOCK(router_get_my_routerinfo);
  424. rend_cache_init();
  425. t = time(NULL);
  426. create_descriptor(&generated, &service_id, 3);
  427. generated->timestamp = t + RECENT_TIME;
  428. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  429. REND_NO_AUTH, NULL, NULL);
  430. desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)
  431. smartlist_get(descs, 0));
  432. smartlist_set(descs, 0, NULL);
  433. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  434. rend_encoded_v2_service_descriptor_free(d));
  435. smartlist_free(descs);
  436. descs = smartlist_new();
  437. generated->timestamp = (t + RECENT_TIME) - 20;
  438. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  439. REND_NO_AUTH, NULL, NULL);
  440. desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)
  441. smartlist_get(descs, 0));
  442. smartlist_set(descs, 0, NULL);
  443. // Test when we have a newer descriptor stored
  444. mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
  445. rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str);
  446. ret = rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str);
  447. tt_int_op(ret, OP_EQ, 0);
  448. // Test when we have an old descriptor stored
  449. rend_cache_purge();
  450. rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str);
  451. ret = rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str);
  452. tt_int_op(ret, OP_EQ, 0);
  453. done:
  454. NS_UNMOCK(router_get_my_routerinfo);
  455. rend_cache_free_all();
  456. rend_service_descriptor_free(generated);
  457. tor_free(service_id);
  458. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  459. rend_encoded_v2_service_descriptor_free(d));
  460. smartlist_free(descs);
  461. rend_encoded_v2_service_descriptor_free(desc_holder_newer);
  462. rend_encoded_v2_service_descriptor_free(desc_holder_older);
  463. tor_free(mock_routerinfo);
  464. }
  465. static void
  466. test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data)
  467. {
  468. (void)data;
  469. int ret;
  470. rend_service_descriptor_t *generated = NULL;
  471. smartlist_t *descs = smartlist_new();
  472. time_t t;
  473. char *service_id = NULL;
  474. rend_encoded_v2_service_descriptor_t *desc_holder_one = NULL;
  475. rend_encoded_v2_service_descriptor_t *desc_holder_two = NULL;
  476. NS_MOCK(router_get_my_routerinfo);
  477. rend_cache_init();
  478. t = time(NULL);
  479. create_descriptor(&generated, &service_id, 3);
  480. generated->timestamp = t + RECENT_TIME;
  481. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  482. REND_NO_AUTH, NULL, NULL);
  483. desc_holder_one = ((rend_encoded_v2_service_descriptor_t *)
  484. smartlist_get(descs, 0));
  485. smartlist_set(descs, 0, NULL);
  486. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  487. rend_encoded_v2_service_descriptor_free(d));
  488. smartlist_free(descs);
  489. descs = smartlist_new();
  490. generated->timestamp = t + RECENT_TIME;
  491. generated->protocols = 41;
  492. rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0,
  493. REND_NO_AUTH, NULL, NULL);
  494. desc_holder_two = ((rend_encoded_v2_service_descriptor_t *)
  495. smartlist_get(descs, 0));
  496. smartlist_set(descs, 0, NULL);
  497. // Test when we have another descriptor stored, with a different descriptor
  498. mock_routerinfo = tor_malloc(sizeof(routerinfo_t));
  499. rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str);
  500. ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str);
  501. tt_int_op(ret, OP_EQ, 0);
  502. done:
  503. NS_UNMOCK(router_get_my_routerinfo);
  504. rend_cache_free_all();
  505. rend_service_descriptor_free(generated);
  506. tor_free(service_id);
  507. SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d,
  508. rend_encoded_v2_service_descriptor_free(d));
  509. smartlist_free(descs);
  510. rend_encoded_v2_service_descriptor_free(desc_holder_one);
  511. rend_encoded_v2_service_descriptor_free(desc_holder_two);
  512. }
  513. #undef NS_SUBMODULE
  514. static void
  515. test_rend_cache_init(void *data)
  516. {
  517. (void)data;
  518. tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting");
  519. tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL "
  520. "when starting");
  521. tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when "
  522. "starting");
  523. rend_cache_init();
  524. tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing");
  525. tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL "
  526. "after initing");
  527. tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL "
  528. "after initing");
  529. tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
  530. tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
  531. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
  532. done:
  533. rend_cache_free_all();
  534. }
  535. static void
  536. test_rend_cache_decrement_allocation(void *data)
  537. {
  538. (void)data;
  539. // Test when the cache has enough allocations
  540. rend_cache_total_allocation = 10;
  541. rend_cache_decrement_allocation(3);
  542. tt_int_op(rend_cache_total_allocation, OP_EQ, 7);
  543. // Test when there are not enough allocations
  544. rend_cache_total_allocation = 1;
  545. setup_full_capture_of_logs(LOG_WARN);
  546. rend_cache_decrement_allocation(2);
  547. tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
  548. expect_single_log_msg_containing(
  549. "Underflow in rend_cache_decrement_allocation");
  550. teardown_capture_of_logs();
  551. // And again
  552. rend_cache_decrement_allocation(2);
  553. tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
  554. done:
  555. teardown_capture_of_logs();
  556. }
  557. static void
  558. test_rend_cache_increment_allocation(void *data)
  559. {
  560. (void)data;
  561. // Test when the cache is not overflowing
  562. rend_cache_total_allocation = 5;
  563. rend_cache_increment_allocation(3);
  564. tt_int_op(rend_cache_total_allocation, OP_EQ, 8);
  565. // Test when there are too many allocations
  566. rend_cache_total_allocation = SIZE_MAX-1;
  567. setup_full_capture_of_logs(LOG_WARN);
  568. rend_cache_increment_allocation(2);
  569. tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
  570. expect_single_log_msg_containing(
  571. "Overflow in rend_cache_increment_allocation");
  572. teardown_capture_of_logs();
  573. // And again
  574. rend_cache_increment_allocation(2);
  575. tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
  576. done:
  577. teardown_capture_of_logs();
  578. }
  579. static void
  580. test_rend_cache_failure_intro_entry_new(void *data)
  581. {
  582. time_t now;
  583. rend_cache_failure_intro_t *entry;
  584. rend_intro_point_failure_t failure;
  585. (void)data;
  586. failure = INTRO_POINT_FAILURE_TIMEOUT;
  587. now = time(NULL);
  588. entry = rend_cache_failure_intro_entry_new(failure);
  589. tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT);
  590. tt_int_op(entry->created_ts, OP_GE, now-5);
  591. tt_int_op(entry->created_ts, OP_LE, now+5);
  592. done:
  593. tor_free(entry);
  594. }
  595. static void
  596. test_rend_cache_failure_intro_lookup(void *data)
  597. {
  598. (void)data;
  599. int ret;
  600. rend_cache_failure_t *failure;
  601. rend_cache_failure_intro_t *ip;
  602. rend_cache_failure_intro_t *entry;
  603. const char key_ip_one[DIGEST_LEN] = "ip1";
  604. const char key_ip_two[DIGEST_LEN] = "ip2";
  605. const char key_foo[DIGEST_LEN] = "foo1";
  606. rend_cache_init();
  607. failure = rend_cache_failure_entry_new();
  608. ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  609. digestmap_set(failure->intro_failures, key_ip_one, ip);
  610. strmap_set_lc(rend_cache_failure, "foo1", failure);
  611. // Test not found
  612. ret = cache_failure_intro_lookup((const uint8_t *) key_foo, "foo2", NULL);
  613. tt_int_op(ret, OP_EQ, 0);
  614. // Test found with no intro failures in it
  615. ret = cache_failure_intro_lookup((const uint8_t *) key_ip_two, "foo1", NULL);
  616. tt_int_op(ret, OP_EQ, 0);
  617. // Test found
  618. ret = cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", NULL);
  619. tt_int_op(ret, OP_EQ, 1);
  620. // Test found and asking for entry
  621. cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", &entry);
  622. tt_assert(entry);
  623. tt_assert(entry == ip);
  624. done:
  625. rend_cache_free_all();
  626. }
  627. static void
  628. test_rend_cache_clean(void *data)
  629. {
  630. rend_cache_entry_t *one, *two;
  631. rend_service_descriptor_t *desc_one, *desc_two;
  632. strmap_iter_t *iter = NULL;
  633. const char *key;
  634. void *val;
  635. (void)data;
  636. rend_cache_init();
  637. // Test with empty rendcache
  638. rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
  639. tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
  640. // Test with two old entries
  641. one = tor_malloc_zero(sizeof(rend_cache_entry_t));
  642. two = tor_malloc_zero(sizeof(rend_cache_entry_t));
  643. desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  644. desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  645. one->parsed = desc_one;
  646. two->parsed = desc_two;
  647. desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST;
  648. desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10;
  649. desc_one->pk = pk_generate(0);
  650. desc_two->pk = pk_generate(1);
  651. strmap_set_lc(rend_cache, "foo1", one);
  652. strmap_set_lc(rend_cache, "foo2", two);
  653. rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
  654. tt_int_op(strmap_size(rend_cache), OP_EQ, 0);
  655. // Test with one old entry and one newer entry
  656. one = tor_malloc_zero(sizeof(rend_cache_entry_t));
  657. two = tor_malloc_zero(sizeof(rend_cache_entry_t));
  658. desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  659. desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  660. one->parsed = desc_one;
  661. two->parsed = desc_two;
  662. desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10;
  663. desc_two->timestamp = time(NULL) - 100;
  664. desc_one->pk = pk_generate(0);
  665. desc_two->pk = pk_generate(1);
  666. strmap_set_lc(rend_cache, "foo1", one);
  667. strmap_set_lc(rend_cache, "foo2", two);
  668. rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT);
  669. tt_int_op(strmap_size(rend_cache), OP_EQ, 1);
  670. iter = strmap_iter_init(rend_cache);
  671. strmap_iter_get(iter, &key, &val);
  672. tt_str_op(key, OP_EQ, "foo2");
  673. done:
  674. rend_cache_free_all();
  675. }
  676. static void
  677. test_rend_cache_failure_entry_new(void *data)
  678. {
  679. rend_cache_failure_t *failure;
  680. (void)data;
  681. failure = rend_cache_failure_entry_new();
  682. tt_assert(failure);
  683. tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 0);
  684. done:
  685. rend_cache_failure_entry_free(failure);
  686. }
  687. static void
  688. test_rend_cache_failure_entry_free(void *data)
  689. {
  690. (void)data;
  691. // Test that it can deal with a NULL argument
  692. rend_cache_failure_entry_free(NULL);
  693. /* done: */
  694. /* (void)0; */
  695. }
  696. static void
  697. test_rend_cache_failure_clean(void *data)
  698. {
  699. rend_cache_failure_t *failure;
  700. rend_cache_failure_intro_t *ip_one, *ip_two;
  701. const char key_one[DIGEST_LEN] = "ip1";
  702. const char key_two[DIGEST_LEN] = "ip2";
  703. (void)data;
  704. rend_cache_init();
  705. // Test with empty failure cache
  706. rend_cache_failure_clean(time(NULL));
  707. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
  708. // Test with one empty failure entry
  709. failure = rend_cache_failure_entry_new();
  710. strmap_set_lc(rend_cache_failure, "foo1", failure);
  711. rend_cache_failure_clean(time(NULL));
  712. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
  713. // Test with one new intro point
  714. failure = rend_cache_failure_entry_new();
  715. ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  716. digestmap_set(failure->intro_failures, key_one, ip_one);
  717. strmap_set_lc(rend_cache_failure, "foo1", failure);
  718. rend_cache_failure_clean(time(NULL));
  719. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1);
  720. // Test with one old intro point
  721. rend_cache_failure_purge();
  722. failure = rend_cache_failure_entry_new();
  723. ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  724. ip_one->created_ts = time(NULL) - 7*60;
  725. digestmap_set(failure->intro_failures, key_one, ip_one);
  726. strmap_set_lc(rend_cache_failure, "foo1", failure);
  727. rend_cache_failure_clean(time(NULL));
  728. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
  729. // Test with one old intro point and one new one
  730. rend_cache_failure_purge();
  731. failure = rend_cache_failure_entry_new();
  732. ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  733. ip_one->created_ts = time(NULL) - 7*60;
  734. digestmap_set(failure->intro_failures, key_one, ip_one);
  735. ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  736. ip_two->created_ts = time(NULL) - 2*60;
  737. digestmap_set(failure->intro_failures, key_two, ip_two);
  738. strmap_set_lc(rend_cache_failure, "foo1", failure);
  739. rend_cache_failure_clean(time(NULL));
  740. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1);
  741. tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1);
  742. done:
  743. rend_cache_free_all();
  744. }
  745. static void
  746. test_rend_cache_failure_remove(void *data)
  747. {
  748. rend_service_descriptor_t *desc;
  749. (void)data;
  750. rend_cache_init();
  751. // Test that it deals well with a NULL desc
  752. rend_cache_failure_remove(NULL);
  753. // Test a descriptor that isn't in the cache
  754. desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  755. desc->pk = pk_generate(0);
  756. rend_cache_failure_remove(desc);
  757. // There seems to not exist any way of getting rend_cache_failure_remove()
  758. // to fail because of a problem with rend_get_service_id from here
  759. rend_cache_free_all();
  760. rend_service_descriptor_free(desc);
  761. /* done: */
  762. /* (void)0; */
  763. }
  764. static void
  765. test_rend_cache_free_all(void *data)
  766. {
  767. rend_cache_failure_t *failure;
  768. rend_cache_entry_t *one;
  769. rend_service_descriptor_t *desc_one;
  770. (void)data;
  771. rend_cache_init();
  772. failure = rend_cache_failure_entry_new();
  773. strmap_set_lc(rend_cache_failure, "foo1", failure);
  774. one = tor_malloc_zero(sizeof(rend_cache_entry_t));
  775. desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  776. one->parsed = desc_one;
  777. desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST;
  778. desc_one->pk = pk_generate(0);
  779. strmap_set_lc(rend_cache, "foo1", one);
  780. rend_cache_free_all();
  781. tt_assert(!rend_cache);
  782. tt_assert(!rend_cache_v2_dir);
  783. tt_assert(!rend_cache_failure);
  784. tt_assert(!rend_cache_total_allocation);
  785. done:
  786. rend_cache_free_all();
  787. }
  788. static void
  789. test_rend_cache_entry_free(void *data)
  790. {
  791. (void)data;
  792. rend_cache_entry_t *e;
  793. // Handles NULL correctly
  794. rend_cache_entry_free(NULL);
  795. // Handles NULL descriptor correctly
  796. e = tor_malloc_zero(sizeof(rend_cache_entry_t));
  797. rend_cache_entry_free(e);
  798. // Handles non-NULL descriptor correctly
  799. e = tor_malloc_zero(sizeof(rend_cache_entry_t));
  800. e->desc = tor_malloc(10);
  801. rend_cache_entry_free(e);
  802. /* done: */
  803. /* (void)0; */
  804. }
  805. static void
  806. test_rend_cache_purge(void *data)
  807. {
  808. (void)data;
  809. // Deals with a NULL rend_cache
  810. rend_cache_purge();
  811. tt_assert(rend_cache);
  812. tt_assert(strmap_size(rend_cache) == 0);
  813. // Deals with existing rend_cache
  814. rend_cache_free_all();
  815. rend_cache_init();
  816. tt_assert(rend_cache);
  817. tt_assert(strmap_size(rend_cache) == 0);
  818. rend_cache_purge();
  819. tt_assert(rend_cache);
  820. tt_assert(strmap_size(rend_cache) == 0);
  821. done:
  822. rend_cache_free_all();
  823. }
  824. static void
  825. test_rend_cache_failure_intro_add(void *data)
  826. {
  827. (void)data;
  828. rend_cache_failure_t *fail_entry;
  829. rend_cache_failure_intro_t *entry;
  830. const char identity[DIGEST_LEN] = "foo1";
  831. rend_cache_init();
  832. // Adds non-existing entry
  833. cache_failure_intro_add((const uint8_t *) identity, "foo2",
  834. INTRO_POINT_FAILURE_TIMEOUT);
  835. fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
  836. tt_assert(fail_entry);
  837. tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
  838. entry = digestmap_get(fail_entry->intro_failures, identity);
  839. tt_assert(entry);
  840. // Adds existing entry
  841. cache_failure_intro_add((const uint8_t *) identity, "foo2",
  842. INTRO_POINT_FAILURE_TIMEOUT);
  843. fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
  844. tt_assert(fail_entry);
  845. tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
  846. entry = digestmap_get(fail_entry->intro_failures, identity);
  847. tt_assert(entry);
  848. done:
  849. rend_cache_free_all();
  850. }
  851. static void
  852. test_rend_cache_intro_failure_note(void *data)
  853. {
  854. (void)data;
  855. rend_cache_failure_t *fail_entry;
  856. rend_cache_failure_intro_t *entry;
  857. const char key[DIGEST_LEN] = "foo1";
  858. rend_cache_init();
  859. // Test not found
  860. rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT,
  861. (const uint8_t *) key, "foo2");
  862. fail_entry = strmap_get_lc(rend_cache_failure, "foo2");
  863. tt_assert(fail_entry);
  864. tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1);
  865. entry = digestmap_get(fail_entry->intro_failures, key);
  866. tt_assert(entry);
  867. tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT);
  868. // Test found
  869. rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE,
  870. (const uint8_t *) key, "foo2");
  871. tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE);
  872. done:
  873. rend_cache_free_all();
  874. }
  875. #define NS_SUBMODULE clean_v2_descs_as_dir
  876. static void
  877. test_rend_cache_clean_v2_descs_as_dir(void *data)
  878. {
  879. rend_cache_entry_t *e;
  880. time_t now, cutoff;
  881. rend_service_descriptor_t *desc;
  882. now = time(NULL);
  883. cutoff = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW);
  884. const char key[DIGEST_LEN] = "abcde";
  885. (void)data;
  886. rend_cache_init();
  887. // Test running with an empty cache
  888. rend_cache_clean_v2_descs_as_dir(cutoff);
  889. tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
  890. // Test with only one new entry
  891. e = tor_malloc_zero(sizeof(rend_cache_entry_t));
  892. e->last_served = now;
  893. desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
  894. desc->timestamp = now;
  895. desc->pk = pk_generate(0);
  896. e->parsed = desc;
  897. digestmap_set(rend_cache_v2_dir, key, e);
  898. /* Set the cutoff to minus 10 seconds. */
  899. rend_cache_clean_v2_descs_as_dir(cutoff - 10);
  900. tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1);
  901. // Test with one old entry
  902. desc->timestamp = cutoff - 1000;
  903. rend_cache_clean_v2_descs_as_dir(cutoff);
  904. tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0);
  905. done:
  906. rend_cache_free_all();
  907. }
  908. #undef NS_SUBMODULE
  909. static void
  910. test_rend_cache_entry_allocation(void *data)
  911. {
  912. (void)data;
  913. size_t ret;
  914. rend_cache_entry_t *e = NULL;
  915. // Handles a null argument
  916. ret = rend_cache_entry_allocation(NULL);
  917. tt_int_op(ret, OP_EQ, 0);
  918. // Handles a non-null argument
  919. e = tor_malloc_zero(sizeof(rend_cache_entry_t));
  920. ret = rend_cache_entry_allocation(e);
  921. tt_int_op(ret, OP_GT, sizeof(rend_cache_entry_t));
  922. done:
  923. tor_free(e);
  924. }
  925. static void
  926. test_rend_cache_failure_intro_entry_free(void *data)
  927. {
  928. (void)data;
  929. rend_cache_failure_intro_t *entry;
  930. // Handles a null argument
  931. rend_cache_failure_intro_entry_free(NULL);
  932. // Handles a non-null argument
  933. entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  934. rend_cache_failure_intro_entry_free(entry);
  935. }
  936. static void
  937. test_rend_cache_failure_purge(void *data)
  938. {
  939. (void)data;
  940. // Handles a null failure cache
  941. strmap_free(rend_cache_failure, rend_cache_failure_entry_free_);
  942. rend_cache_failure = NULL;
  943. rend_cache_failure_purge();
  944. tt_ptr_op(rend_cache_failure, OP_NE, NULL);
  945. tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0);
  946. done:
  947. rend_cache_free_all();
  948. }
  949. static void
  950. test_rend_cache_validate_intro_point_failure(void *data)
  951. {
  952. (void)data;
  953. rend_service_descriptor_t *desc = NULL;
  954. char *service_id = NULL;
  955. rend_intro_point_t *intro = NULL;
  956. const char *identity = NULL;
  957. rend_cache_failure_t *failure;
  958. rend_cache_failure_intro_t *ip;
  959. rend_cache_init();
  960. create_descriptor(&desc, &service_id, 3);
  961. desc->timestamp = time(NULL) + RECENT_TIME;
  962. intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0);
  963. identity = intro->extend_info->identity_digest;
  964. failure = rend_cache_failure_entry_new();
  965. ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
  966. digestmap_set(failure->intro_failures, identity, ip);
  967. strmap_set_lc(rend_cache_failure, service_id, failure);
  968. // Test when we have an intro point in our cache
  969. validate_intro_point_failure(desc, service_id);
  970. tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2);
  971. done:
  972. rend_cache_free_all();
  973. rend_service_descriptor_free(desc);
  974. tor_free(service_id);
  975. }
  976. struct testcase_t rend_cache_tests[] = {
  977. { "init", test_rend_cache_init, 0, NULL, NULL },
  978. { "decrement_allocation", test_rend_cache_decrement_allocation, 0,
  979. NULL, NULL },
  980. { "increment_allocation", test_rend_cache_increment_allocation, 0,
  981. NULL, NULL },
  982. { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL },
  983. { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0,
  984. NULL, NULL },
  985. { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL },
  986. { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL },
  987. { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0,
  988. NULL, NULL },
  989. { "free_all", test_rend_cache_free_all, 0, NULL, NULL },
  990. { "purge", test_rend_cache_purge, 0, NULL, NULL },
  991. { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL },
  992. { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL },
  993. { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL },
  994. { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL },
  995. { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0,
  996. NULL, NULL },
  997. { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0,
  998. NULL, NULL },
  999. { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL },
  1000. { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL },
  1001. { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL },
  1002. { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL },
  1003. { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0,
  1004. NULL, NULL },
  1005. { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0,
  1006. NULL, NULL },
  1007. { "store_v2_desc_as_client_with_different_time",
  1008. test_rend_cache_store_v2_desc_as_client_with_different_time, 0,
  1009. NULL, NULL },
  1010. { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0,
  1011. NULL, NULL },
  1012. { "store_v2_desc_as_dir_with_different_time",
  1013. test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL },
  1014. { "store_v2_desc_as_dir_with_different_content",
  1015. test_rend_cache_store_v2_desc_as_dir_with_different_content, 0,
  1016. NULL, NULL },
  1017. { "validate_intro_point_failure",
  1018. test_rend_cache_validate_intro_point_failure, 0, NULL, NULL },
  1019. END_OF_TESTCASES
  1020. };