/** Decode the microdescriptors from the string starting at <b>s</b> and * ending at <b>eos</b>, and store them in <b>cache</b>. If <b>no_save</b>, * mark them as non-writable to disk. If <b>where</b> is SAVED_IN_CACHE, * leave their bodies as pointers to the mmap'd cache. If where is * <b>SAVED_NOWHERE</b>, do not allow annotations. If listed_at is not -1, * set the last_listed field of every microdesc to listed_at. If * requested_digests is non-null, then it contains a list of digests we mean * to allow, so we should reject any non-requested microdesc with a different * digest, and alter the list to contain only the digests of those microdescs * we didn't find. * Return a newly allocated list of the added microdescriptors, or NULL */ smartlist_t * microdescs_add_to_cache(microdesc_cache_t *cache, const char *s, const char *eos, saved_location_t where, int no_save, time_t listed_at, smartlist_t *requested_digests256) { smartlist_t *descriptors, *added; const int allow_annotations = (where != SAVED_NOWHERE); descriptors = microdescs_parse_from_string(s, eos, allow_annotations, where); if (listed_at != (time_t)-1) { SMARTLIST_FOREACH(descriptors, microdesc_t *, md, md->last_listed = listed_at); }
/** Decode the microdescriptors from the string starting at <b>s</b> and * ending at <b>eos</b>, and store them in <b>cache</b>. If <b>no_save</b>, * mark them as non-writable to disk. If <b>where</b> is SAVED_IN_CACHE, * leave their bodies as pointers to the mmap'd cache. If where is * <b>SAVED_NOWHERE</b>, do not allow annotations. If listed_at is not -1, * set the last_listed field of every microdesc to listed_at. If * requested_digests is non-null, then it contains a list of digests we mean * to allow, so we should reject any non-requested microdesc with a different * digest, and alter the list to contain only the digests of those microdescs * we didn't find. * Return a newly allocated list of the added microdescriptors, or NULL */ smartlist_t * microdescs_add_to_cache(microdesc_cache_t *cache, const char *s, const char *eos, saved_location_t where, int no_save, time_t listed_at, smartlist_t *requested_digests256) { void * const DIGEST_REQUESTED = (void*)1; void * const DIGEST_RECEIVED = (void*)2; void * const DIGEST_INVALID = (void*)3; smartlist_t *descriptors, *added; const int allow_annotations = (where != SAVED_NOWHERE); smartlist_t *invalid_digests = smartlist_new(); descriptors = microdescs_parse_from_string(s, eos, allow_annotations, where, invalid_digests); if (listed_at != (time_t)-1) { SMARTLIST_FOREACH(descriptors, microdesc_t *, md, md->last_listed = listed_at); }
/** More tests for parsing different kinds of microdescriptors, and getting * invalid digests trackd from them. */ static void test_md_parse(void *arg) { (void) arg; char *mem_op_hex_tmp = NULL; smartlist_t *invalid = smartlist_new(); smartlist_t *mds = microdescs_parse_from_string(MD_PARSE_TEST_DATA, NULL, 1, SAVED_NOWHERE, invalid); tt_int_op(smartlist_len(mds), OP_EQ, 11); tt_int_op(smartlist_len(invalid), OP_EQ, 4); test_memeq_hex(smartlist_get(invalid,0), "5d76bf1c6614e885614a1e0ad074e1ab" "4ea14655ebeefb1736a71b5ed8a15a51"); test_memeq_hex(smartlist_get(invalid,1), "2fde0ee3343669c2444cd9d53cbd39c6" "a7d1fc0513513e840ca7f6e68864b36c"); test_memeq_hex(smartlist_get(invalid,2), "20d1576c5ab11bbcff0dedb1db4a3cfc" "c8bc8dd839d8cbfef92d00a1a7d7b294"); test_memeq_hex(smartlist_get(invalid,3), "074770f394c73dbde7b44412e9692add" "691a478d4727f9804b77646c95420a96"); /* Spot-check the valid ones. */ const microdesc_t *md = smartlist_get(mds, 5); test_memeq_hex(md->digest, "54bb6d733ddeb375d2456c79ae103961" "da0cae29620375ac4cf13d54da4d92b3"); tt_int_op(md->last_listed, OP_EQ, 0); tt_int_op(md->saved_location, OP_EQ, SAVED_NOWHERE); tt_int_op(md->no_save, OP_EQ, 0); tt_uint_op(md->held_in_map, OP_EQ, 0); tt_uint_op(md->held_by_nodes, OP_EQ, 0); tt_assert(md->onion_curve25519_pkey); md = smartlist_get(mds, 6); test_memeq_hex(md->digest, "53f740bd222ab37f19f604b1d3759aa6" "5eff1fbce9ac254bd0fa50d4af9b1bae"); tt_assert(! md->exit_policy); md = smartlist_get(mds, 8); test_memeq_hex(md->digest, "a0a155562d8093d8fd0feb7b93b7226e" "17f056c2142aab7a4ea8c5867a0376d5"); tt_assert(md->onion_curve25519_pkey); md = smartlist_get(mds, 10); test_memeq_hex(md->digest, "409ebd87d23925a2732bd467a92813c9" "21ca378fcb9ca193d354c51550b6d5e9"); tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6); tt_int_op(md->ipv6_orport, OP_EQ, 9090); done: SMARTLIST_FOREACH(mds, microdesc_t *, mdsc, microdesc_free(mdsc)); smartlist_free(mds); SMARTLIST_FOREACH(invalid, char *, cp, tor_free(cp)); smartlist_free(invalid); tor_free(mem_op_hex_tmp); }