summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-06-18 04:34:52 +0000
committerNick Mathewson <nickm@torproject.org>2008-06-18 04:34:52 +0000
commited174245c6700bc09af6ece7df2be36b032e163a (patch)
tree72ee6e75a5df7265a637e161da36fefdf2c284cc
parent2e5e2f946a62f6e6ba8f788d3571ffd9b56e7e9f (diff)
downloadtor-ed174245c6700bc09af6ece7df2be36b032e163a.tar.gz
tor-ed174245c6700bc09af6ece7df2be36b032e163a.zip
implement more fine-tuning options for stats code
svn:r15345
-rw-r--r--src/or/config.c3
-rw-r--r--src/or/geoip.c52
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/router.c9
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);