test_rendcache.c 39 KB

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