void sandbox_free_getaddrinfo_cache(void) { cached_getaddrinfo_item_t **next, **item; for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache); item; item = next) { next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item); cached_getaddrinfo_item_free(*item); } HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache); }
/** Clear history of connecting clients used by entry and bridge stats. */ static void client_history_clear(void) { clientmap_entry_t **ent, **next, *this; for (ent = HT_START(clientmap, &client_history); ent != NULL; ent = next) { if ((*ent)->action == GEOIP_CLIENT_CONNECT) { this = *ent; next = HT_NEXT_RMV(clientmap, &client_history, ent); tor_free(this); } else { next = HT_NEXT(clientmap, &client_history, ent); } } }
fp_pair_map_iter_t * fp_pair_map_iter_next_rmv(fp_pair_map_t *map, fp_pair_map_iter_t *iter) { fp_pair_map_entry_t *rmv; tor_assert(map); tor_assert(iter); tor_assert(*iter); rmv = *iter; iter = HT_NEXT_RMV(fp_pair_map_impl, &(map->head), iter); tor_free(rmv); return iter; }
void fp_pair_map_free(fp_pair_map_t *map, void (*free_val)(void*)) { fp_pair_map_entry_t **ent, **next, *this; if (map) { for (ent = HT_START(fp_pair_map_impl, &(map->head)); ent != NULL; ent = next) { this = *ent; next = HT_NEXT_RMV(fp_pair_map_impl, &(map->head), ent); if (free_val) free_val(this->val); tor_free(this); } tor_assert(HT_EMPTY(&(map->head))); HT_CLEAR(fp_pair_map_impl, &(map->head)); tor_free(map); } }
/** Return a newly allocated comma-separated string containing statistics * on network status downloads. The string contains the number of completed * requests, timeouts, and still running requests as well as the download * times by deciles and quartiles. Return NULL if we have not observed * requests for long enough. */ static char * geoip_get_dirreq_history(geoip_client_action_t action, dirreq_type_t type) { char *result = NULL; smartlist_t *dirreq_completed = NULL; uint32_t complete = 0, timeouts = 0, running = 0; int bufsize = 1024, written; dirreq_map_entry_t **ptr, **next, *ent; struct timeval now; tor_gettimeofday(&now); if (action != GEOIP_CLIENT_NETWORKSTATUS && action != GEOIP_CLIENT_NETWORKSTATUS_V2) return NULL; dirreq_completed = smartlist_new(); for (ptr = HT_START(dirreqmap, &dirreq_map); ptr; ptr = next) { ent = *ptr; if (ent->action != action || ent->type != type) { next = HT_NEXT(dirreqmap, &dirreq_map, ptr); continue; } else { if (ent->completed) { smartlist_add(dirreq_completed, ent); complete++; next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr); } else { if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT) timeouts++; else running++; next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr); tor_free(ent); } } } #define DIR_REQ_GRANULARITY 4 complete = round_uint32_to_next_multiple_of(complete, DIR_REQ_GRANULARITY); timeouts = round_uint32_to_next_multiple_of(timeouts, DIR_REQ_GRANULARITY); running = round_uint32_to_next_multiple_of(running, DIR_REQ_GRANULARITY); result = tor_malloc_zero(bufsize); written = tor_snprintf(result, bufsize, "complete=%u,timeout=%u," "running=%u", complete, timeouts, running); if (written < 0) { tor_free(result); goto done; } #define MIN_DIR_REQ_RESPONSES 16 if (complete >= MIN_DIR_REQ_RESPONSES) { uint32_t *dltimes; /* We may have rounded 'completed' up. Here we want to use the * real value. */ complete = smartlist_len(dirreq_completed); dltimes = tor_malloc_zero(sizeof(uint32_t) * complete); SMARTLIST_FOREACH_BEGIN(dirreq_completed, dirreq_map_entry_t *, ent) { uint32_t bytes_per_second; uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time, &ent->completion_time); if (time_diff == 0) time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible * by law of nature or something, but a milisecond * is a bit greater than "instantly" */ bytes_per_second = (uint32_t)(1000 * ent->response_size / time_diff); dltimes[ent_sl_idx] = bytes_per_second; } SMARTLIST_FOREACH_END(ent);