diff --git a/doc/TODO b/doc/TODO index da351c8f18..cb5b522de5 100644 --- a/doc/TODO +++ b/doc/TODO @@ -31,18 +31,18 @@ R . spec . geoip caching and publishing for bridges R . spec - Implement - . Code to load a geoip file from disk + o Code to load a geoip file from disk o Truncated format - - Full format. + o Full format. o Actually invoke o Code to store a GEOIP file in memory. o Code to remember client IPs. - . Code to generate history lines - - Make history lines match spec. + o Code to generate history lines - Controller interface - Track consecutive time up, not time since last-forgotten IP. - Add log lines. - Tests + - Mention in dir-spec.txt d let Vidalia use the geoip data too rather than doing its own anonymized queries o bridge address disbursal strategies diff --git a/src/or/geoip.c b/src/or/geoip.c index eeeb453f2f..c9fb91cdfb 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -81,9 +81,14 @@ geoip_load_file(const char *filename) geoip_entries = smartlist_create(); country_idxplus1_by_lc_code = strmap_new(); while (!feof(f)) { + char buf[512]; unsigned int low, high; char b[3]; - if (fscanf(f, "%u,%u,%2s", &low, &high, b) == 3) { + if (fgets(buf, sizeof(buf), f) == NULL) + break; + if (sscanf(buf,"%u,%u,%2s", &low, &high, b) == 3) { + geoip_add_entry(low, high, b); + } else if (sscanf(buf,"\"%u\",\"%u\",\"%2s\",", &low, &high, b) == 3) { geoip_add_entry(low, high, b); } } @@ -200,6 +205,12 @@ geoip_remove_old_clients(time_t cutoff) #define MIN_IPS_TO_NOTE_ANYTHING 16 #define IP_GRANULARITY 8 +time_t +geoip_get_history_start(void) +{ + return client_history_starts; +} + char * geoip_get_client_history(time_t now) { diff --git a/src/or/or.h b/src/or/or.h index da9a6f3ac4..758e9faf0c 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3208,6 +3208,7 @@ const char *geoip_get_country_name(int num); int geoip_is_loaded(void); void geoip_note_client_seen(uint32_t addr, time_t now); void geoip_remove_old_clients(time_t cutoff); +time_t geoip_get_history_start(void); char *geoip_get_client_history(time_t now); void geoip_free_all(void); diff --git a/src/or/router.c b/src/or/router.c index 37f34439f5..30b307dc40 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1694,6 +1694,7 @@ int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, crypto_pk_env_t *ident_key) { + or_options_t *options = get_options(); char identity[HEX_DIGEST_LEN+1]; char published[ISO_TIME_LEN+1]; char digest[DIGEST_LEN]; @@ -1708,14 +1709,32 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, result = tor_snprintf(s, maxlen, "extra-info %s %s\n" - "published %s\n%s" - "router-signature\n", + "published %s\n%s", extrainfo->nickname, identity, published, bandwidth_usage); tor_free(bandwidth_usage); if (result<0) return -1; + + if (options->BridgeRelay && options->BridgeRecordUsageByCountry) { + char *geoip_summary = geoip_get_client_history(time(NULL)); + if (geoip_summary) { + char geoip_start[ISO_TIME_LEN+1]; + format_iso_time(geoip_start, geoip_get_history_start()); + result = tor_snprintf(s+strlen(s), maxlen-strlen(s), + "geoip-start-time %s\n" + "geoip-client-origins %s\n", + geoip_start, geoip_summary); + tor_free(geoip_summary); + if (result<0) + return -1; + } + } + + len = strlen(s); + strlcat(s+len, "router-signature\n", maxlen-len); + len += strlen(s+len); if (router_get_extrainfo_hash(s, digest)<0) return -1; if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)