static void test_rend_cache_init(void *data) { (void)data; tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting"); tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL " "when starting"); tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when " "starting"); rend_cache_init(); tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing"); tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL " "after initing"); tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL " "after initing"); tt_int_op(strmap_size(rend_cache), OP_EQ, 0); tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); done: rend_cache_free_all(); }
static void test_rend_cache_failure_clean(void *data) { rend_cache_failure_t *failure; rend_cache_failure_intro_t *ip_one, *ip_two; const char key_one[DIGEST_LEN] = "ip1"; const char key_two[DIGEST_LEN] = "ip2"; (void)data; rend_cache_init(); // Test with empty failure cache rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); // Test with one empty failure entry failure = rend_cache_failure_entry_new(); strmap_set_lc(rend_cache_failure, "foo1", failure); rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); // Test with one new intro point failure = rend_cache_failure_entry_new(); ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); digestmap_set(failure->intro_failures, key_one, ip_one); strmap_set_lc(rend_cache_failure, "foo1", failure); rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); // Test with one old intro point rend_cache_failure_purge(); failure = rend_cache_failure_entry_new(); ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); ip_one->created_ts = time(NULL) - 7*60; digestmap_set(failure->intro_failures, key_one, ip_one); strmap_set_lc(rend_cache_failure, "foo1", failure); rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); // Test with one old intro point and one new one rend_cache_failure_purge(); failure = rend_cache_failure_entry_new(); ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); ip_one->created_ts = time(NULL) - 7*60; digestmap_set(failure->intro_failures, key_one, ip_one); ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); ip_two->created_ts = time(NULL) - 2*60; digestmap_set(failure->intro_failures, key_two, ip_two); strmap_set_lc(rend_cache_failure, "foo1", failure); rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1); done: rend_cache_free_all(); }
static uint32_t get_seq_idx(seqenc_t* E, const str_t* seqname) { uint32_t n = strmap_size(E->seq_index); uint32_t idx = strmap_get(E->seq_index, seqname); if (idx >= n) { E->d_ext_pos = realloc_or_die(E->d_ext_pos, (n + 1) * sizeof(cond_dist256_t)); cond_dist256_init(&E->d_ext_pos[n], 9 * 256); } return idx; }
static void test_rend_cache_purge(void *data) { (void)data; // Deals with a NULL rend_cache rend_cache_purge(); tt_assert(rend_cache); tt_assert(strmap_size(rend_cache) == 0); // Deals with existing rend_cache rend_cache_free_all(); rend_cache_init(); tt_assert(rend_cache); tt_assert(strmap_size(rend_cache) == 0); rend_cache_purge(); tt_assert(rend_cache); tt_assert(strmap_size(rend_cache) == 0); done: rend_cache_free_all(); }
static void test_rend_cache_failure_purge(void *data) { (void)data; // Handles a null failure cache strmap_free(rend_cache_failure, rend_cache_failure_entry_free_); rend_cache_failure = NULL; rend_cache_failure_purge(); tt_ptr_op(rend_cache_failure, OP_NE, NULL); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); done: rend_cache_free_all(); }
void seqenc_free(seqenc_t* E) { if (E == NULL) return; str_free(&E->tmpseq); ac_free(E->ac); cond_dist16_free(&E->cs); size_t i; for (i = 0; i < prefix_len; ++i) { cond_dist16_free(&E->cs0[i]); } free(E->d_nmask); uint32_enc_free(&E->d_contig_off); cond_dist4_free(&E->supercontig_motif); uint32_enc_free(&E->d_ext_flags); cond_dist128_free(&E->d_ext_seqname); size_t refsize = strmap_size(E->seq_index); for (i = 0; i < refsize; ++i) { cond_dist256_free(&E->d_ext_pos[i]); } free(E->d_ext_pos); cond_dist16_free(&E->d_ext_cigar_op); uint32_enc_free(&E->d_ext_cigar_n); for (i = 0; i < 9; ++i) { uint32_enc_free(&E->d_ext_cigar_len[i]); } uint32_enc_free(&E->d_ext_tlen); strmap_free(E->seq_index); free(E); }
static void test_rend_cache_clean(void *data) { rend_cache_entry_t *one, *two; rend_service_descriptor_t *desc_one, *desc_two; strmap_iter_t *iter = NULL; const char *key; void *val; (void)data; rend_cache_init(); // Test with empty rendcache rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); tt_int_op(strmap_size(rend_cache), OP_EQ, 0); // Test with two old entries one = tor_malloc_zero(sizeof(rend_cache_entry_t)); two = tor_malloc_zero(sizeof(rend_cache_entry_t)); desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); one->parsed = desc_one; two->parsed = desc_two; desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; desc_one->pk = pk_generate(0); desc_two->pk = pk_generate(1); strmap_set_lc(rend_cache, "foo1", one); strmap_set_lc(rend_cache, "foo2", two); rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); tt_int_op(strmap_size(rend_cache), OP_EQ, 0); // Test with one old entry and one newer entry one = tor_malloc_zero(sizeof(rend_cache_entry_t)); two = tor_malloc_zero(sizeof(rend_cache_entry_t)); desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); one->parsed = desc_one; two->parsed = desc_two; desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; desc_two->timestamp = time(NULL) - 100; desc_one->pk = pk_generate(0); desc_two->pk = pk_generate(1); strmap_set_lc(rend_cache, "foo1", one); strmap_set_lc(rend_cache, "foo2", two); rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); tt_int_op(strmap_size(rend_cache), OP_EQ, 1); iter = strmap_iter_init(rend_cache); strmap_iter_get(iter, &key, &val); tt_str_op(key, OP_EQ, "foo2"); done: rend_cache_free_all(); }
/** Run unit tests for string-to-void* map functions */ static void test_container_strmap(void) { strmap_t *map; strmap_iter_t *iter; const char *k; void *v; char *visited = NULL; smartlist_t *found_keys = NULL; map = strmap_new(); test_assert(map); test_eq(strmap_size(map), 0); test_assert(strmap_isempty(map)); v = strmap_set(map, "K1", (void*)99); test_eq_ptr(v, NULL); test_assert(!strmap_isempty(map)); v = strmap_set(map, "K2", (void*)101); test_eq_ptr(v, NULL); v = strmap_set(map, "K1", (void*)100); test_eq_ptr(v, (void*)99); test_eq_ptr(strmap_get(map,"K1"), (void*)100); test_eq_ptr(strmap_get(map,"K2"), (void*)101); test_eq_ptr(strmap_get(map,"K-not-there"), NULL); strmap_assert_ok(map); v = strmap_remove(map,"K2"); strmap_assert_ok(map); test_eq_ptr(v, (void*)101); test_eq_ptr(strmap_get(map,"K2"), NULL); test_eq_ptr(strmap_remove(map,"K2"), NULL); strmap_set(map, "K2", (void*)101); strmap_set(map, "K3", (void*)102); strmap_set(map, "K4", (void*)103); test_eq(strmap_size(map), 4); strmap_assert_ok(map); strmap_set(map, "K5", (void*)104); strmap_set(map, "K6", (void*)105); strmap_assert_ok(map); /* Test iterator. */ iter = strmap_iter_init(map); found_keys = smartlist_new(); while (!strmap_iter_done(iter)) { strmap_iter_get(iter,&k,&v); smartlist_add(found_keys, tor_strdup(k)); test_eq_ptr(v, strmap_get(map, k)); if (!strcmp(k, "K2")) { iter = strmap_iter_next_rmv(map,iter); } else { iter = strmap_iter_next(map,iter); } } /* Make sure we removed K2, but not the others. */ test_eq_ptr(strmap_get(map, "K2"), NULL); test_eq_ptr(strmap_get(map, "K5"), (void*)104); /* Make sure we visited everyone once */ smartlist_sort_strings(found_keys); visited = smartlist_join_strings(found_keys, ":", 0, NULL); test_streq(visited, "K1:K2:K3:K4:K5:K6"); strmap_assert_ok(map); /* Clean up after ourselves. */ strmap_free(map, NULL); map = NULL; /* Now try some lc functions. */ map = strmap_new(); strmap_set_lc(map,"Ab.C", (void*)1); test_eq_ptr(strmap_get(map,"ab.c"), (void*)1); strmap_assert_ok(map); test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1); test_eq_ptr(strmap_get(map,"AB.C"), NULL); test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1); strmap_assert_ok(map); test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL); done: if (map) strmap_free(map,NULL); if (found_keys) { SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp)); smartlist_free(found_keys); } tor_free(visited); }
/** Parse the content of a client_key file in <b>ckstr</b> and add * rend_authorized_client_t's for each parsed client to * <b>parsed_clients</b>. Return the number of parsed clients as result * or -1 for failure. */ int rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr) { int result = -1; smartlist_t *tokens; directory_token_t *tok; const char *current_entry = NULL; memarea_t *area = NULL; char *err_msg = NULL; if (!ckstr || strlen(ckstr) == 0) return -1; tokens = smartlist_new(); /* Begin parsing with first entry, skipping comments or whitespace at the * beginning. */ area = memarea_new(); current_entry = eat_whitespace(ckstr); while (!strcmpstart(current_entry, "client-name ")) { rend_authorized_client_t *parsed_entry; /* Determine end of string. */ const char *eos = strstr(current_entry, "\nclient-name "); if (!eos) eos = current_entry + strlen(current_entry); else eos = eos + 1; /* Free tokens and clear token list. */ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_clear(tokens); memarea_clear(area); /* Tokenize string. */ if (tokenize_string(area, current_entry, eos, tokens, client_keys_token_table, 0)) { log_warn(LD_REND, "Error tokenizing client keys file."); goto err; } /* Advance to next entry, if available. */ current_entry = eos; /* Check minimum allowed length of token list. */ if (smartlist_len(tokens) < 2) { log_warn(LD_REND, "Impossibly short client key entry."); goto err; } /* Parse client name. */ tok = find_by_keyword(tokens, C_CLIENT_NAME); tor_assert(tok == smartlist_get(tokens, 0)); tor_assert(tok->n_args == 1); if (!rend_valid_client_name(tok->args[0])) { log_warn(LD_CONFIG, "Illegal client name: %s. (Length must be " "between 1 and %d, and valid characters are " "[A-Za-z0-9+-_].)", tok->args[0], REND_CLIENTNAME_MAX_LEN); goto err; } /* Check if client name is duplicate. */ if (strmap_get(parsed_clients, tok->args[0])) { log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains a " "duplicate client name: '%s'. Ignoring.", tok->args[0]); goto err; } parsed_entry = tor_malloc_zero(sizeof(rend_authorized_client_t)); parsed_entry->client_name = tor_strdup(tok->args[0]); strmap_set(parsed_clients, parsed_entry->client_name, parsed_entry); /* Parse client key. */ tok = find_opt_by_keyword(tokens, C_CLIENT_KEY); if (tok) { parsed_entry->client_key = tok->key; tok->key = NULL; /* Prevent free */ } /* Parse descriptor cookie. */ tok = find_by_keyword(tokens, C_DESCRIPTOR_COOKIE); tor_assert(tok->n_args == 1); if (rend_auth_decode_cookie(tok->args[0], parsed_entry->descriptor_cookie, NULL, &err_msg) < 0) { tor_assert(err_msg); log_warn(LD_REND, "%s", err_msg); tor_free(err_msg); goto err; } } result = strmap_size(parsed_clients); goto done; err: result = -1; done: /* Free tokens and clear token list. */ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_free(tokens); if (area) memarea_drop_all(area); return result; }