hs_cache.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. /* Copyright (c) 2016-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_cache.c
  5. * \brief Handle hidden service descriptor caches.
  6. **/
  7. /* For unit tests.*/
  8. #define HS_CACHE_PRIVATE
  9. #include "core/or/or.h"
  10. #include "app/config/config.h"
  11. #include "lib/crypt_ops/crypto_format.h"
  12. #include "lib/crypt_ops/crypto_util.h"
  13. #include "feature/hs/hs_ident.h"
  14. #include "feature/hs/hs_common.h"
  15. #include "feature/hs/hs_client.h"
  16. #include "feature/hs/hs_descriptor.h"
  17. #include "feature/nodelist/networkstatus.h"
  18. #include "feature/rend/rendcache.h"
  19. #include "feature/hs/hs_cache.h"
  20. #include "feature/nodelist/networkstatus_st.h"
  21. #define SUBPROCESS_PRIVATE
  22. #include "lib/process/env.h"
  23. #include "lib/process/subprocess.h"
  24. #include "lib/evloop/compat_libevent.h"
  25. #include <event2/event.h>
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. static int cached_client_descriptor_has_expired(time_t now,
  30. const hs_cache_client_descriptor_t *cached_desc);
  31. /********************** Directory HS cache ******************/
  32. /* Directory descriptor cache. Map indexed by blinded key. */
  33. static digest256map_t *hs_cache_v3_dir;
  34. /* Remove a given descriptor from our cache. */
  35. static void
  36. remove_v3_desc_as_dir(const hs_cache_dir_descriptor_t *desc)
  37. {
  38. tor_assert(desc);
  39. digest256map_remove(hs_cache_v3_dir, desc->key);
  40. }
  41. /* Store a given descriptor in our cache. */
  42. static void
  43. store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc)
  44. {
  45. tor_assert(desc);
  46. digest256map_set(hs_cache_v3_dir, desc->key, desc);
  47. }
  48. /* Query our cache and return the entry or NULL if not found. */
  49. static hs_cache_dir_descriptor_t *
  50. lookup_v3_desc_as_dir(const uint8_t *key)
  51. {
  52. tor_assert(key);
  53. return digest256map_get(hs_cache_v3_dir, key);
  54. }
  55. #define cache_dir_desc_free(val) \
  56. FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
  57. /* Free a directory descriptor object. */
  58. static void
  59. cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc)
  60. {
  61. if (desc == NULL) {
  62. return;
  63. }
  64. hs_desc_plaintext_data_free(desc->plaintext_data);
  65. tor_free(desc->encoded_desc);
  66. tor_free(desc);
  67. }
  68. /* Helper function: Use by the free all function using the digest256map
  69. * interface to cache entries. */
  70. static void
  71. cache_dir_desc_free_void(void *ptr)
  72. {
  73. cache_dir_desc_free_(ptr);
  74. }
  75. /* Create a new directory cache descriptor object from a encoded descriptor.
  76. * On success, return the heap-allocated cache object, otherwise return NULL if
  77. * we can't decode the descriptor. */
  78. static hs_cache_dir_descriptor_t *
  79. cache_dir_desc_new(const char *desc)
  80. {
  81. hs_cache_dir_descriptor_t *dir_desc;
  82. tor_assert(desc);
  83. dir_desc = tor_malloc_zero(sizeof(hs_cache_dir_descriptor_t));
  84. dir_desc->plaintext_data =
  85. tor_malloc_zero(sizeof(hs_desc_plaintext_data_t));
  86. dir_desc->encoded_desc = tor_strdup(desc);
  87. if (hs_desc_decode_plaintext(desc, dir_desc->plaintext_data) < 0) {
  88. log_debug(LD_DIR, "Unable to decode descriptor. Rejecting.");
  89. goto err;
  90. }
  91. /* The blinded pubkey is the indexed key. */
  92. dir_desc->key = dir_desc->plaintext_data->blinded_pubkey.pubkey;
  93. dir_desc->created_ts = time(NULL);
  94. return dir_desc;
  95. err:
  96. cache_dir_desc_free(dir_desc);
  97. return NULL;
  98. }
  99. /* Return the size of a cache entry in bytes. */
  100. static size_t
  101. cache_get_dir_entry_size(const hs_cache_dir_descriptor_t *entry)
  102. {
  103. return (sizeof(*entry) + hs_desc_plaintext_obj_size(entry->plaintext_data)
  104. + strlen(entry->encoded_desc));
  105. }
  106. // PIRONION: v3 store
  107. static int
  108. hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc);
  109. /* Try to store a valid version 3 descriptor in the directory cache. Return 0
  110. * on success else a negative value is returned indicating that we have a
  111. * newer version in our cache. On error, caller is responsible to free the
  112. * given descriptor desc. */
  113. static int
  114. cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
  115. {
  116. hs_cache_dir_descriptor_t *cache_entry;
  117. tor_assert(desc);
  118. /* Verify if we have an entry in the cache for that key and if yes, check
  119. * if we should replace it? */
  120. cache_entry = lookup_v3_desc_as_dir(desc->key);
  121. if (cache_entry != NULL) {
  122. /* Only replace descriptor if revision-counter is greater than the one
  123. * in our cache */
  124. if (cache_entry->plaintext_data->revision_counter >=
  125. desc->plaintext_data->revision_counter) {
  126. log_info(LD_REND, "Descriptor revision counter in our cache is "
  127. "greater or equal than the one we received (%d/%d). "
  128. "Rejecting!",
  129. (int)cache_entry->plaintext_data->revision_counter,
  130. (int)desc->plaintext_data->revision_counter);
  131. goto err;
  132. }
  133. /* We now know that the descriptor we just received is a new one so
  134. * remove the entry we currently have from our cache so we can then
  135. * store the new one. */
  136. remove_v3_desc_as_dir(cache_entry);
  137. rend_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
  138. cache_dir_desc_free(cache_entry);
  139. }
  140. /* Store the descriptor we just got. We are sure here that either we
  141. * don't have the entry or we have a newer descriptor and the old one
  142. * has been removed from the cache. */
  143. store_v3_desc_as_dir(desc);
  144. /* Also send it to the PIR server if we have one. */
  145. hs_cache_pirserver_insert_desc(desc);
  146. /* Update our total cache size with this entry for the OOM. This uses the
  147. * old HS protocol cache subsystem for which we are tied with. */
  148. rend_cache_increment_allocation(cache_get_dir_entry_size(desc));
  149. /* XXX: Update HS statistics. We should have specific stats for v3. */
  150. return 0;
  151. err:
  152. return -1;
  153. }
  154. // PIRONION: v3 lookup
  155. /* Using the query which is the base64 encoded blinded key of a version 3
  156. * descriptor, lookup in our directory cache the entry. If found, 1 is
  157. * returned and desc_out is populated with a newly allocated string being the
  158. * encoded descriptor. If not found, 0 is returned and desc_out is untouched.
  159. * On error, a negative value is returned and desc_out is untouched. */
  160. static int
  161. cache_lookup_v3_as_dir(const char *query, const char **desc_out)
  162. {
  163. int found = 0;
  164. ed25519_public_key_t blinded_key;
  165. const hs_cache_dir_descriptor_t *entry;
  166. tor_assert(query);
  167. /* Decode blinded key using the given query value. */
  168. if (ed25519_public_from_base64(&blinded_key, query) < 0) {
  169. log_info(LD_REND, "Unable to decode the v3 HSDir query %s.",
  170. safe_str_client(query));
  171. goto err;
  172. }
  173. entry = lookup_v3_desc_as_dir(blinded_key.pubkey);
  174. if (entry != NULL) {
  175. found = 1;
  176. if (desc_out) {
  177. *desc_out = entry->encoded_desc;
  178. }
  179. }
  180. return found;
  181. err:
  182. return -1;
  183. }
  184. /* Clean the v3 cache by removing any entry that has expired using the
  185. * <b>global_cutoff</b> value. If <b>global_cutoff</b> is 0, the cleaning
  186. * process will use the lifetime found in the plaintext data section. Return
  187. * the number of bytes cleaned. */
  188. STATIC size_t
  189. cache_clean_v3_as_dir(time_t now, time_t global_cutoff)
  190. {
  191. size_t bytes_removed = 0;
  192. /* Code flow error if this ever happens. */
  193. tor_assert(global_cutoff >= 0);
  194. if (!hs_cache_v3_dir) { /* No cache to clean. Just return. */
  195. return 0;
  196. }
  197. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_dir, key,
  198. hs_cache_dir_descriptor_t *, entry) {
  199. size_t entry_size;
  200. time_t cutoff = global_cutoff;
  201. if (!cutoff) {
  202. /* Cutoff is the lifetime of the entry found in the descriptor. */
  203. cutoff = now - entry->plaintext_data->lifetime_sec;
  204. }
  205. /* If the entry has been created _after_ the cutoff, not expired so
  206. * continue to the next entry in our v3 cache. */
  207. if (entry->created_ts > cutoff) {
  208. continue;
  209. }
  210. /* Here, our entry has expired, remove and free. */
  211. MAP_DEL_CURRENT(key);
  212. entry_size = cache_get_dir_entry_size(entry);
  213. bytes_removed += entry_size;
  214. /* Entry is not in the cache anymore, destroy it. */
  215. cache_dir_desc_free(entry);
  216. /* Update our cache entry allocation size for the OOM. */
  217. rend_cache_decrement_allocation(entry_size);
  218. /* Logging. */
  219. {
  220. char key_b64[BASE64_DIGEST256_LEN + 1];
  221. digest256_to_base64(key_b64, (const char *) key);
  222. log_info(LD_REND, "Removing v3 descriptor '%s' from HSDir cache",
  223. safe_str_client(key_b64));
  224. }
  225. } DIGEST256MAP_FOREACH_END;
  226. return bytes_removed;
  227. }
  228. /* Given an encoded descriptor, store it in the directory cache depending on
  229. * which version it is. Return a negative value on error. On success, 0 is
  230. * returned. */
  231. int
  232. hs_cache_store_as_dir(const char *desc)
  233. {
  234. hs_cache_dir_descriptor_t *dir_desc = NULL;
  235. tor_assert(desc);
  236. /* Create a new cache object. This can fail if the descriptor plaintext data
  237. * is unparseable which in this case a log message will be triggered. */
  238. dir_desc = cache_dir_desc_new(desc);
  239. if (dir_desc == NULL) {
  240. goto err;
  241. }
  242. /* Call the right function against the descriptor version. At this point,
  243. * we are sure that the descriptor's version is supported else the
  244. * decoding would have failed. */
  245. switch (dir_desc->plaintext_data->version) {
  246. case HS_VERSION_THREE:
  247. default:
  248. if (cache_store_v3_as_dir(dir_desc) < 0) {
  249. goto err;
  250. }
  251. break;
  252. }
  253. return 0;
  254. err:
  255. cache_dir_desc_free(dir_desc);
  256. return -1;
  257. }
  258. /* Using the query, lookup in our directory cache the entry. If found, 1 is
  259. * returned and desc_out is populated with a newly allocated string being
  260. * the encoded descriptor. If not found, 0 is returned and desc_out is
  261. * untouched. On error, a negative value is returned and desc_out is
  262. * untouched. */
  263. int
  264. hs_cache_lookup_as_dir(uint32_t version, const char *query,
  265. const char **desc_out)
  266. {
  267. int found;
  268. tor_assert(query);
  269. /* This should never be called with an unsupported version. */
  270. tor_assert(hs_desc_is_supported_version(version));
  271. switch (version) {
  272. case HS_VERSION_THREE:
  273. default:
  274. found = cache_lookup_v3_as_dir(query, desc_out);
  275. break;
  276. }
  277. return found;
  278. }
  279. /* Clean all directory caches using the current time now. */
  280. void
  281. hs_cache_clean_as_dir(time_t now)
  282. {
  283. time_t cutoff;
  284. /* Start with v2 cache cleaning. */
  285. cutoff = now - rend_cache_max_entry_lifetime();
  286. rend_cache_clean_v2_descs_as_dir(cutoff);
  287. /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
  288. * to compute the cutoff by itself using the lifetime value. */
  289. cache_clean_v3_as_dir(now, 0);
  290. }
  291. /********************** Client-side HS cache ******************/
  292. /* Client-side HS descriptor cache. Map indexed by service identity key. */
  293. static digest256map_t *hs_cache_v3_client;
  294. /* Client-side introduction point state cache. Map indexed by service public
  295. * identity key (onion address). It contains hs_cache_client_intro_state_t
  296. * objects all related to a specific service. */
  297. static digest256map_t *hs_cache_client_intro_state;
  298. /* Return the size of a client cache entry in bytes. */
  299. static size_t
  300. cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry)
  301. {
  302. return sizeof(*entry) +
  303. strlen(entry->encoded_desc) + hs_desc_obj_size(entry->desc);
  304. }
  305. /* Remove a given descriptor from our cache. */
  306. static void
  307. remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
  308. {
  309. tor_assert(desc);
  310. digest256map_remove(hs_cache_v3_client, desc->key.pubkey);
  311. /* Update cache size with this entry for the OOM handler. */
  312. rend_cache_decrement_allocation(cache_get_client_entry_size(desc));
  313. }
  314. /* Store a given descriptor in our cache. */
  315. static void
  316. store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
  317. {
  318. tor_assert(desc);
  319. digest256map_set(hs_cache_v3_client, desc->key.pubkey, desc);
  320. /* Update cache size with this entry for the OOM handler. */
  321. rend_cache_increment_allocation(cache_get_client_entry_size(desc));
  322. }
  323. /* Query our cache and return the entry or NULL if not found or if expired. */
  324. STATIC hs_cache_client_descriptor_t *
  325. lookup_v3_desc_as_client(const uint8_t *key)
  326. {
  327. time_t now = approx_time();
  328. hs_cache_client_descriptor_t *cached_desc;
  329. tor_assert(key);
  330. /* Do the lookup */
  331. cached_desc = digest256map_get(hs_cache_v3_client, key);
  332. if (!cached_desc) {
  333. return NULL;
  334. }
  335. /* Don't return expired entries */
  336. if (cached_client_descriptor_has_expired(now, cached_desc)) {
  337. return NULL;
  338. }
  339. return cached_desc;
  340. }
  341. /* Parse the encoded descriptor in <b>desc_str</b> using
  342. * <b>service_identity_pk<b> to decrypt it first.
  343. *
  344. * If everything goes well, allocate and return a new
  345. * hs_cache_client_descriptor_t object. In case of error, return NULL. */
  346. static hs_cache_client_descriptor_t *
  347. cache_client_desc_new(const char *desc_str,
  348. const ed25519_public_key_t *service_identity_pk)
  349. {
  350. hs_descriptor_t *desc = NULL;
  351. hs_cache_client_descriptor_t *client_desc = NULL;
  352. tor_assert(desc_str);
  353. tor_assert(service_identity_pk);
  354. /* Decode the descriptor we just fetched. */
  355. if (hs_client_decode_descriptor(desc_str, service_identity_pk, &desc) < 0) {
  356. goto end;
  357. }
  358. tor_assert(desc);
  359. /* All is good: make a cache object for this descriptor */
  360. client_desc = tor_malloc_zero(sizeof(hs_cache_client_descriptor_t));
  361. ed25519_pubkey_copy(&client_desc->key, service_identity_pk);
  362. /* Set expiration time for this cached descriptor to be the start of the next
  363. * time period since that's when clients need to start using the next blinded
  364. * pk of the service (and hence will need its next descriptor). */
  365. client_desc->expiration_ts = hs_get_start_time_of_next_time_period(0);
  366. client_desc->desc = desc;
  367. client_desc->encoded_desc = tor_strdup(desc_str);
  368. end:
  369. return client_desc;
  370. }
  371. #define cache_client_desc_free(val) \
  372. FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
  373. /** Free memory allocated by <b>desc</b>. */
  374. static void
  375. cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
  376. {
  377. if (desc == NULL) {
  378. return;
  379. }
  380. hs_descriptor_free(desc->desc);
  381. memwipe(&desc->key, 0, sizeof(desc->key));
  382. memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
  383. tor_free(desc->encoded_desc);
  384. tor_free(desc);
  385. }
  386. /** Helper function: Use by the free all function to clear the client cache */
  387. static void
  388. cache_client_desc_free_void(void *ptr)
  389. {
  390. hs_cache_client_descriptor_t *desc = ptr;
  391. cache_client_desc_free(desc);
  392. }
  393. /* Return a newly allocated and initialized hs_cache_intro_state_t object. */
  394. static hs_cache_intro_state_t *
  395. cache_intro_state_new(void)
  396. {
  397. hs_cache_intro_state_t *state = tor_malloc_zero(sizeof(*state));
  398. state->created_ts = approx_time();
  399. return state;
  400. }
  401. #define cache_intro_state_free(val) \
  402. FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
  403. /* Free an hs_cache_intro_state_t object. */
  404. static void
  405. cache_intro_state_free_(hs_cache_intro_state_t *state)
  406. {
  407. tor_free(state);
  408. }
  409. /* Helper function: used by the free all function. */
  410. static void
  411. cache_intro_state_free_void(void *state)
  412. {
  413. cache_intro_state_free_(state);
  414. }
  415. /* Return a newly allocated and initialized hs_cache_client_intro_state_t
  416. * object. */
  417. static hs_cache_client_intro_state_t *
  418. cache_client_intro_state_new(void)
  419. {
  420. hs_cache_client_intro_state_t *cache = tor_malloc_zero(sizeof(*cache));
  421. cache->intro_points = digest256map_new();
  422. return cache;
  423. }
  424. #define cache_client_intro_state_free(val) \
  425. FREE_AND_NULL(hs_cache_client_intro_state_t, \
  426. cache_client_intro_state_free_, (val))
  427. /* Free a cache_client_intro_state object. */
  428. static void
  429. cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache)
  430. {
  431. if (cache == NULL) {
  432. return;
  433. }
  434. digest256map_free(cache->intro_points, cache_intro_state_free_void);
  435. tor_free(cache);
  436. }
  437. /* Helper function: used by the free all function. */
  438. static void
  439. cache_client_intro_state_free_void(void *entry)
  440. {
  441. cache_client_intro_state_free_(entry);
  442. }
  443. /* For the given service identity key service_pk and an introduction
  444. * authentication key auth_key, lookup the intro state object. Return 1 if
  445. * found and put it in entry if not NULL. Return 0 if not found and entry is
  446. * untouched. */
  447. static int
  448. cache_client_intro_state_lookup(const ed25519_public_key_t *service_pk,
  449. const ed25519_public_key_t *auth_key,
  450. hs_cache_intro_state_t **entry)
  451. {
  452. hs_cache_intro_state_t *state;
  453. hs_cache_client_intro_state_t *cache;
  454. tor_assert(service_pk);
  455. tor_assert(auth_key);
  456. /* Lookup the intro state cache for this service key. */
  457. cache = digest256map_get(hs_cache_client_intro_state, service_pk->pubkey);
  458. if (cache == NULL) {
  459. goto not_found;
  460. }
  461. /* From the cache we just found for the service, lookup in the introduction
  462. * points map for the given authentication key. */
  463. state = digest256map_get(cache->intro_points, auth_key->pubkey);
  464. if (state == NULL) {
  465. goto not_found;
  466. }
  467. if (entry) {
  468. *entry = state;
  469. }
  470. return 1;
  471. not_found:
  472. return 0;
  473. }
  474. /* Note the given failure in state. */
  475. static void
  476. cache_client_intro_state_note(hs_cache_intro_state_t *state,
  477. rend_intro_point_failure_t failure)
  478. {
  479. tor_assert(state);
  480. switch (failure) {
  481. case INTRO_POINT_FAILURE_GENERIC:
  482. state->error = 1;
  483. break;
  484. case INTRO_POINT_FAILURE_TIMEOUT:
  485. state->timed_out = 1;
  486. break;
  487. case INTRO_POINT_FAILURE_UNREACHABLE:
  488. state->unreachable_count++;
  489. break;
  490. default:
  491. tor_assert_nonfatal_unreached();
  492. return;
  493. }
  494. }
  495. /* For the given service identity key service_pk and an introduction
  496. * authentication key auth_key, add an entry in the client intro state cache
  497. * If no entry exists for the service, it will create one. If state is non
  498. * NULL, it will point to the new intro state entry. */
  499. static void
  500. cache_client_intro_state_add(const ed25519_public_key_t *service_pk,
  501. const ed25519_public_key_t *auth_key,
  502. hs_cache_intro_state_t **state)
  503. {
  504. hs_cache_intro_state_t *entry, *old_entry;
  505. hs_cache_client_intro_state_t *cache;
  506. tor_assert(service_pk);
  507. tor_assert(auth_key);
  508. /* Lookup the state cache for this service key. */
  509. cache = digest256map_get(hs_cache_client_intro_state, service_pk->pubkey);
  510. if (cache == NULL) {
  511. cache = cache_client_intro_state_new();
  512. digest256map_set(hs_cache_client_intro_state, service_pk->pubkey, cache);
  513. }
  514. entry = cache_intro_state_new();
  515. old_entry = digest256map_set(cache->intro_points, auth_key->pubkey, entry);
  516. /* This should never happened because the code flow is to lookup the entry
  517. * before adding it. But, just in case, non fatal assert and free it. */
  518. tor_assert_nonfatal(old_entry == NULL);
  519. tor_free(old_entry);
  520. if (state) {
  521. *state = entry;
  522. }
  523. }
  524. /* Remove every intro point state entry from cache that has been created
  525. * before or at the cutoff. */
  526. static void
  527. cache_client_intro_state_clean(time_t cutoff,
  528. hs_cache_client_intro_state_t *cache)
  529. {
  530. tor_assert(cache);
  531. DIGEST256MAP_FOREACH_MODIFY(cache->intro_points, key,
  532. hs_cache_intro_state_t *, entry) {
  533. if (entry->created_ts <= cutoff) {
  534. cache_intro_state_free(entry);
  535. MAP_DEL_CURRENT(key);
  536. }
  537. } DIGEST256MAP_FOREACH_END;
  538. }
  539. /* Return true iff no intro points are in this cache. */
  540. static int
  541. cache_client_intro_state_is_empty(const hs_cache_client_intro_state_t *cache)
  542. {
  543. return digest256map_isempty(cache->intro_points);
  544. }
  545. /** Check whether <b>client_desc</b> is useful for us, and store it in the
  546. * client-side HS cache if so. The client_desc is freed if we already have a
  547. * fresher (higher revision counter count) in the cache. */
  548. static int
  549. cache_store_as_client(hs_cache_client_descriptor_t *client_desc)
  550. {
  551. hs_cache_client_descriptor_t *cache_entry;
  552. /* TODO: Heavy code duplication with cache_store_as_dir(). Consider
  553. * refactoring and uniting! */
  554. tor_assert(client_desc);
  555. /* Check if we already have a descriptor from this HS in cache. If we do,
  556. * check if this descriptor is newer than the cached one */
  557. cache_entry = lookup_v3_desc_as_client(client_desc->key.pubkey);
  558. if (cache_entry != NULL) {
  559. /* If we have an entry in our cache that has a revision counter greater
  560. * than the one we just fetched, discard the one we fetched. */
  561. if (cache_entry->desc->plaintext_data.revision_counter >
  562. client_desc->desc->plaintext_data.revision_counter) {
  563. cache_client_desc_free(client_desc);
  564. goto done;
  565. }
  566. /* Remove old entry. Make space for the new one! */
  567. remove_v3_desc_as_client(cache_entry);
  568. /* We just removed an old descriptor and will replace it. We'll close all
  569. * intro circuits related to this old one so we don't have leftovers. We
  570. * leave the rendezvous circuits opened because they could be in use. */
  571. hs_client_close_intro_circuits_from_desc(cache_entry->desc);
  572. /* Free it. */
  573. cache_client_desc_free(cache_entry);
  574. }
  575. /* Store descriptor in cache */
  576. store_v3_desc_as_client(client_desc);
  577. done:
  578. return 0;
  579. }
  580. /* Return true iff the cached client descriptor at <b>cached_desc</b has
  581. * expired. */
  582. static int
  583. cached_client_descriptor_has_expired(time_t now,
  584. const hs_cache_client_descriptor_t *cached_desc)
  585. {
  586. /* We use the current consensus time to see if we should expire this
  587. * descriptor since we use consensus time for all other parts of the protocol
  588. * as well (e.g. to build the blinded key and compute time periods). */
  589. const networkstatus_t *ns = networkstatus_get_live_consensus(now);
  590. /* If we don't have a recent consensus, consider this entry expired since we
  591. * will want to fetch a new HS desc when we get a live consensus. */
  592. if (!ns) {
  593. return 1;
  594. }
  595. if (cached_desc->expiration_ts <= ns->valid_after) {
  596. return 1;
  597. }
  598. return 0;
  599. }
  600. /* clean the client cache using now as the current time. Return the total size
  601. * of removed bytes from the cache. */
  602. static size_t
  603. cache_clean_v3_as_client(time_t now)
  604. {
  605. size_t bytes_removed = 0;
  606. if (!hs_cache_v3_client) { /* No cache to clean. Just return. */
  607. return 0;
  608. }
  609. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key,
  610. hs_cache_client_descriptor_t *, entry) {
  611. size_t entry_size;
  612. /* If the entry has not expired, continue to the next cached entry */
  613. if (!cached_client_descriptor_has_expired(now, entry)) {
  614. continue;
  615. }
  616. /* Here, our entry has expired, remove and free. */
  617. MAP_DEL_CURRENT(key);
  618. entry_size = cache_get_client_entry_size(entry);
  619. bytes_removed += entry_size;
  620. /* Entry is not in the cache anymore, destroy it. */
  621. cache_client_desc_free(entry);
  622. /* Update our OOM. We didn't use the remove() function because we are in
  623. * a loop so we have to explicitly decrement. */
  624. rend_cache_decrement_allocation(entry_size);
  625. /* Logging. */
  626. {
  627. char key_b64[BASE64_DIGEST256_LEN + 1];
  628. digest256_to_base64(key_b64, (const char *) key);
  629. log_info(LD_REND, "Removing hidden service v3 descriptor '%s' "
  630. "from client cache",
  631. safe_str_client(key_b64));
  632. }
  633. } DIGEST256MAP_FOREACH_END;
  634. return bytes_removed;
  635. }
  636. /** Public API: Given the HS ed25519 identity public key in <b>key</b>, return
  637. * its HS encoded descriptor if it's stored in our cache, or NULL if not. */
  638. const char *
  639. hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key)
  640. {
  641. hs_cache_client_descriptor_t *cached_desc = NULL;
  642. tor_assert(key);
  643. cached_desc = lookup_v3_desc_as_client(key->pubkey);
  644. if (cached_desc) {
  645. tor_assert(cached_desc->encoded_desc);
  646. return cached_desc->encoded_desc;
  647. }
  648. return NULL;
  649. }
  650. /** Public API: Given the HS ed25519 identity public key in <b>key</b>, return
  651. * its HS descriptor if it's stored in our cache, or NULL if not. */
  652. const hs_descriptor_t *
  653. hs_cache_lookup_as_client(const ed25519_public_key_t *key)
  654. {
  655. hs_cache_client_descriptor_t *cached_desc = NULL;
  656. tor_assert(key);
  657. cached_desc = lookup_v3_desc_as_client(key->pubkey);
  658. if (cached_desc) {
  659. tor_assert(cached_desc->desc);
  660. return cached_desc->desc;
  661. }
  662. return NULL;
  663. }
  664. /** Public API: Given an encoded descriptor, store it in the client HS
  665. * cache. Return -1 on error, 0 on success .*/
  666. int
  667. hs_cache_store_as_client(const char *desc_str,
  668. const ed25519_public_key_t *identity_pk)
  669. {
  670. hs_cache_client_descriptor_t *client_desc = NULL;
  671. tor_assert(desc_str);
  672. tor_assert(identity_pk);
  673. /* Create client cache descriptor object */
  674. client_desc = cache_client_desc_new(desc_str, identity_pk);
  675. if (!client_desc) {
  676. log_warn(LD_GENERAL, "HSDesc parsing failed!");
  677. log_debug(LD_GENERAL, "Failed to parse HSDesc: %s.", escaped(desc_str));
  678. goto err;
  679. }
  680. /* Push it to the cache */
  681. if (cache_store_as_client(client_desc) < 0) {
  682. goto err;
  683. }
  684. return 0;
  685. err:
  686. cache_client_desc_free(client_desc);
  687. return -1;
  688. }
  689. /* Clean all client caches using the current time now. */
  690. void
  691. hs_cache_clean_as_client(time_t now)
  692. {
  693. /* Start with v2 cache cleaning. */
  694. rend_cache_clean(now, REND_CACHE_TYPE_CLIENT);
  695. /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
  696. * to compute the cutoff by itself using the lifetime value. */
  697. cache_clean_v3_as_client(now);
  698. }
  699. /* Purge the client descriptor cache. */
  700. void
  701. hs_cache_purge_as_client(void)
  702. {
  703. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key,
  704. hs_cache_client_descriptor_t *, entry) {
  705. size_t entry_size = cache_get_client_entry_size(entry);
  706. MAP_DEL_CURRENT(key);
  707. cache_client_desc_free(entry);
  708. /* Update our OOM. We didn't use the remove() function because we are in
  709. * a loop so we have to explicitly decrement. */
  710. rend_cache_decrement_allocation(entry_size);
  711. } DIGEST256MAP_FOREACH_END;
  712. log_info(LD_REND, "Hidden service client descriptor cache purged.");
  713. }
  714. /* For a given service identity public key and an introduction authentication
  715. * key, note the given failure in the client intro state cache. */
  716. void
  717. hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk,
  718. const ed25519_public_key_t *auth_key,
  719. rend_intro_point_failure_t failure)
  720. {
  721. int found;
  722. hs_cache_intro_state_t *entry;
  723. tor_assert(service_pk);
  724. tor_assert(auth_key);
  725. found = cache_client_intro_state_lookup(service_pk, auth_key, &entry);
  726. if (!found) {
  727. /* Create a new entry and add it to the cache. */
  728. cache_client_intro_state_add(service_pk, auth_key, &entry);
  729. }
  730. /* Note down the entry. */
  731. cache_client_intro_state_note(entry, failure);
  732. }
  733. /* For a given service identity public key and an introduction authentication
  734. * key, return true iff it is present in the failure cache. */
  735. const hs_cache_intro_state_t *
  736. hs_cache_client_intro_state_find(const ed25519_public_key_t *service_pk,
  737. const ed25519_public_key_t *auth_key)
  738. {
  739. hs_cache_intro_state_t *state = NULL;
  740. cache_client_intro_state_lookup(service_pk, auth_key, &state);
  741. return state;
  742. }
  743. /* Cleanup the client introduction state cache. */
  744. void
  745. hs_cache_client_intro_state_clean(time_t now)
  746. {
  747. time_t cutoff = now - HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE;
  748. DIGEST256MAP_FOREACH_MODIFY(hs_cache_client_intro_state, key,
  749. hs_cache_client_intro_state_t *, cache) {
  750. /* Cleanup intro points failure. */
  751. cache_client_intro_state_clean(cutoff, cache);
  752. /* Is this cache empty for this service key? If yes, remove it from the
  753. * cache. Else keep it. */
  754. if (cache_client_intro_state_is_empty(cache)) {
  755. cache_client_intro_state_free(cache);
  756. MAP_DEL_CURRENT(key);
  757. }
  758. } DIGEST256MAP_FOREACH_END;
  759. }
  760. /* Purge the client introduction state cache. */
  761. void
  762. hs_cache_client_intro_state_purge(void)
  763. {
  764. DIGEST256MAP_FOREACH_MODIFY(hs_cache_client_intro_state, key,
  765. hs_cache_client_intro_state_t *, cache) {
  766. MAP_DEL_CURRENT(key);
  767. cache_client_intro_state_free(cache);
  768. } DIGEST256MAP_FOREACH_END;
  769. log_info(LD_REND, "Hidden service client introduction point state "
  770. "cache purged.");
  771. }
  772. /**************** Generics *********************************/
  773. /* Do a round of OOM cleanup on all directory caches. Return the amount of
  774. * removed bytes. It is possible that the returned value is lower than
  775. * min_remove_bytes if the caches get emptied out so the caller should be
  776. * aware of this. */
  777. size_t
  778. hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
  779. {
  780. time_t k;
  781. size_t bytes_removed = 0;
  782. /* Our OOM handler called with 0 bytes to remove is a code flow error. */
  783. tor_assert(min_remove_bytes != 0);
  784. /* The algorithm is as follow. K is the oldest expected descriptor age.
  785. *
  786. * 1) Deallocate all entries from v2 cache that are older than K hours.
  787. * 1.1) If the amount of remove bytes has been reached, stop.
  788. * 2) Deallocate all entries from v3 cache that are older than K hours
  789. * 2.1) If the amount of remove bytes has been reached, stop.
  790. * 3) Set K = K - RendPostPeriod and repeat process until K is < 0.
  791. *
  792. * This ends up being O(Kn).
  793. */
  794. /* Set K to the oldest expected age in seconds which is the maximum
  795. * lifetime of a cache entry. We'll use the v2 lifetime because it's much
  796. * bigger than the v3 thus leading to cleaning older descriptors. */
  797. k = rend_cache_max_entry_lifetime();
  798. do {
  799. time_t cutoff;
  800. /* If K becomes negative, it means we've empty the caches so stop and
  801. * return what we were able to cleanup. */
  802. if (k < 0) {
  803. break;
  804. }
  805. /* Compute a cutoff value with K and the current time. */
  806. cutoff = now - k;
  807. /* Start by cleaning the v2 cache with that cutoff. */
  808. bytes_removed += rend_cache_clean_v2_descs_as_dir(cutoff);
  809. if (bytes_removed < min_remove_bytes) {
  810. /* We haven't remove enough bytes so clean v3 cache. */
  811. bytes_removed += cache_clean_v3_as_dir(now, cutoff);
  812. /* Decrement K by a post period to shorten the cutoff. */
  813. k -= get_options()->RendPostPeriod;
  814. }
  815. } while (bytes_removed < min_remove_bytes);
  816. return bytes_removed;
  817. }
  818. /* Return the maximum size of a v3 HS descriptor. */
  819. unsigned int
  820. hs_cache_get_max_descriptor_size(void)
  821. {
  822. return (unsigned) networkstatus_get_param(NULL,
  823. "HSV3MaxDescriptorSize",
  824. HS_DESC_MAX_LEN, 1, INT32_MAX);
  825. }
  826. static process_handle_t *pirserver;
  827. static buf_t *pirserver_stdin_buf;
  828. static struct event *pirserver_stdin_ev;
  829. static struct event *pirserver_stdout_ev;
  830. static struct event *pirserver_stderr_ev;
  831. typedef enum {
  832. PIRSERVER_READSTATE_HEADER,
  833. PIRSERVER_READSTATE_BODY
  834. } PIRServerReadState;
  835. #define PIRSERVER_HDR_SIZE 13
  836. #define PIRSERVER_REQUEST_PARAMS 0x01
  837. #define PIRSERVER_REQUEST_STORE 0x02
  838. #define PIRSERVER_REQUEST_LOOKUP 0x03
  839. #define PIRSERVER_RESPONSE_PARAMS 0xFF
  840. #define PIRSERVER_RESPONSE_LOOKUP_SUCCESS 0xFE
  841. #define PIRSERVER_RESPONSE_LOOKUP_FAILURE 0xFD
  842. static void
  843. hs_cache_pirserver_received(const unsigned char *hdrbuf,
  844. const char *bodybuf, size_t bodylen)
  845. {
  846. /* PIRONION TODO: actually deliver the received message */
  847. log_info(LD_DIRSERV,"PIRSERVER response header %p flag %d body len %ld body %s", *(void**)hdrbuf, hdrbuf[8], bodylen, escaped(bodybuf));
  848. }
  849. /* This is called when the pirserver has output for us. */
  850. static void
  851. hs_cache_pirserver_stdoutcb(evutil_socket_t fd, short what,
  852. ATTR_UNUSED void *arg) {
  853. static PIRServerReadState readstate = PIRSERVER_READSTATE_HEADER;
  854. static size_t readoff = 0;
  855. static size_t readleft = PIRSERVER_HDR_SIZE;
  856. static unsigned char hdrbuf[PIRSERVER_HDR_SIZE];
  857. static char *bodybuf = NULL;
  858. if (!(what & EV_READ)) {
  859. /* Not sure why we're here */
  860. return;
  861. }
  862. if (readstate == PIRSERVER_READSTATE_HEADER) {
  863. int res = read(fd, hdrbuf + readoff, readleft);
  864. if (res <= 0) return;
  865. readoff += res;
  866. readleft -= res;
  867. if (readleft == 0) {
  868. readleft = ntohl(*(uint32_t*)(hdrbuf+PIRSERVER_HDR_SIZE-4));
  869. free(bodybuf);
  870. bodybuf = NULL;
  871. if (readleft > 0) {
  872. bodybuf = malloc(readleft);
  873. readoff = 0;
  874. readstate = PIRSERVER_READSTATE_BODY;
  875. } else {
  876. hs_cache_pirserver_received(hdrbuf, NULL, 0);
  877. readoff = 0;
  878. readleft = PIRSERVER_HDR_SIZE;
  879. readstate = PIRSERVER_READSTATE_HEADER;
  880. }
  881. }
  882. } else if (readstate == PIRSERVER_READSTATE_BODY) {
  883. int res = read(fd, bodybuf + readoff, readleft);
  884. if (res <= 0) return;
  885. readoff += res;
  886. readleft -= res;
  887. if (readleft == 0) {
  888. /* Reading is complete */
  889. hs_cache_pirserver_received(hdrbuf, bodybuf, readoff);
  890. /* Prepare for the next output from the PIR server */
  891. free(bodybuf);
  892. bodybuf = NULL;
  893. readoff = 0;
  894. readleft = PIRSERVER_HDR_SIZE;
  895. readstate = PIRSERVER_READSTATE_HEADER;
  896. }
  897. }
  898. }
  899. /* This is called when the pirserver is ready to read from its stdin. */
  900. static void
  901. hs_cache_pirserver_stdincb(evutil_socket_t fd, short what,
  902. ATTR_UNUSED void *arg) {
  903. int res;
  904. size_t bufsize = buf_datalen(pirserver_stdin_buf);
  905. char *netbuf = NULL;
  906. if (!(what & EV_WRITE)) {
  907. /* Not sure why we're here */
  908. log_info(LD_DIRSERV,"PIRSERVER bailing");
  909. return;
  910. }
  911. if (bufsize == 0) {
  912. log_err(LD_DIRSERV,"PIRSERVER trying to write 0-length buffer");
  913. return;
  914. }
  915. netbuf = malloc(bufsize);
  916. if (netbuf == NULL) {
  917. log_err(LD_DIRSERV,"PIRSERVER failed to allocate buffer");
  918. return;
  919. }
  920. /* One might think that just calling buf_flush_to_socket would be
  921. * the thing to do, but that function ends up calling sendto()
  922. * instead of write(), which doesn't work on pipes. So we do it
  923. * more manually. Using a bufferevent may be another option. */
  924. buf_peek(pirserver_stdin_buf, netbuf, bufsize);
  925. res = write(fd, netbuf, bufsize);
  926. free(netbuf);
  927. if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
  928. /* Try writing again later */
  929. event_add(pirserver_stdin_ev, NULL);
  930. return;
  931. }
  932. if (res <= 0) {
  933. /* Stop trying to write. */
  934. return;
  935. }
  936. buf_drain(pirserver_stdin_buf, res);
  937. bufsize -= res;
  938. if (bufsize > 0) {
  939. /* There's more to write */
  940. event_add(pirserver_stdin_ev, NULL);
  941. }
  942. }
  943. /* This is called when the pirserver writes something to its stderr. */
  944. static void
  945. hs_cache_pirserver_stderrcb(evutil_socket_t fd, short what,
  946. ATTR_UNUSED void *arg) {
  947. if (!(what & EV_READ)) {
  948. /* Not sure why we're here */
  949. return;
  950. }
  951. char buf[1000];
  952. int res = read(fd, buf, sizeof(buf)-1);
  953. if (res <= 0) return;
  954. buf[res] = '\0';
  955. log_info(LD_DIRSERV,"PIRSERVER %s", escaped(buf));
  956. }
  957. /* Poke the hidden service cache PIR subsystem to launch the PIR
  958. server if needed. */
  959. static void
  960. hs_cache_pir_poke(void)
  961. {
  962. int res;
  963. const char *pirserverpath = getenv("PIR_SERVER_PATH");
  964. smartlist_t *env_vars = get_current_process_environment_variables();
  965. const char *argv[2];
  966. process_environment_t *env;
  967. if (pirserver && pirserver->status == PROCESS_STATUS_RUNNING) {
  968. /* The PIR server appears to be open */
  969. return;
  970. }
  971. if (pirserver) {
  972. if (pirserver_stdin_buf) {
  973. buf_free(pirserver_stdin_buf);
  974. pirserver_stdin_buf = NULL;
  975. }
  976. if (pirserver_stdin_ev) {
  977. event_free(pirserver_stdin_ev);
  978. pirserver_stdin_ev = NULL;
  979. }
  980. if (pirserver_stdout_ev) {
  981. event_free(pirserver_stdout_ev);
  982. pirserver_stdout_ev = NULL;
  983. }
  984. if (pirserver_stderr_ev) {
  985. event_free(pirserver_stderr_ev);
  986. pirserver_stderr_ev = NULL;
  987. }
  988. tor_process_handle_destroy(pirserver, 1);
  989. pirserver = NULL;
  990. }
  991. if (!pirserverpath) {
  992. /* We don't have a configured PIR server */
  993. return;
  994. }
  995. argv[0] = pirserverpath;
  996. argv[1] = NULL;
  997. env = process_environment_make(env_vars);
  998. res = tor_spawn_background(pirserverpath, argv, env, &pirserver);
  999. SMARTLIST_FOREACH(env_vars, void *, x, tor_free(x));
  1000. smartlist_free(env_vars);
  1001. if (res != PROCESS_STATUS_RUNNING) {
  1002. /* Launch failure */
  1003. return;
  1004. }
  1005. /* Create a libevent event to listen to the PIR server's responses. */
  1006. pirserver_stdout_ev = event_new(tor_libevent_get_base(),
  1007. pirserver->stdout_pipe, EV_READ|EV_PERSIST,
  1008. hs_cache_pirserver_stdoutcb, NULL);
  1009. event_add(pirserver_stdout_ev, NULL);
  1010. /* And one to listen to the PIR server's stderr. */
  1011. pirserver_stderr_ev = event_new(tor_libevent_get_base(),
  1012. pirserver->stderr_pipe, EV_READ|EV_PERSIST,
  1013. hs_cache_pirserver_stderrcb, NULL);
  1014. event_add(pirserver_stderr_ev, NULL);
  1015. /* And one for writability to the pirserver's stdin, but don't add
  1016. * it just yet. Also create the buffer it will use. */
  1017. pirserver_stdin_buf = buf_new();
  1018. pirserver_stdin_ev = event_new(tor_libevent_get_base(),
  1019. pirserver->stdin_pipe, EV_WRITE, hs_cache_pirserver_stdincb,
  1020. NULL);
  1021. }
  1022. /* Initialize the hidden service cache PIR subsystem. */
  1023. static void
  1024. hs_cache_pir_init(void)
  1025. {
  1026. pirserver = NULL;
  1027. pirserver_stdin_buf = NULL;
  1028. pirserver_stdin_ev = NULL;
  1029. pirserver_stdout_ev = NULL;
  1030. pirserver_stderr_ev = NULL;
  1031. }
  1032. static int
  1033. hs_cache_pirserver_send(const unsigned char *buf, size_t len)
  1034. {
  1035. hs_cache_pir_poke();
  1036. if (pirserver == NULL || pirserver->status != PROCESS_STATUS_RUNNING) {
  1037. /* Launch failed */
  1038. return -1;
  1039. }
  1040. /* Write the data to the stdin buffer */
  1041. if (len > 0) {
  1042. buf_add(pirserver_stdin_buf, (const char *)buf, len);
  1043. event_add(pirserver_stdin_ev, NULL);
  1044. }
  1045. return len;
  1046. }
  1047. static int
  1048. hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc)
  1049. {
  1050. unsigned char hdr[13];
  1051. size_t encoded_desc_len;
  1052. size_t len;
  1053. int res;
  1054. int written = 0;
  1055. static uint32_t inscounter = 0;
  1056. memmove(hdr, "\0\0\0\0", 4);
  1057. ++inscounter;
  1058. *(uint32_t*)(hdr+4) = htonl(inscounter);
  1059. hdr[8] = PIRSERVER_REQUEST_STORE;
  1060. encoded_desc_len = strlen(desc->encoded_desc);
  1061. len = DIGEST256_LEN + encoded_desc_len;
  1062. *(uint32_t*)(hdr+9) = htonl(len);
  1063. res = hs_cache_pirserver_send(hdr, PIRSERVER_HDR_SIZE);
  1064. if (res <= 0) return -1;
  1065. written += res;
  1066. res = hs_cache_pirserver_send(desc->key, DIGEST256_LEN);
  1067. if (res <= 0) return -1;
  1068. written += res;
  1069. res = hs_cache_pirserver_send(
  1070. (const unsigned char *)desc->encoded_desc,
  1071. encoded_desc_len);
  1072. if (res <= 0) return -1;
  1073. written += res;
  1074. return written;
  1075. }
  1076. /* Initialize the hidden service cache subsystem. */
  1077. void
  1078. hs_cache_init(void)
  1079. {
  1080. /* Calling this twice is very wrong code flow. */
  1081. tor_assert(!hs_cache_v3_dir);
  1082. hs_cache_v3_dir = digest256map_new();
  1083. tor_assert(!hs_cache_v3_client);
  1084. hs_cache_v3_client = digest256map_new();
  1085. tor_assert(!hs_cache_client_intro_state);
  1086. hs_cache_client_intro_state = digest256map_new();
  1087. hs_cache_pir_init();
  1088. }
  1089. /* Cleanup the hidden service cache subsystem. */
  1090. void
  1091. hs_cache_free_all(void)
  1092. {
  1093. digest256map_free(hs_cache_v3_dir, cache_dir_desc_free_void);
  1094. hs_cache_v3_dir = NULL;
  1095. digest256map_free(hs_cache_v3_client, cache_client_desc_free_void);
  1096. hs_cache_v3_client = NULL;
  1097. digest256map_free(hs_cache_client_intro_state,
  1098. cache_client_intro_state_free_void);
  1099. hs_cache_client_intro_state = NULL;
  1100. }