/*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);
+ /* 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 */
++ } 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;
} c_hist_t;
/** Sorting helper: return -1, 1, or 0 based on comparison of two
- * geoip_entry_t. Sort in descending order of total, and then by country
+ * geoip_ipv4_entry_t. Sort in descending order of total, and then by country
* code. */
static int
-_c_hist_compare(const void **_a, const void **_b)
+c_hist_compare_(const void **_a, const void **_b)
{
const c_hist_t *a = *_a, *b = *_b;
if (a->total > b->total)
}
/* Sort entries. Note that we must do this _AFTER_ rounding, or else
* the sort order could leak info. */
- smartlist_sort(entries, _c_hist_compare);
+ smartlist_sort(entries, c_hist_compare_);
- /* Build the result. */
- chunks = smartlist_new();
- SMARTLIST_FOREACH(entries, c_hist_t *, ch, {
- smartlist_add_asprintf(chunks, "%s=%u", ch->country, ch->total);
- });
- result = smartlist_join_strings(chunks, ",", 0, NULL);
- done:
- tor_free(counts);
- if (chunks) {
+ if (country_str) {
+ smartlist_t *chunks = smartlist_new();
+ SMARTLIST_FOREACH(entries, c_hist_t *, ch, {
+ smartlist_add_asprintf(chunks, "%s=%u", ch->country, ch->total);
+ });
+ *country_str = smartlist_join_strings(chunks, ",", 0, NULL);
SMARTLIST_FOREACH(chunks, char *, c, tor_free(c));
smartlist_free(chunks);
}
* \brief Header file for geoip.c.
**/
-#ifndef _TOR_GEOIP_H
-#define _TOR_GEOIP_H
+#ifndef TOR_GEOIP_H
+#define TOR_GEOIP_H
#ifdef GEOIP_PRIVATE
- int geoip_parse_entry(const char *line);
+ int geoip_parse_entry(const char *line, sa_family_t family);
+ int geoip_get_country_by_ipv4(uint32_t ipaddr);
+ int geoip_get_country_by_ipv6(const struct in6_addr *addr);
#endif
int should_record_bridge_info(const or_options_t *options);
- int geoip_load_file(const char *filename, const or_options_t *options);
- int geoip_get_country_by_ip(uint32_t ipaddr);
+ int geoip_load_file(sa_family_t family, const char *filename);
int geoip_get_country_by_addr(const tor_addr_t *addr);
int geoip_get_n_countries(void);
const char *geoip_get_country_name(country_t num);