/* Helper function: This handles the DEL_ALL state action using an * <b>obj_type</b> and <b>data</b> needed for the action. */ static void state_query_del_all_(sr_state_object_t obj_type) { if (BUG(!sr_state)) return; switch (obj_type) { case SR_STATE_OBJ_COMMIT: { /* We are in a new protocol run so cleanup commitments. */ DIGESTMAP_FOREACH_MODIFY(sr_state->commits, key, sr_commit_t *, c) { sr_commit_free(c); MAP_DEL_CURRENT(key); } DIGESTMAP_FOREACH_END; break; } /* The following objects are _NOT_ supposed to be removed. */ case SR_STATE_OBJ_CURSRV: case SR_STATE_OBJ_PREVSRV: case SR_STATE_OBJ_PHASE: case SR_STATE_OBJ_COMMITS: case SR_STATE_OBJ_VALID_AFTER: default: tor_assert(0); } }
/** Remove all entries that re REND_CACHE_FAILURE_MAX_AGE old. This is * called every second. * * We have to clean these regurlarly else if for whatever reasons an hidden * service goes offline and a client tries to connect to it during that * time, a failure entry is created and the client will be unable to connect * for a while even though the service has return online. */ void rend_cache_failure_clean(time_t now) { time_t cutoff = now - REND_CACHE_FAILURE_MAX_AGE; STRMAP_FOREACH_MODIFY(rend_cache_failure, key, rend_cache_failure_t *, ent) { /* Free and remove every intro failure object that match the cutoff. */ DIGESTMAP_FOREACH_MODIFY(ent->intro_failures, ip_key, rend_cache_failure_intro_t *, ip_ent) { if (ip_ent->created_ts < cutoff) { rend_cache_failure_intro_entry_free(ip_ent); MAP_DEL_CURRENT(ip_key); } } DIGESTMAP_FOREACH_END; /* If the entry is now empty of intro point failures, remove it. */ if (digestmap_isempty(ent->intro_failures)) { rend_cache_failure_entry_free(ent); MAP_DEL_CURRENT(key); } } STRMAP_FOREACH_END;
/** Helper: free a rend cache failure object. */ static void rend_cache_failure_entry_free(rend_cache_failure_t *entry) { if (entry == NULL) { return; } /* Free and remove every intro failure object. */ DIGESTMAP_FOREACH_MODIFY(entry->intro_failures, key, rend_cache_failure_intro_t *, e) { rend_cache_failure_intro_entry_free(e); MAP_DEL_CURRENT(key); } DIGESTMAP_FOREACH_END; tor_free(entry); }
/** Remove all TRACKEXIT mappings from the addressmap for which the target * host is unknown or no longer allowed, or for which the source address * is no longer in trackexithosts. */ void addressmap_clear_excluded_trackexithosts(const or_options_t *options) { const routerset_t *allow_nodes = options->ExitNodes; const routerset_t *exclude_nodes = options->ExcludeExitNodesUnion_; if (!addressmap) return; if (routerset_is_empty(allow_nodes)) allow_nodes = NULL; if (allow_nodes == NULL && routerset_is_empty(exclude_nodes)) return; STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) { size_t len; const char *target = ent->new_address, *dot; char *nodename; const node_t *node; if (!target) { /* DNS resolving in progress */ continue; } else if (strcmpend(target, ".exit")) { /* Not a .exit mapping */ continue; } else if (ent->source != ADDRMAPSRC_TRACKEXIT) { /* Not a trackexit mapping. */ continue; } len = strlen(target); if (len < 6) continue; /* malformed. */ dot = target + len - 6; /* dot now points to just before .exit */ while (dot > target && *dot != '.') dot--; if (*dot == '.') dot++; nodename = tor_strndup(dot, len-5-(dot-target));; node = node_get_by_nickname(nodename, 0); tor_free(nodename); if (!node || (allow_nodes && !routerset_contains_node(allow_nodes, node)) || routerset_contains_node(exclude_nodes, node) || !hostname_in_track_host_exits(options, address)) { /* We don't know this one, or we want to be rid of it. */ addressmap_ent_remove(address, ent); MAP_DEL_CURRENT(address); } } STRMAP_FOREACH_END;
/** Unregister all TrackHostExits mappings from any address to * *.exitname.exit. */ void clear_trackexithost_mappings(const char *exitname) { char *suffix = NULL; if (!addressmap || !exitname) return; tor_asprintf(&suffix, ".%s.exit", exitname); tor_strlower(suffix); STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) { if (ent->source == ADDRMAPSRC_TRACKEXIT && !strcmpend(ent->new_address, suffix)) { addressmap_ent_remove(address, ent); MAP_DEL_CURRENT(address); } } STRMAP_FOREACH_END; tor_free(suffix); }
/* Clean the v3 cache by removing any entry that has expired using the * <b>global_cutoff</b> value. If <b>global_cutoff</b> is 0, the cleaning * process will use the lifetime found in the plaintext data section. Return * the number of bytes cleaned. */ STATIC size_t cache_clean_v3_as_dir(time_t now, time_t global_cutoff) { size_t bytes_removed = 0; /* Code flow error if this ever happens. */ tor_assert(global_cutoff >= 0); if (!hs_cache_v3_dir) { /* No cache to clean. Just return. */ return 0; } DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_dir, key, hs_cache_dir_descriptor_t *, entry) { size_t entry_size; time_t cutoff = global_cutoff; if (!cutoff) { /* Cutoff is the lifetime of the entry found in the descriptor. */ cutoff = now - entry->plaintext_data->lifetime_sec; } /* If the entry has been created _after_ the cutoff, not expired so * continue to the next entry in our v3 cache. */ if (entry->created_ts > cutoff) { continue; } /* Here, our entry has expired, remove and free. */ MAP_DEL_CURRENT(key); entry_size = cache_get_dir_entry_size(entry); bytes_removed += entry_size; /* Entry is not in the cache anymore, destroy it. */ cache_dir_desc_free(entry); /* Update our cache entry allocation size for the OOM. */ rend_cache_decrement_allocation(entry_size); /* Logging. */ { char key_b64[BASE64_DIGEST256_LEN + 1]; digest256_to_base64(key_b64, (const char *) key); log_info(LD_REND, "Removing v3 descriptor '%s' from HSDir cache", safe_str_client(key_b64)); } } DIGEST256MAP_FOREACH_END;
/** Scan the measured bandwidth cache and remove expired entries */ STATIC void dirserv_expire_measured_bw_cache(time_t now) { if (mbw_cache) { /* Iterate through the cache and check each entry */ DIGESTMAP_FOREACH_MODIFY(mbw_cache, k, mbw_cache_entry_t *, e) { if (now > e->as_of + MAX_MEASUREMENT_AGE) { tor_free(e); MAP_DEL_CURRENT(k); } } DIGESTMAP_FOREACH_END; /* Check if we cleared the whole thing and free if so */ if (digestmap_size(mbw_cache) == 0) { digestmap_free(mbw_cache, tor_free_); mbw_cache = 0; } } }