diff options
author | Roger Dingledine <arma@torproject.org> | 2009-01-28 06:50:36 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2009-01-28 06:50:36 +0000 |
commit | edff6063172ad4fb6a835b2c218856aa93efe8da (patch) | |
tree | 41396b6f0e70c20df8fc1902d3dca20fb07b49c9 | |
parent | 31d60992c6a71a2aee35bf43267f606755bcac6c (diff) | |
download | tor-edff6063172ad4fb6a835b2c218856aa93efe8da.tar.gz tor-edff6063172ad4fb6a835b2c218856aa93efe8da.zip |
patch from matt to implement 'getinfo status/clients-seen'
svn:r18287
-rw-r--r-- | doc/spec/control-spec.txt | 5 | ||||
-rw-r--r-- | src/or/control.c | 23 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/router.c | 35 |
4 files changed, 50 insertions, 14 deletions
diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt index c30c2209cd..883c78f407 100644 --- a/doc/spec/control-spec.txt +++ b/doc/spec/control-spec.txt @@ -581,6 +581,11 @@ $Id$ "status/version/current" Status of the current version. One of: new, old, unrecommended, recommended, new in series, obsolete. + "status/clients-seen" + A summary of which countries we've seen clients from recently, + formatted the same as the CLIENTS_SEEN status event described in + Section 4.1.14. This GETINFO option is currently available only + for bridge relays. Examples: C: GETINFO version desc/name/moria1 diff --git a/src/or/control.c b/src/or/control.c index 9c9fce0992..9f80d38cf6 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1837,6 +1837,25 @@ getinfo_helper_events(control_connection_t *control_conn, log_warn(LD_GENERAL, "%s is deprecated; it no longer gives useful " "information", question); } + } else if (!strcmp(question, "status/clients-seen")) { + char geoip_start[ISO_TIME_LEN+1]; + char *geoip_summary; + smartlist_t *sl; + + geoip_summary = extrainfo_get_client_geoip_summary(time(NULL)); + if (!geoip_summary) + return -1; + format_iso_time(geoip_start, geoip_get_history_start()); + + sl = smartlist_create(); + smartlist_add(sl, (char *)"TimeStarted=\""); + smartlist_add(sl, geoip_start); + smartlist_add(sl, (char *)"\" CountrySummary="); + smartlist_add(sl, geoip_summary); + *answer = smartlist_join_strings(sl, "", 0, 0); + + tor_free(geoip_summary); + smartlist_free(sl); } else { return 0; } @@ -1937,6 +1956,8 @@ static const getinfo_item_t getinfo_items[] = { "circuits."), DOC("status/bootstrap-phase", "The last bootstrap phase status event that Tor sent."), + DOC("status/clients-seen", + "Breakdown of client countries seen by a bridge."), DOC("status/version/recommended", "List of currently recommended versions."), DOC("status/version/current", "Status of the current version."), DOC("status/version/num-versioning", "Number of versioning authorities."), @@ -3931,7 +3952,7 @@ void control_event_clients_seen(const char *timestarted, const char *countries) { send_control_event(EVENT_CLIENTS_SEEN, 0, - "650 CLIENTS_SEEN Timestarted=\"%s\" CountrySummary=%s\r\n", + "650 CLIENTS_SEEN TimeStarted=\"%s\" CountrySummary=%s\r\n", timestarted, countries); } diff --git a/src/or/or.h b/src/or/or.h index 438424d97e..b1561cbc4f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4233,6 +4233,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, crypto_pk_env_t *ident_key); int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, crypto_pk_env_t *ident_key); +char *extrainfo_get_client_geoip_summary(time_t); int is_legal_nickname(const char *s); int is_legal_nickname_or_hexdigest(const char *s); int is_legal_hexdigest(const char *s); diff --git a/src/or/router.c b/src/or/router.c index 3d6cae367e..68e775c806 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1863,19 +1863,7 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, return -1; if (should_record_bridge_info(options)) { - static time_t last_purged_at = 0; - char *geoip_summary; - time_t now = time(NULL); - 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); + char *geoip_summary = extrainfo_get_client_geoip_summary(time(NULL)); if (geoip_summary) { char geoip_start[ISO_TIME_LEN+1]; format_iso_time(geoip_start, geoip_get_history_start()); @@ -1918,6 +1906,27 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, return (int)strlen(s)+1; } +/** Return a newly allocated comma-separated string containing entries for all + * the countries from which we've seen enough clients connect over the + * previous 48 hours. The entry format is cc=num where num is the number of + * IPs we've seen connecting from that country, and cc is a lowercased + * country code. Returns NULL if we don't want to export geoip data yet. */ +char * +extrainfo_get_client_geoip_summary(time_t now) +{ + static time_t last_purged_at = 0; + 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; + } + return geoip_get_client_history(now, GEOIP_CLIENT_CONNECT); +} + /** Return true iff <b>s</b> is a legally valid server nickname. */ int is_legal_nickname(const char *s) |