STATIC int replaycache_add_and_test_internal( time_t present, replaycache_t *r, const void *data, size_t len, time_t *elapsed) { int rv = 0; uint8_t digest[DIGEST256_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_digest256((char *)digest, (const char *)data, len, DIGEST_SHA256); /* check map */ access_time = digest256map_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; digest256map_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; }
/* Store a given descriptor in our cache. */ static void store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc) { tor_assert(desc); digest256map_set(hs_cache_v3_dir, desc->key, desc); }