diff options
author | Karsten Loesing <karsten.loesing@gmx.net> | 2009-07-05 20:48:16 +0200 |
---|---|---|
committer | Karsten Loesing <karsten.loesing@gmx.net> | 2009-07-05 20:48:16 +0200 |
commit | c0b6cb132baaf9cf259bfb09e14c1128d7abc9d6 (patch) | |
tree | c3fdbed1a09dcc86fbcef74d16bc665e7ee05def | |
parent | 4d6af73db88e409764f43fc6cdaa432d667becf3 (diff) | |
download | tor-c0b6cb132baaf9cf259bfb09e14c1128d7abc9d6.tar.gz tor-c0b6cb132baaf9cf259bfb09e14c1128d7abc9d6.zip |
If configured, write entry-node statistics to disk periodically.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.in | 7 | ||||
-rw-r--r-- | src/or/config.c | 20 | ||||
-rw-r--r-- | src/or/geoip.c | 42 | ||||
-rw-r--r-- | src/or/or.h | 9 | ||||
-rw-r--r-- | src/or/router.c | 3 |
6 files changed, 84 insertions, 1 deletions
@@ -21,6 +21,10 @@ Changes in version 0.2.2.1-alpha - 2009-??-?? transferred bytes per port to disk every 24 hours. To enable this, run configure with the --enable-exit-stats option, and set "ExitPortStatistics 1" in your torrc. + - Entry nodes can write statistics on the rough number and origins of + connecting clients to disk every 24 hours. To enable this, run + configure with the --enable-entry-stats option, and set + "EntryStatistics 1" in your torrc. o Minor bugfixes - Hidden service clients didn't use a cached service descriptor that diff --git a/configure.in b/configure.in index 844211588d..0f83207991 100644 --- a/configure.in +++ b/configure.in @@ -99,6 +99,13 @@ if test "$enable_geoip_stats" = "yes"; then AC_DEFINE(ENABLE_GEOIP_STATS, 1, [Defined if we try to collect per-country statistics]) fi +AC_ARG_ENABLE(entry-stats, + AS_HELP_STRING(--enable-entry-stats, enable code for entry guards to collect per-country statistics)) + +if test "$enable_entry_stats" = "yes"; then + AC_DEFINE(ENABLE_ENTRY_STATS, 1, [Defined if we try to collect per-country statistics]) +fi + AC_ARG_ENABLE(gcc-warnings, AS_HELP_STRING(--enable-gcc-warnings, enable verbose warnings)) diff --git a/src/or/config.c b/src/or/config.c index f1fea13e58..c9ef21bb8c 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -198,6 +198,7 @@ static config_var_t _option_vars[] = { V(DownloadExtraInfo, BOOL, "0"), V(EnforceDistinctSubnets, BOOL, "1"), V(EntryNodes, ROUTERSET, NULL), + V(EntryStatistics, BOOL, "0"), V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"), V(ExcludeNodes, ROUTERSET, NULL), V(ExcludeExitNodes, ROUTERSET, NULL), @@ -1395,6 +1396,25 @@ options_act(or_options_t *old_options) log_warn(LD_CONFIG, "ExitPortStatistics enabled, but Tor was built " "without port statistics support."); #endif +#ifdef ENABLE_ENTRY_STATS + if (options->EntryStatistics) { + if (should_record_bridge_info(options)) { + /* Don't allow measuring statistics on entry guards when configured + * as bridge. */ + log_warn(LD_CONFIG, "Bridges cannot be configured to measure " + "additional GeoIP statistics as entry guards."); + return -1; + } else + log_notice(LD_CONFIG, "Configured to measure entry node " + "statistics. Look for the entry-stats file that will " + "first be written to the data directory in 24 hours " + "from now."); + } +#else + if (options->EntryStatistics) + log_warn(LD_CONFIG, "EntryStatistics enabled, but Tor was built " + "without entry node statistics support."); +#endif /* Check if we need to parse and add the EntryNodes config option. */ if (options->EntryNodes && (!old_options || diff --git a/src/or/geoip.c b/src/or/geoip.c index 41c8f21cdb..13a6a28500 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -13,6 +13,7 @@ static void clear_geoip_db(void); static void dump_geoip_stats(void); +static void dump_entry_stats(void); /** An entry from the GeoIP file: maps an IP range to a country. */ typedef struct geoip_entry_t { @@ -308,8 +309,13 @@ geoip_note_client_seen(geoip_client_action_t action, or_options_t *options = get_options(); clientmap_entry_t lookup, *ent; if (action == GEOIP_CLIENT_CONNECT) { +#ifdef ENABLE_ENTRY_STATS + if (!options->EntryStatistics) + return; +#else if (!(options->BridgeRelay && options->BridgeRecordUsageByCountry)) return; +#endif /* Did we recently switch from bridge to relay or back? */ if (client_history_starts > now) return; @@ -337,6 +343,8 @@ geoip_note_client_seen(geoip_client_action_t action, geoip_remove_old_clients(current_request_period_starts); /* Before rotating, write the current stats to disk. */ dump_geoip_stats(); + if (get_options()->EntryStatistics) + dump_entry_stats(); /* Now rotate request period */ SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, { memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1], @@ -657,6 +665,40 @@ dump_geoip_stats(void) #endif } +/** Store all our geoip statistics as entry guards into + * $DATADIR/entry-stats. */ +static void +dump_entry_stats(void) +{ +#ifdef ENABLE_ENTRY_STATS + time_t now = time(NULL); + char *filename = get_datadir_fname("entry-stats"); + char *data = NULL; + char since[ISO_TIME_LEN+1], written[ISO_TIME_LEN+1]; + open_file_t *open_file = NULL; + FILE *out; + + data = geoip_get_client_history(now, GEOIP_CLIENT_CONNECT); + format_iso_time(since, geoip_get_history_start()); + format_iso_time(written, now); + out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND, + 0600, &open_file); + if (!out) + goto done; + if (fprintf(out, "written %s\nstarted-at %s\nips %s\n", + written, since, data ? data : "") < 0) + goto done; + + finish_writing_to_file(open_file); + open_file = NULL; + done: + if (open_file) + abort_writing_to_file(open_file); + tor_free(filename); + tor_free(data); +#endif +} + /** Helper used to implement GETINFO ip-to-country/... controller command. */ int getinfo_helper_geoip(control_connection_t *control_conn, diff --git a/src/or/or.h b/src/or/or.h index 935ea523df..65eac0e9e9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2478,6 +2478,9 @@ typedef struct { /** If true, the user wants us to collect statistics on port usage. */ int ExitPortStatistics; + /** If true, the user wants us to collect statistics as entry node. */ + int EntryStatistics; + /** If true, do not believe anybody who tells us that a domain resolves * to an internal address, or that an internal address has a PTR mapping. * Helps avoid some cross-site attacks. */ @@ -3595,6 +3598,10 @@ int dnsserv_launch_request(const char *name, int is_reverse); * we are willing to talk about it? */ #define DIR_RECORD_USAGE_MIN_OBSERVATION_TIME (24*60*60) +/** Time interval: Flush geoip data to disk this often when measuring on an + * entry guard. */ +#define ENTRY_RECORD_USAGE_RETAIN_IPS (24*60*60) + #ifdef GEOIP_PRIVATE int geoip_parse_entry(const char *line); #endif @@ -3610,7 +3617,7 @@ country_t geoip_get_country(const char *countrycode); * the others, we're not. */ typedef enum { - /** We've noticed a connection as a bridge relay. */ + /** We've noticed a connection as a bridge relay or entry guard. */ GEOIP_CLIENT_CONNECT = 0, /** We've served a networkstatus consensus as a directory server. */ GEOIP_CLIENT_NETWORKSTATUS = 1, diff --git a/src/or/router.c b/src/or/router.c index cb73e378c0..bdea4fa764 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1919,6 +1919,9 @@ extrainfo_get_client_geoip_summary(time_t now) #ifdef ENABLE_GEOIP_STATS geoip_purge_interval = DIR_RECORD_USAGE_RETAIN_IPS; #endif +#ifdef ENABLE_ENTRY_STATS + geoip_purge_interval = ENTRY_RECORD_USAGE_RETAIN_IPS; +#endif if (now > last_purged_at+geoip_purge_interval) { /* (Note that this also discards items in the client history with * action GEOIP_CLIENT_NETWORKSTATUS{_V2}, which doesn't matter |