tor  0.4.0.0-alpha-dev
Data Structures | Macros | Typedefs | Functions | Variables
geoip.c File Reference
#include "lib/geoip/geoip.h"
#include "lib/container/map.h"
#include "lib/container/order.h"
#include "lib/container/smartlist.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/ctime/di_ops.h"
#include "lib/encoding/binascii.h"
#include "lib/fs/files.h"
#include "lib/log/escape.h"
#include "lib/malloc/malloc.h"
#include "lib/net/address.h"
#include "lib/net/inaddr.h"
#include "lib/string/compat_ctype.h"
#include "lib/string/compat_string.h"
#include "lib/string/scanf.h"
#include "lib/string/util_string.h"
#include <stdio.h>
#include <string.h>

Go to the source code of this file.

Data Structures

struct  geoip_ipv4_entry_t
 
struct  geoip_ipv6_entry_t
 

Typedefs

typedef struct geoip_ipv4_entry_t geoip_ipv4_entry_t
 
typedef struct geoip_ipv6_entry_t geoip_ipv6_entry_t
 

Functions

static void init_geoip_countries (void)
 
const smartlist_tgeoip_get_countries (void)
 
 MOCK_IMPL (country_t, geoip_get_country,(const char *country))
 
static void geoip_add_entry (const tor_addr_t *low, const tor_addr_t *high, const char *country)
 
STATIC int geoip_parse_entry (const char *line, sa_family_t family)
 
static int geoip_ipv4_compare_entries_ (const void **_a, const void **_b)
 
static int geoip_ipv4_compare_key_to_entry_ (const void *_key, const void **_member)
 
static int geoip_ipv6_compare_entries_ (const void **_a, const void **_b)
 
static int geoip_ipv6_compare_key_to_entry_ (const void *_key, const void **_member)
 
int geoip_load_file (sa_family_t family, const char *filename, int severity)
 
int geoip_get_country_by_ipv4 (uint32_t ipaddr)
 
int geoip_get_country_by_ipv6 (const struct in6_addr *addr)
 
 MOCK_IMPL (int, geoip_get_country_by_addr,(const tor_addr_t *addr))
 
 MOCK_IMPL (int, geoip_get_n_countries,(void))
 
const char * geoip_get_country_name (country_t num)
 
 MOCK_IMPL (int, geoip_is_loaded,(sa_family_t family))
 
const char * geoip_db_digest (sa_family_t family)
 
STATIC void clear_geoip_db (void)
 
void geoip_free_all (void)
 

Variables

static smartlist_tgeoip_countries = NULL
 
static strmap_t * country_idxplus1_by_lc_code = NULL
 
static smartlist_tgeoip_ipv4_entries = NULL
 
static smartlist_tgeoip_ipv6_entries = NULL
 
static char geoip_digest [DIGEST_LEN]
 
static char geoip6_digest [DIGEST_LEN]
 

Detailed Description

Functions related to maintaining an IP-to-country database; to summarizing client connections by country to entry guards, bridges, and directory servers; and for statistics on answering network status requests.

There are two main kinds of functions in this module: geoip functions, which map groups of IPv4 and IPv6 addresses to country codes, and statistical functions, which collect statistics about different kinds of per-country usage.

The geoip lookup tables are implemented as sorted lists of disjoint address ranges, each mapping to a singleton geoip_country_t. These country objects are also indexed by their names in a hashtable.

The tables are populated from disk at startup by the geoip_load_file() function. For more information on the file format they read, see that function. See the scripts and the README file in src/config for more information about how those files are generated.

Tor uses GeoIP information in order to implement user requests (such as ExcludeNodes {cc}), and to keep track of how much usage relays are getting for each country.

Definition in file geoip.c.

Typedef Documentation

◆ geoip_ipv4_entry_t

An entry from the GeoIP IPv4 file: maps an IPv4 range to a country.

◆ geoip_ipv6_entry_t

An entry from the GeoIP IPv6 file: maps an IPv6 range to a country.

Function Documentation

◆ clear_geoip_db()

STATIC void clear_geoip_db ( void  )

Release all storage held by the GeoIP databases and country list.

Definition at line 478 of file geoip.c.

References geoip_countries, SMARTLIST_FOREACH, and tor_free.

Referenced by geoip_free_all().

◆ geoip_add_entry()

static void geoip_add_entry ( const tor_addr_t low,
const tor_addr_t high,
const char *  country 
)
static

Add an entry to a GeoIP table, mapping all IP addresses between low and high, inclusive, to the 2-letter country code country.

Definition at line 111 of file geoip.c.

References IF_BUG_ONCE, tor_addr_compare(), and tor_addr_family().

◆ geoip_db_digest()

const char* geoip_db_digest ( sa_family_t  family)

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().

Definition at line 467 of file geoip.c.

References DIGEST_LEN, geoip_digest, hex_str(), and tor_assert().

◆ geoip_free_all()

void geoip_free_all ( void  )

Release all storage held in this file.

Definition at line 504 of file geoip.c.

References clear_geoip_db(), and geoip_digest.

◆ geoip_get_countries()

const smartlist_t* geoip_get_countries ( void  )

Return a list of geoip_country_t for all known countries.

Definition at line 83 of file geoip.c.

References geoip_countries, and init_geoip_countries().

Referenced by geoip_get_request_history().

◆ geoip_get_country_by_ipv4()

int geoip_get_country_by_ipv4 ( uint32_t  ipaddr)

Given an IP address in host order, return a number representing the 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().

Definition at line 385 of file geoip.c.

References geoip_ipv4_entry_t::country, geoip_ipv4_compare_key_to_entry_(), geoip_ipv4_entries, and smartlist_bsearch().

Referenced by MOCK_IMPL().

◆ geoip_get_country_by_ipv6()

int geoip_get_country_by_ipv6 ( const struct in6_addr addr)

Given an IPv6 address, return a number representing the 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().

Definition at line 401 of file geoip.c.

Referenced by MOCK_IMPL().

◆ geoip_get_country_name()

const char* geoip_get_country_name ( country_t  num)

Return the two-letter country code associated with the number num, or "??" for an unknown value.

Definition at line 441 of file geoip.c.

References geoip_countries.

◆ geoip_ipv4_compare_entries_()

static int geoip_ipv4_compare_entries_ ( const void **  _a,
const void **  _b 
)
static

Sorting helper: return -1, 1, or 0 based on comparison of two geoip_ipv4_entry_t

Definition at line 226 of file geoip.c.

References geoip_ipv4_entry_t::ip_low.

◆ geoip_ipv4_compare_key_to_entry_()

static int geoip_ipv4_compare_key_to_entry_ ( const void *  _key,
const void **  _member 
)
static

bsearch helper: return -1, 1, or 0 based on comparison of an IP (a pointer to a uint32_t in host order) to a geoip_ipv4_entry_t

Definition at line 240 of file geoip.c.

References geoip_ipv4_entry_t::ip_high.

Referenced by geoip_get_country_by_ipv4().

◆ geoip_ipv6_compare_entries_()

static int geoip_ipv6_compare_entries_ ( const void **  _a,
const void **  _b 
)
static

Sorting helper: return -1, 1, or 0 based on comparison of two geoip_ipv6_entry_t

Definition at line 256 of file geoip.c.

References fast_memcmp, and geoip_ipv6_entry_t::ip_low.

◆ geoip_ipv6_compare_key_to_entry_()

static int geoip_ipv6_compare_key_to_entry_ ( const void *  _key,
const void **  _member 
)
static

bsearch helper: return -1, 1, or 0 based on comparison of an IPv6 (a pointer to a in6_addr) to a geoip_ipv6_entry_t

Definition at line 266 of file geoip.c.

References fast_memcmp, geoip_ipv6_entry_t::ip_high, and geoip_ipv6_entry_t::ip_low.

◆ geoip_load_file()

int geoip_load_file ( sa_family_t  family,
const char *  filename,
int  severity 
)

Clear appropriate GeoIP database, based on family, and reload it from the file filename. 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).

Definition at line 318 of file geoip.c.

References geoip_countries, geoip_ipv4_entries, init_geoip_countries(), LD_GENERAL, log_fn, SMARTLIST_FOREACH, tor_assert(), tor_fopen_cloexec(), and tor_free.

◆ geoip_parse_entry()

STATIC int geoip_parse_entry ( const char *  line,
sa_family_t  family 
)

Add an entry to the GeoIP table indicated by family, parsing it from line. The format is as for geoip_load_file().

Definition at line 157 of file geoip.c.

References geoip_countries, geoip_ipv4_entries, and init_geoip_countries().

◆ init_geoip_countries()

static void init_geoip_countries ( void  )
static

Set up a new list of geoip countries with no countries (yet) set in it, except for the unknown country.

Definition at line 285 of file geoip.c.

References geoip_countries.

Referenced by geoip_get_countries(), geoip_load_file(), geoip_parse_entry(), and MOCK_IMPL().

◆ MOCK_IMPL() [1/4]

MOCK_IMPL ( country_t  ,
geoip_get_country  ,
(const char *country)   
)

Return the index of the country's entry in the GeoIP country list if it is a valid 2-letter country code, otherwise return -1.

Definition at line 94 of file geoip.c.

References country_idxplus1_by_lc_code, and strmap_get_lc().

◆ MOCK_IMPL() [2/4]

MOCK_IMPL ( int  ,
geoip_get_country_by_addr  ,
(const tor_addr_t *addr)   
)

Given an IP address, return a number representing the 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().

Definition at line 417 of file geoip.c.

References geoip_get_country_by_ipv4(), geoip_get_country_by_ipv6(), tor_addr_family(), tor_addr_to_in6(), and tor_addr_to_ipv4h().

◆ MOCK_IMPL() [3/4]

MOCK_IMPL ( int  ,
geoip_get_n_countries  ,
(void)   
)

Return the number of countries recognized by the GeoIP country list.

Definition at line 430 of file geoip.c.

References geoip_countries, and init_geoip_countries().

◆ MOCK_IMPL() [4/4]

MOCK_IMPL ( int  ,
geoip_is_loaded  ,
(sa_family_t family)   
)

Return true iff we have loaded a GeoIP database.

Definition at line 451 of file geoip.c.

References geoip_countries, geoip_ipv4_entries, and tor_assert().

Variable Documentation

◆ country_idxplus1_by_lc_code

strmap_t* country_idxplus1_by_lc_code = NULL
static

A map from lowercased country codes to their position in geoip_countries. The index is encoded in the pointer, and 1 is added so that NULL can mean not found.

Definition at line 72 of file geoip.c.

Referenced by MOCK_IMPL().

◆ geoip_countries

smartlist_t* geoip_countries = NULL
static

◆ geoip_digest

char geoip_digest[DIGEST_LEN]
static

SHA1 digest of the GeoIP files to include in extra-info descriptors.

Definition at line 78 of file geoip.c.

Referenced by geoip_db_digest(), and geoip_free_all().

◆ geoip_ipv4_entries

smartlist_t* geoip_ipv4_entries = NULL
static

Lists of all known geoip_ipv4_entry_t and geoip_ipv6_entry_t, sorted by their respective ip_low.

Definition at line 75 of file geoip.c.

Referenced by geoip_get_country_by_ipv4(), geoip_load_file(), geoip_parse_entry(), and MOCK_IMPL().