From 423c2a7a2770d7a08927accecb7e8c36d36a474c Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Tue, 9 Nov 2010 09:13:45 +0100 Subject: [PATCH 1/2] Add GeoIP file digest to extra-info descriptor. --- changes/enhancement1883 | 4 ++++ doc/spec/dir-spec.txt | 6 ++++++ src/or/geoip.c | 18 ++++++++++++++++++ src/or/geoip.h | 1 + src/or/router.c | 11 +++++++++++ 5 files changed, 40 insertions(+) create mode 100644 changes/enhancement1883 diff --git a/changes/enhancement1883 b/changes/enhancement1883 new file mode 100644 index 0000000000..fe6bc1ab79 --- /dev/null +++ b/changes/enhancement1883 @@ -0,0 +1,4 @@ + o Minor features: + - Add GeoIP file digest to extra-info descriptor. Implements + enhancement 1883. + diff --git a/doc/spec/dir-spec.txt b/doc/spec/dir-spec.txt index 4a7a557b31..04e73c4676 100644 --- a/doc/spec/dir-spec.txt +++ b/doc/spec/dir-spec.txt @@ -622,6 +622,12 @@ As documented in 2.1 above. See migration notes in section 2.2.1. + "geoip-db-digest" Digest NL + [At most once.] + + SHA1 digest of the GeoIP database file that is used to resolve IP + addresses to country codes. + ("geoip-start" YYYY-MM-DD HH:MM:SS NL) ("geoip-client-origins" CC=N,CC=N,... NL) diff --git a/src/or/geoip.c b/src/or/geoip.c index ee8d72ee1d..b2a47aa68f 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -44,6 +44,9 @@ static strmap_t *country_idxplus1_by_lc_code = NULL; /** A list of all known geoip_entry_t, sorted by ip_low. */ static smartlist_t *geoip_entries = NULL; +/** SHA1 digest of the GeoIP file to include in extra-info descriptors. */ +static char geoip_digest[DIGEST_LEN]; + /** Return the index of the country's entry in the GeoIP DB * if it is a valid 2-letter country code, otherwise return -1. */ @@ -201,6 +204,7 @@ geoip_load_file(const char *filename, or_options_t *options) FILE *f; const char *msg = ""; int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO; + crypto_digest_env_t *geoip_digest_env = NULL; clear_geoip_db(); if (!(f = fopen(filename, "r"))) { log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s", @@ -214,11 +218,13 @@ geoip_load_file(const char *filename, or_options_t *options) smartlist_free(geoip_entries); } geoip_entries = smartlist_create(); + geoip_digest_env = crypto_new_digest_env(); log_notice(LD_GENERAL, "Parsing GEOIP file."); while (!feof(f)) { char buf[512]; if (fgets(buf, (int)sizeof(buf), f) == NULL) break; + crypto_digest_add_bytes(geoip_digest_env, buf, strlen(buf)); /* FFFF track full country name. */ geoip_parse_entry(buf); } @@ -231,6 +237,11 @@ geoip_load_file(const char *filename, or_options_t *options) * country. */ refresh_all_country_info(); + /* Remember file digest so that we can include it in our extra-info + * descriptors. */ + crypto_digest_get_digest(geoip_digest_env, geoip_digest, DIGEST_LEN); + crypto_free_digest_env(geoip_digest_env); + return 0; } @@ -278,6 +289,13 @@ geoip_is_loaded(void) return geoip_countries != NULL && geoip_entries != NULL; } +/** Return the hex-encoded SHA1 digest of the loaded GeoIP file. */ +const char * +geoip_db_digest(void) +{ + return hex_str(geoip_digest, DIGEST_LEN); +} + /** Entry in a map from IP address to the last time we've seen an incoming * connection from that IP address. Used by bridges only, to track which * countries have them blocked. */ diff --git a/src/or/geoip.h b/src/or/geoip.h index 68e01deecc..ac38c00da5 100644 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@ -21,6 +21,7 @@ int geoip_get_country_by_ip(uint32_t ipaddr); int geoip_get_n_countries(void); const char *geoip_get_country_name(country_t num); int geoip_is_loaded(void); +const char *geoip_db_digest(void); country_t geoip_get_country(const char *countrycode); void geoip_note_client_seen(geoip_client_action_t action, diff --git a/src/or/router.c b/src/or/router.c index a188d50f94..85300a3186 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -2015,6 +2015,17 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, if (options->ExtraInfoStatistics && write_stats_to_extrainfo) { char *contents = NULL; log_info(LD_GENERAL, "Adding stats to extra-info descriptor."); + if (geoip_is_loaded()) { + size_t pos = strlen(s); + if (tor_snprintf(s + pos, maxlen - strlen(s), + "geoip-db-digest %s\n", + geoip_db_digest()) < 0) { + log_warn(LD_DIR, "Could not write geoip-db-digest to extra-info " + "descriptor."); + s[pos] = '\0'; + write_stats_to_extrainfo = 0; + } + } if (options->DirReqStatistics && load_stats_file("stats"PATH_SEPARATOR"dirreq-stats", "dirreq-stats-end", now, &contents) > 0) { From 8833381d9c6ae274599b16fc11cec7527b12c465 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Fri, 12 Nov 2010 09:06:27 +0100 Subject: [PATCH 2/2] Add two fixes to the new geoip-db-digest line. --- src/or/geoip.c | 4 +++- src/or/router.c | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/or/geoip.c b/src/or/geoip.c index b2a47aa68f..ae0776a571 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -289,7 +289,9 @@ geoip_is_loaded(void) return geoip_countries != NULL && geoip_entries != NULL; } -/** Return the hex-encoded SHA1 digest of the loaded GeoIP file. */ +/** Return the hex-encoded SHA1 digest of the loaded GeoIP file. The + * result does not need to be deallocated, but will be overwritten by the + * next call of hex_str(). */ const char * geoip_db_digest(void) { diff --git a/src/or/router.c b/src/or/router.c index 85300a3186..4d3c66f4d5 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -2012,20 +2012,19 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, if (result<0) return -1; + if (geoip_is_loaded()) { + if (tor_snprintf(s + strlen(s), maxlen - strlen(s), + "geoip-db-digest %s\n", + geoip_db_digest()) < 0) { + log_warn(LD_DIR, "Could not write geoip-db-digest to extra-info " + "descriptor."); + return -1; + } + } + if (options->ExtraInfoStatistics && write_stats_to_extrainfo) { char *contents = NULL; log_info(LD_GENERAL, "Adding stats to extra-info descriptor."); - if (geoip_is_loaded()) { - size_t pos = strlen(s); - if (tor_snprintf(s + pos, maxlen - strlen(s), - "geoip-db-digest %s\n", - geoip_db_digest()) < 0) { - log_warn(LD_DIR, "Could not write geoip-db-digest to extra-info " - "descriptor."); - s[pos] = '\0'; - write_stats_to_extrainfo = 0; - } - } if (options->DirReqStatistics && load_stats_file("stats"PATH_SEPARATOR"dirreq-stats", "dirreq-stats-end", now, &contents) > 0) {