Loading changes/nowhereland 0 → 100644 +6 −0 Original line number Diff line number Diff line o Minor features: - Add support for the country code "{??}" in torrc options like ExcludeNodes, to indicate all routers of unknown country. Fixes bug 1094. src/or/geoip.c +31 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "routerlist.h" static void clear_geoip_db(void); static void init_geoip_countries(void); /** An entry from the GeoIP file: maps an IP range to a country. */ typedef struct geoip_entry_t { Loading Loading @@ -106,11 +107,11 @@ geoip_parse_entry(const char *line) { unsigned int low, high; char b[3]; if (!geoip_countries) { geoip_countries = smartlist_create(); if (!geoip_countries) init_geoip_countries(); if (!geoip_entries) geoip_entries = smartlist_create(); country_idxplus1_by_lc_code = strmap_new(); } while (TOR_ISSPACE(*line)) ++line; if (*line == '#') Loading Loading @@ -165,6 +166,24 @@ should_record_bridge_info(or_options_t *options) return options->BridgeRelay && options->BridgeRecordUsageByCountry; } /** Set up a new list of geoip countries with no countries (yet) set in it, * except for the unknown country. */ static void init_geoip_countries(void) { geoip_country_t *geoip_unresolved; geoip_countries = smartlist_create(); /* Add a geoip_country_t for requests that could not be resolved to a * country as first element (index 0) to geoip_countries. */ geoip_unresolved = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(geoip_unresolved->countrycode, "??", sizeof(geoip_unresolved->countrycode)); smartlist_add(geoip_countries, geoip_unresolved); country_idxplus1_by_lc_code = strmap_new(); strmap_set_lc(country_idxplus1_by_lc_code, "??", (void*)(1)); } /** Clear the GeoIP database and reload it from the file * <b>filename</b>. Return 0 on success, -1 on failure. * Loading @@ -190,17 +209,8 @@ geoip_load_file(const char *filename, or_options_t *options) filename, msg); return -1; } if (!geoip_countries) { geoip_country_t *geoip_unresolved; geoip_countries = smartlist_create(); /* Add a geoip_country_t for requests that could not be resolved to a * country as first element (index 0) to geoip_countries. */ geoip_unresolved = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(geoip_unresolved->countrycode, "??", sizeof(geoip_unresolved->countrycode)); smartlist_add(geoip_countries, geoip_unresolved); country_idxplus1_by_lc_code = strmap_new(); } if (!geoip_countries) init_geoip_countries(); if (geoip_entries) { SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, e, tor_free(e)); smartlist_free(geoip_entries); Loading @@ -227,9 +237,10 @@ geoip_load_file(const char *filename, or_options_t *options) } /** Given an IP address in host order, return a number representing the * country to which that address belongs, or -1 for unknown. The return value * will always be less than geoip_get_n_countries(). To decode it, * call geoip_get_country_name(). * country to which that address belongs, -1 for "No geoip information * available", or 0 for the 'unknown country'. The return value will always * be less than geoip_get_n_countries(). To decode it, call * geoip_get_country_name(). */ int geoip_get_country_by_ip(uint32_t ipaddr) Loading @@ -238,7 +249,7 @@ geoip_get_country_by_ip(uint32_t ipaddr) if (!geoip_entries) return -1; ent = smartlist_bsearch(geoip_entries, &ipaddr, _geoip_compare_key_to_entry); return ent ? (int)ent->country : -1; return ent ? (int)ent->country : 0; } /** Return the number of countries recognized by the GeoIP database. */ Loading Loading @@ -417,7 +428,7 @@ geoip_note_client_seen(geoip_client_action_t action, if (options->BridgeRelay) { while (current_request_period_starts + REQUEST_HIST_PERIOD < now) { if (!geoip_countries) geoip_countries = smartlist_create(); init_geoip_countries(); if (!current_request_period_starts) { current_request_period_starts = now; break; Loading src/test/test.c +4 −2 Original line number Diff line number Diff line Loading @@ -1108,10 +1108,12 @@ test_geoip(void) test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"")); test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"")); /* We should have 3 countries: ab, xy, zz. */ test_eq(3, geoip_get_n_countries()); /* We should have 4 countries: ??, ab, xy, zz. */ test_eq(4, geoip_get_n_countries()); /* Make sure that country ID actually works. */ #define NAMEFOR(x) geoip_get_country_name(geoip_get_country_by_ip(x)) test_streq("??", NAMEFOR(3)); test_eq(0, geoip_get_country_by_ip(3)); test_streq("ab", NAMEFOR(32)); test_streq("??", NAMEFOR(5)); test_streq("??", NAMEFOR(51)); Loading Loading
changes/nowhereland 0 → 100644 +6 −0 Original line number Diff line number Diff line o Minor features: - Add support for the country code "{??}" in torrc options like ExcludeNodes, to indicate all routers of unknown country. Fixes bug 1094.
src/or/geoip.c +31 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "routerlist.h" static void clear_geoip_db(void); static void init_geoip_countries(void); /** An entry from the GeoIP file: maps an IP range to a country. */ typedef struct geoip_entry_t { Loading Loading @@ -106,11 +107,11 @@ geoip_parse_entry(const char *line) { unsigned int low, high; char b[3]; if (!geoip_countries) { geoip_countries = smartlist_create(); if (!geoip_countries) init_geoip_countries(); if (!geoip_entries) geoip_entries = smartlist_create(); country_idxplus1_by_lc_code = strmap_new(); } while (TOR_ISSPACE(*line)) ++line; if (*line == '#') Loading Loading @@ -165,6 +166,24 @@ should_record_bridge_info(or_options_t *options) return options->BridgeRelay && options->BridgeRecordUsageByCountry; } /** Set up a new list of geoip countries with no countries (yet) set in it, * except for the unknown country. */ static void init_geoip_countries(void) { geoip_country_t *geoip_unresolved; geoip_countries = smartlist_create(); /* Add a geoip_country_t for requests that could not be resolved to a * country as first element (index 0) to geoip_countries. */ geoip_unresolved = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(geoip_unresolved->countrycode, "??", sizeof(geoip_unresolved->countrycode)); smartlist_add(geoip_countries, geoip_unresolved); country_idxplus1_by_lc_code = strmap_new(); strmap_set_lc(country_idxplus1_by_lc_code, "??", (void*)(1)); } /** Clear the GeoIP database and reload it from the file * <b>filename</b>. Return 0 on success, -1 on failure. * Loading @@ -190,17 +209,8 @@ geoip_load_file(const char *filename, or_options_t *options) filename, msg); return -1; } if (!geoip_countries) { geoip_country_t *geoip_unresolved; geoip_countries = smartlist_create(); /* Add a geoip_country_t for requests that could not be resolved to a * country as first element (index 0) to geoip_countries. */ geoip_unresolved = tor_malloc_zero(sizeof(geoip_country_t)); strlcpy(geoip_unresolved->countrycode, "??", sizeof(geoip_unresolved->countrycode)); smartlist_add(geoip_countries, geoip_unresolved); country_idxplus1_by_lc_code = strmap_new(); } if (!geoip_countries) init_geoip_countries(); if (geoip_entries) { SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, e, tor_free(e)); smartlist_free(geoip_entries); Loading @@ -227,9 +237,10 @@ geoip_load_file(const char *filename, or_options_t *options) } /** Given an IP address in host order, return a number representing the * country to which that address belongs, or -1 for unknown. The return value * will always be less than geoip_get_n_countries(). To decode it, * call geoip_get_country_name(). * country to which that address belongs, -1 for "No geoip information * available", or 0 for the 'unknown country'. The return value will always * be less than geoip_get_n_countries(). To decode it, call * geoip_get_country_name(). */ int geoip_get_country_by_ip(uint32_t ipaddr) Loading @@ -238,7 +249,7 @@ geoip_get_country_by_ip(uint32_t ipaddr) if (!geoip_entries) return -1; ent = smartlist_bsearch(geoip_entries, &ipaddr, _geoip_compare_key_to_entry); return ent ? (int)ent->country : -1; return ent ? (int)ent->country : 0; } /** Return the number of countries recognized by the GeoIP database. */ Loading Loading @@ -417,7 +428,7 @@ geoip_note_client_seen(geoip_client_action_t action, if (options->BridgeRelay) { while (current_request_period_starts + REQUEST_HIST_PERIOD < now) { if (!geoip_countries) geoip_countries = smartlist_create(); init_geoip_countries(); if (!current_request_period_starts) { current_request_period_starts = now; break; Loading
src/test/test.c +4 −2 Original line number Diff line number Diff line Loading @@ -1108,10 +1108,12 @@ test_geoip(void) test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"")); test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"")); /* We should have 3 countries: ab, xy, zz. */ test_eq(3, geoip_get_n_countries()); /* We should have 4 countries: ??, ab, xy, zz. */ test_eq(4, geoip_get_n_countries()); /* Make sure that country ID actually works. */ #define NAMEFOR(x) geoip_get_country_name(geoip_get_country_by_ip(x)) test_streq("??", NAMEFOR(3)); test_eq(0, geoip_get_country_by_ip(3)); test_streq("ab", NAMEFOR(32)); test_streq("??", NAMEFOR(5)); test_streq("??", NAMEFOR(51)); Loading