goto done;
}
- {
- struct in_addr in;
- if (tor_inet_aton((TO_CONN(conn))->address, &in)) {
- geoip_note_client_seen(act, ntohl(in.s_addr), time(NULL));
- geoip_note_ns_response(act, GEOIP_SUCCESS);
- /* Note that a request for a network status has started, so that we
- * can measure the download time later on. */
- if (TO_CONN(conn)->dirreq_id)
- geoip_start_dirreq(TO_CONN(conn)->dirreq_id, dlen, act,
- DIRREQ_TUNNELED);
- else
- geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen, act,
- DIRREQ_DIRECT);
- }
- }
+ geoip_note_client_seen(act, &TO_CONN(conn)->addr, time(NULL));
+ geoip_note_ns_response(act, GEOIP_SUCCESS);
+ /* Note that a request for a network status has started, so that we
+ * can measure the download time later on. */
+ if (TO_CONN(conn)->dirreq_id)
+ geoip_start_dirreq(TO_CONN(conn)->dirreq_id, dlen, act,
+ DIRREQ_TUNNELED);
+ else
+ geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen, act,
+ DIRREQ_DIRECT);
// note_request(request_type,dlen);
(void) request_type;
return ent ? (int)ent->country : 0;
}
+/** 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().
+ */
+int
+geoip_get_country_by_addr(const tor_addr_t *addr)
+{
+ uint32_t ipaddr;
+ if (tor_addr_family(addr) != AF_INET)
+ /*XXXX IP6 support ipv6 geoip.*/
+ return -1;
+ ipaddr = tor_addr_to_ipv4h(addr);
+ return geoip_get_country_by_ip(ipaddr);
+}
+
/** Return the number of countries recognized by the GeoIP database. */
int
geoip_get_n_countries(void)
* countries have them blocked. */
typedef struct clientmap_entry_t {
HT_ENTRY(clientmap_entry_t) node;
- uint32_t ipaddr;
+ tor_addr_t addr;
/** Time when we last saw this IP address, in MINUTES since the epoch.
*
* (This will run out of space around 4011 CE. If Tor is still in use around
static INLINE unsigned
clientmap_entry_hash(const clientmap_entry_t *a)
{
- return ht_improve_hash((unsigned) a->ipaddr);
+ return ht_improve_hash(tor_addr_hash(&a->addr));
}
/** Hashtable helper: compare two clientmap_entry_t values for equality. */
static INLINE int
clientmap_entries_eq(const clientmap_entry_t *a, const clientmap_entry_t *b)
{
- return a->ipaddr == b->ipaddr && a->action == b->action;
+ return !tor_addr_compare(&a->addr, &b->addr, CMP_EXACT) &&
+ a->action == b->action;
}
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
return 0;
}
-/** Note that we've seen a client connect from the IP <b>addr</b> (host order)
+/** Note that we've seen a client connect from the IP <b>addr</b>
* at time <b>now</b>. Ignored by all but bridges and directories if
* configured accordingly. */
void
geoip_note_client_seen(geoip_client_action_t action,
- uint32_t addr, time_t now)
+ const tor_addr_t *addr, time_t now)
{
const or_options_t *options = get_options();
clientmap_entry_t lookup, *ent;
return;
}
- lookup.ipaddr = addr;
+ tor_addr_copy(&lookup.addr, addr);
lookup.action = (int)action;
ent = HT_FIND(clientmap, &client_history, &lookup);
if (! ent) {
ent = tor_malloc_zero(sizeof(clientmap_entry_t));
- ent->ipaddr = addr;
+ tor_addr_copy(&ent->addr, addr);
ent->action = (int)action;
HT_INSERT(clientmap, &client_history, ent);
}
if (action == GEOIP_CLIENT_NETWORKSTATUS ||
action == GEOIP_CLIENT_NETWORKSTATUS_V2) {
- int country_idx = geoip_get_country_by_ip(addr);
+ int country_idx = geoip_get_country_by_addr(addr);
if (country_idx < 0)
country_idx = 0; /** unresolved requests are stored at index 0. */
if (country_idx >= 0 && country_idx < smartlist_len(geoip_countries)) {
int country;
if ((*ent)->action != (int)action)
continue;
- country = geoip_get_country_by_ip((*ent)->ipaddr);
+ country = geoip_get_country_by_addr(&(*ent)->addr);
if (country < 0)
country = 0; /** unresolved requests are stored at index 0. */
tor_assert(0 <= country && country < n_countries);
*entry_stats_2 =
"entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"entry-ips \n";
+ tor_addr_t addr;
/* Populate the DB a bit. Add these in order, since we can't do the final
* 'sort' step. These aren't very good IP addresses, but they're perfectly
get_options_mutable()->BridgeRelay = 1;
get_options_mutable()->BridgeRecordUsageByCountry = 1;
/* Put 9 observations in AB... */
- for (i=32; i < 40; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-7200);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 225, now-7200);
+ for (i=32; i < 40; ++i) {
+ tor_addr_from_ipv4h(&addr, (uint32_t) i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-7200);
+ }
+ tor_addr_from_ipv4h(&addr, (uint32_t) 225);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-7200);
/* and 3 observations in XY, several times. */
for (j=0; j < 10; ++j)
- for (i=52; i < 55; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-3600);
+ for (i=52; i < 55; ++i) {
+ tor_addr_from_ipv4h(&addr, (uint32_t) i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-3600);
+ }
/* and 17 observations in ZZ... */
- for (i=110; i < 127; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now);
+ for (i=110; i < 127; ++i) {
+ tor_addr_from_ipv4h(&addr, (uint32_t) i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now);
+ }
s = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
test_assert(s);
test_streq("zz=24,ab=16,xy=8", s);
/* Start testing dirreq statistics by making sure that we don't collect
* dirreq stats without initializing them. */
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now);
s = geoip_format_dirreq_stats(now + 86400);
test_assert(!s);
/* Initialize stats, note one connecting client, and generate the
* dirreq-stats history string. */
geoip_dirreq_stats_init(now);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now);
s = geoip_format_dirreq_stats(now + 86400);
test_streq(dirreq_stats_1, s);
tor_free(s);
/* Stop collecting stats, add another connecting client, and ensure we
* don't generate a history string. */
geoip_dirreq_stats_term();
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, 101, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 101);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now);
s = geoip_format_dirreq_stats(now + 86400);
test_assert(!s);
/* Re-start stats, add a connecting client, reset stats, and make sure
* that we get an all empty history string. */
geoip_dirreq_stats_init(now);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now);
geoip_reset_dirreq_stats(now);
s = geoip_format_dirreq_stats(now + 86400);
test_streq(dirreq_stats_2, s);
/* Start testing entry statistics by making sure that we don't collect
* anything without initializing entry stats. */
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now);
s = geoip_format_entry_stats(now + 86400);
test_assert(!s);
/* Initialize stats, note one connecting client, and generate the
* entry-stats history string. */
geoip_entry_stats_init(now);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now);
s = geoip_format_entry_stats(now + 86400);
test_streq(entry_stats_1, s);
tor_free(s);
/* Stop collecting stats, add another connecting client, and ensure we
* don't generate a history string. */
geoip_entry_stats_term();
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 101, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 101);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now);
s = geoip_format_entry_stats(now + 86400);
test_assert(!s);
/* Re-start stats, add a connecting client, reset stats, and make sure
* that we get an all empty history string. */
geoip_entry_stats_init(now);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 100, now);
+ tor_addr_from_ipv4h(&addr, (uint32_t) 100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now);
geoip_reset_entry_stats(now);
s = geoip_format_entry_stats(now + 86400);
test_streq(entry_stats_2, s);