test_rendcache.c 39 KB

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