From ed174245c6700bc09af6ece7df2be36b032e163a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 18 Jun 2008 04:34:52 +0000 Subject: [PATCH] implement more fine-tuning options for stats code svn:r15345 --- src/or/config.c | 3 +++ src/or/geoip.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- src/or/or.h | 3 +++ src/or/router.c | 9 +++++++-- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/or/config.c b/src/or/config.c index d4006f0229..7373d1e8b9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -183,6 +183,9 @@ static config_var_t _option_vars[] = { OBSOLETE("DirPostPeriod"), #ifdef ENABLE_GEOIP_STATS V(DirRecordUsageByCountry, BOOL, "0"), + V(DirRecordUsageGranularity, UINT, "4"), + V(DirRecordUsageRetainIPs, INTERVAL, "14 days"), + V(DirRecordUsageSaveInterval, INTERVAL, "6 hours"), #endif VAR("DirServer", LINELIST, DirServers, NULL), V(DNSPort, UINT, "0"), diff --git a/src/or/geoip.c b/src/or/geoip.c index 40ee5c8e18..b795bccee7 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -408,6 +408,14 @@ _c_hist_compare(const void **_a, const void **_b) /*DOCDOC*/ #define GEOIP_MIN_OBSERVATION_TIME (12*60*60) +static INLINE unsigned +round_to_next_multiple_of(unsigned number, unsigned divisor) +{ + number += divisor - 1; + number -= number % divisor; + return number; +} + /** Return a newly allocated comma-separated string containing entries for all * the countries from which we've seen enough clients connect. The entry * format is cc=num where num is the number of IPs we've seen connecting from @@ -428,6 +436,11 @@ geoip_get_client_history(time_t now, geoip_client_action_t action) clientmap_entry_t **ent; unsigned *counts = tor_malloc_zero(sizeof(unsigned)*n_countries); unsigned total = 0; + unsigned granularity = IP_GRANULARITY; +#ifdef ENABLE_GEOIP_STATS + if (get_options()->DirRecordUsageByCountry) + granularity = get_options()->DirRecordUsageGranularity; +#endif HT_FOREACH(ent, clientmap, &client_history) { int country; if (((*ent)->last_seen & ACTION_MASK) != action) @@ -456,9 +469,7 @@ geoip_get_client_history(time_t now, geoip_client_action_t action) #else if (c > 0) { #endif - /* Round up to the next multiple of IP_GRANULARITY */ - c += IP_GRANULARITY-1; - c -= c % IP_GRANULARITY; + c = round_to_next_multiple_of(c, granularity); countrycode = geoip_get_country_name(i); ent = tor_malloc(sizeof(c_hist_t)); strlcpy(ent->country, countrycode, sizeof(ent->country)); @@ -493,12 +504,18 @@ geoip_get_client_history(time_t now, geoip_client_action_t action) return result; } - /**DOCDOC*/ +/**DOCDOC*/ char * geoip_get_request_history(time_t now, geoip_client_action_t action) { - smartlist_t *entries; + smartlist_t *entries, *strings; char *result; + unsigned granularity = IP_GRANULARITY; +#ifdef ENABLE_GEOIP_STATS + if (get_options()->DirRecordUsageByCountry) + granularity = get_options()->DirRecordUsageGranularity; +#endif + if (client_history_starts >= (now - GEOIP_MIN_OBSERVATION_TIME)) return NULL; if (action != GEOIP_CLIENT_NETWORKSTATUS && @@ -506,23 +523,36 @@ geoip_get_request_history(time_t now, geoip_client_action_t action) return NULL; if (!geoip_countries) return NULL; + entries = smartlist_create(); SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, { uint32_t *n = (action == GEOIP_CLIENT_NETWORKSTATUS) ? c->n_v3_ns_requests : c->n_v2_ns_requests; uint32_t tot = 0; int i; - char buf[32]; + c_hist_t *ent; for (i=0; i < REQUEST_HIST_LEN; ++i) tot += n[i]; if (!tot) continue; - tor_snprintf(buf, sizeof(buf), "%s=%ld", c->countrycode, (long)tot); - smartlist_add(entries, tor_strdup(buf)); + ent = tor_malloc_zero(sizeof(c_hist_t)); + strlcpy(ent->country, c->countrycode, sizeof(ent->country)); + ent->total = round_to_next_multiple_of(tot, granularity); + smartlist_add(entries, ent); }); - smartlist_sort_strings(entries); - result = smartlist_join_strings(entries, ",", 0, NULL); - SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp)); + smartlist_sort(entries, _c_hist_compare); + + strings = smartlist_create(); + SMARTLIST_FOREACH(entries, c_hist_t *, ent, { + char buf[32]; + tor_snprintf(buf, sizeof(buf), "%s=%u", ent->country, ent->total); + smartlist_add(strings, tor_strdup(buf)); + }); + result = smartlist_join_strings(strings, ",", 0, NULL); + SMARTLIST_FOREACH(strings, char *, cp, tor_free(cp)); + SMARTLIST_FOREACH(entries, c_hist_t *, ent, tor_free(ent)); + smartlist_free(strings); + smartlist_free(entries); return result; } diff --git a/src/or/or.h b/src/or/or.h index ca3c4cd371..5affef5d97 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2396,6 +2396,9 @@ typedef struct { int BridgeRecordUsageByCountry; #ifdef ENABLE_GEOIP_STATS int DirRecordUsageByCountry; + int DirRecordUsageGranularity; + int DirRecordUsageRetainIPs; + int DirRecordUsageSaveInterval; #endif /** Optionally, a file with GeoIP data. */ diff --git a/src/or/router.c b/src/or/router.c index 399f3138ba..4cd02370af 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1826,8 +1826,13 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, static time_t last_purged_at = 0; char *geoip_summary; time_t now = time(NULL); - if (now > last_purged_at+48*60*60) { - geoip_remove_old_clients(now-48*60*60); + int geoip_purge_interval = 48*60*60; +#ifdef ENABLE_GEOIP_STATS + if (get_options()->DirRecordUsageByCountry) + geoip_purge_interval = get_options()->DirRecordUsageRetainIPs; +#endif + if (now > last_purged_at+geoip_purge_interval) { + geoip_remove_old_clients(now-geoip_purge_interval); last_purged_at = now; } geoip_summary = geoip_get_client_history(time(NULL), GEOIP_CLIENT_CONNECT); -- 2.11.4.GIT