static void test_rend_cache_failure_intro_add(void *data) { (void)data; rend_cache_failure_t *fail_entry; rend_cache_failure_intro_t *entry; const char identity[DIGEST_LEN] = "foo1"; rend_cache_init(); // Adds non-existing entry cache_failure_intro_add((const uint8_t *) identity, "foo2", INTRO_POINT_FAILURE_TIMEOUT); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); entry = digestmap_get(fail_entry->intro_failures, identity); tt_assert(entry); // Adds existing entry cache_failure_intro_add((const uint8_t *) identity, "foo2", INTRO_POINT_FAILURE_TIMEOUT); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); entry = digestmap_get(fail_entry->intro_failures, identity); tt_assert(entry); done: rend_cache_free_all(); }
static void test_rend_cache_intro_failure_note(void *data) { (void)data; rend_cache_failure_t *fail_entry; rend_cache_failure_intro_t *entry; const char key[DIGEST_LEN] = "foo1"; rend_cache_init(); // Test not found rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT, (const uint8_t *) key, "foo2"); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); entry = digestmap_get(fail_entry->intro_failures, key); tt_assert(entry); tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); // Test found rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE, (const uint8_t *) key, "foo2"); tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE); done: rend_cache_free_all(); }
int replaycache_add_and_test_internal( time_t present, replaycache_t *r, const void *data, int len, time_t *elapsed) { int rv = 0; char digest[DIGEST_LEN]; time_t *access_time; /* sanity check */ if (present <= 0 || !r || !data || len <= 0) { log_info(LD_BUG, "replaycache_add_and_test_internal() called with stupid" " parameters; please fix this."); goto done; } /* compute digest */ crypto_digest(digest, (const char *)data, len); /* check map */ access_time = digestmap_get(r->digests_seen, digest); /* seen before? */ if (access_time != NULL) { /* * If it's far enough in the past, no hit. If the horizon is zero, we * never expire. */ if (*access_time >= present - r->horizon || r->horizon == 0) { /* replay cache hit, return 1 */ rv = 1; /* If we want to output an elapsed time, do so */ if (elapsed) { if (present >= *access_time) { *elapsed = present - *access_time; } else { /* We shouldn't really be seeing hits from the future, but... */ *elapsed = 0; } } } /* * If it's ahead of the cached time, update */ if (*access_time < present) { *access_time = present; } } else { /* No, so no hit and update the digest map with the current time */ access_time = tor_malloc(sizeof(*access_time)); *access_time = present; digestmap_set(r->digests_seen, digest, access_time); } /* now scrub the cache if it's time */ replaycache_scrub_if_needed_internal(present, r); done: return rv; }
/** If conn is listed in orconn_identity_map, remove it, and clear * conn->identity_digest. Otherwise do nothing. */ void connection_or_remove_from_identity_map(or_connection_t *conn) { or_connection_t *tmp; tor_assert(conn); if (!orconn_identity_map) return; tmp = digestmap_get(orconn_identity_map, conn->identity_digest); if (!tmp) { if (!tor_digest_is_zero(conn->identity_digest)) { log_warn(LD_BUG, "Didn't find connection '%s' on identity map when " "trying to remove it.", conn->nickname ? conn->nickname : "NULL"); } return; } if (conn == tmp) { if (conn->next_with_same_id) digestmap_set(orconn_identity_map, conn->identity_digest, conn->next_with_same_id); else digestmap_remove(orconn_identity_map, conn->identity_digest); } else { while (tmp->next_with_same_id) { if (tmp->next_with_same_id == conn) { tmp->next_with_same_id = conn->next_with_same_id; break; } tmp = tmp->next_with_same_id; } } memset(conn->identity_digest, 0, DIGEST_LEN); conn->next_with_same_id = NULL; }
/** Store a measured bandwidth cache entry when reading the measured * bandwidths file. */ STATIC void dirserv_cache_measured_bw(const measured_bw_line_t *parsed_line, time_t as_of) { mbw_cache_entry_t *e = NULL; tor_assert(parsed_line); /* Allocate a cache if we need */ if (!mbw_cache) mbw_cache = digestmap_new(); /* Check if we have an existing entry */ e = digestmap_get(mbw_cache, parsed_line->node_id); /* If we do, we can re-use it */ if (e) { /* Check that we really are newer, and update */ if (as_of > e->as_of) { e->mbw_kb = parsed_line->bw_kb; e->as_of = as_of; } } else { /* We'll have to insert a new entry */ e = tor_malloc(sizeof(*e)); e->mbw_kb = parsed_line->bw_kb; e->as_of = as_of; digestmap_set(mbw_cache, parsed_line->node_id, e); } }
/** Query the cache by identity digest, return value indicates whether * we found it. The bw_out and as_of_out pointers receive the cached * bandwidth value and the time it was cached if not NULL. */ int dirserv_query_measured_bw_cache_kb(const char *node_id, long *bw_kb_out, time_t *as_of_out) { mbw_cache_entry_t *v = NULL; int rv = 0; if (mbw_cache && node_id) { v = digestmap_get(mbw_cache, node_id); if (v) { /* Found something */ rv = 1; if (bw_kb_out) *bw_kb_out = v->mbw_kb; if (as_of_out) *as_of_out = v->as_of; } } return rv; }
/** Helper for dirserv_compute_performance_thresholds(): Decide whether to * include a router in our calculations, and return true iff we should; the * require_mbw parameter is passed in by * dirserv_compute_performance_thresholds() and controls whether we ever * count routers with only advertised bandwidths */ static int router_counts_toward_thresholds(const node_t *node, time_t now, const digestmap_t *omit_as_sybil, int require_mbw) { /* Have measured bw? */ int have_mbw = dirserv_has_measured_bw(node->identity); uint64_t min_bw_kb = ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER_KB; const or_options_t *options = get_options(); if (options->TestingTorNetwork) { min_bw_kb = (int64_t)options->TestingMinExitFlagThreshold / 1000; } return node->ri && router_is_active(node->ri, node, now) && !digestmap_get(omit_as_sybil, node->identity) && (dirserv_get_credible_bandwidth_kb(node->ri) >= min_bw_kb) && (have_mbw || !require_mbw); }
/* Helper function: return a commit using the RSA fingerprint of the * authority or NULL if no such commit is known. */ static sr_commit_t * state_query_get_commit(const char *rsa_fpr) { tor_assert(rsa_fpr); return digestmap_get(sr_state->commits, rsa_fpr); }