/** Clear the GeoIP database and reload it from the file * <b>filename</b>. Return 0 on success, -1 on failure. * * Recognized line formats are: * INTIPLOW,INTIPHIGH,CC * and * "INTIPLOW","INTIPHIGH","CC","CC3","COUNTRY NAME" * where INTIPLOW and INTIPHIGH are IPv4 addresses encoded as 4-byte unsigned * integers, and CC is a country code. * * It also recognizes, and skips over, blank lines and lines that start * with '#' (comments). */ int geoip_load_file(const char *filename, const or_options_t *options) { FILE *f; const char *msg = ""; int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO; crypto_digest_t *geoip_digest_env = NULL; clear_geoip_db(); if (!(f = tor_fopen_cloexec(filename, "r"))) { log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s", filename, msg); return -1; } if (!geoip_countries) init_geoip_countries(); if (geoip_entries) { SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, e, tor_free(e)); smartlist_free(geoip_entries); } geoip_entries = smartlist_new(); geoip_digest_env = crypto_digest_new(); log_notice(LD_GENERAL, "Parsing GEOIP file %s.", filename); 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); } /*XXXX abort and return -1 if no entries/illformed?*/ fclose(f); smartlist_sort(geoip_entries, geoip_compare_entries_); /* Okay, now we need to maybe change our mind about what is in which * 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_digest_free(geoip_digest_env); return 0; }
/** Clear the GeoIP database and reload it from the file * <b>filename</b>. Return 0 on success, -1 on failure. * * Recognized line formats are: * INTIPLOW,INTIPHIGH,CC * and * "INTIPLOW","INTIPHIGH","CC","CC3","COUNTRY NAME" * where INTIPLOW and INTIPHIGH are IPv4 addresses encoded as 4-byte unsigned * integers, and CC is a country code. * * It also recognizes, and skips over, blank lines and lines that start * with '#' (comments). */ int 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; clear_geoip_db(); if (!(f = fopen(filename, "r"))) { log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s", filename, msg); return -1; } if (!geoip_countries) { geoip_countries = smartlist_create(); country_idxplus1_by_lc_code = strmap_new(); } if (geoip_entries) { SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, e, tor_free(e)); smartlist_free(geoip_entries); } geoip_entries = smartlist_create(); log_notice(LD_GENERAL, "Parsing GEOIP file."); while (!feof(f)) { char buf[512]; if (fgets(buf, (int)sizeof(buf), f) == NULL) break; /* FFFF track full country name. */ geoip_parse_entry(buf); } /*XXXX abort and return -1 if no entries/illformed?*/ fclose(f); smartlist_sort(geoip_entries, _geoip_compare_entries); /* Okay, now we need to maybe change our mind about what is in which * country. */ refresh_all_country_info(); return 0; }
/** Clear appropriate GeoIP database, based on <b>family</b>, and * reload it from the file <b>filename</b>. Return 0 on success, -1 on * failure. * * Recognized line formats for IPv4 are: * INTIPLOW,INTIPHIGH,CC * and * "INTIPLOW","INTIPHIGH","CC","CC3","COUNTRY NAME" * where INTIPLOW and INTIPHIGH are IPv4 addresses encoded as 4-byte unsigned * integers, and CC is a country code. * * Recognized line format for IPv6 is: * IPV6LOW,IPV6HIGH,CC * where IPV6LOW and IPV6HIGH are IPv6 addresses and CC is a country code. * * It also recognizes, and skips over, blank lines and lines that start * with '#' (comments). */ int geoip_load_file(sa_family_t family, const char *filename) { FILE *f; const char *msg = ""; const or_options_t *options = get_options(); int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO; crypto_digest_t *geoip_digest_env = NULL; tor_assert(family == AF_INET || family == AF_INET6); if (!(f = tor_fopen_cloexec(filename, "r"))) { log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s", filename, msg); return -1; } if (!geoip_countries) init_geoip_countries(); if (family == AF_INET) { if (geoip_ipv4_entries) { SMARTLIST_FOREACH(geoip_ipv4_entries, geoip_ipv4_entry_t *, e, tor_free(e)); smartlist_free(geoip_ipv4_entries); } geoip_ipv4_entries = smartlist_new(); } else { /* AF_INET6 */ if (geoip_ipv6_entries) { SMARTLIST_FOREACH(geoip_ipv6_entries, geoip_ipv6_entry_t *, e, tor_free(e)); smartlist_free(geoip_ipv6_entries); } geoip_ipv6_entries = smartlist_new(); } geoip_digest_env = crypto_digest_new(); log_notice(LD_GENERAL, "Parsing GEOIP %s file %s.", (family == AF_INET) ? "IPv4" : "IPv6", filename); 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, family); } /*XXXX abort and return -1 if no entries/illformed?*/ fclose(f); /* Sort list and remember file digests so that we can include it in * our extra-info descriptors. */ if (family == AF_INET) { smartlist_sort(geoip_ipv4_entries, geoip_ipv4_compare_entries_); /* Okay, now we need to maybe change our mind about what is in * which country. We do this for IPv4 only since that's what we * store in node->country. */ refresh_all_country_info(); crypto_digest_get_digest(geoip_digest_env, geoip_digest, DIGEST_LEN); } else { /* AF_INET6 */ smartlist_sort(geoip_ipv6_entries, geoip_ipv6_compare_entries_); crypto_digest_get_digest(geoip_digest_env, geoip6_digest, DIGEST_LEN); } crypto_digest_free(geoip_digest_env); return 0; }