hs_cache.c 40 KB

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