/** * Write <b>datalen</b> bytes of data at <b>data</b> into the <b>cache</b>, * labeling that data with <b>labels</b>. On failure, return NULL. On * success, return a newly created consensus_cache_entry_t. * * The returned value will be owned by the cache, and you will have a * reference to it. Call consensus_cache_entry_decref() when you are * done with it. * * The provided <b>labels</b> MUST have distinct keys: if they don't, * this API does not specify which values (if any) for the duplicate keys * will be considered. */ consensus_cache_entry_t * consensus_cache_add(consensus_cache_t *cache, const config_line_t *labels, const uint8_t *data, size_t datalen) { char *fname = NULL; int r = storage_dir_save_labeled_to_file(cache->dir, labels, data, datalen, &fname); if (r < 0 || fname == NULL) { return NULL; } consensus_cache_entry_t *ent = tor_malloc_zero(sizeof(consensus_cache_entry_t)); ent->magic = CCE_MAGIC; ent->fname = fname; ent->labels = config_lines_dup(labels); ent->in_cache = cache; ent->unused_since = TIME_MAX; smartlist_add(cache->entries, ent); /* Start the reference count at 2: the caller owns one copy, and the * cache owns another. */ ent->refcnt = 2; return ent; }
static void test_storagedir_save_labeled(void *arg) { (void)arg; char *dirname = tor_strdup(get_fname_rnd("store_dir")); storage_dir_t *d = NULL; uint8_t *inp = tor_malloc_zero(8192); config_line_t *labels = NULL; char *fname = NULL; uint8_t *saved = NULL; d = storage_dir_new(dirname, 10); tt_assert(d); crypto_rand((char *)inp, 8192); config_line_append(&labels, "Foo", "bar baz"); config_line_append(&labels, "quux", "quuzXxz"); const char expected[] = "Foo bar baz\n" "quux quuzXxz\n"; int r = storage_dir_save_labeled_to_file(d, labels, inp, 8192, &fname); tt_int_op(r, OP_EQ, 0); size_t n = 0; saved = storage_dir_read(d, fname, 1, &n); tt_assert(memchr(saved, '\0', n)); tt_str_op((char*)saved, OP_EQ, expected); /* NUL guarantees strcmp works */ tt_mem_op(saved+strlen(expected)+1, OP_EQ, inp, 8192); done: storage_dir_free(d); tor_free(dirname); tor_free(inp); tor_free(fname); config_free_lines(labels); tor_free(saved); }