[tor-commits] [tor/master] Count IPv6 connections in bridge and entry stats.

nickm at torproject.org nickm at torproject.org
Tue Mar 27 15:22:50 UTC 2012


commit 4aca55efd2ac627a0311cd5cb00d5ad02e765da2
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Thu Feb 9 11:12:30 2012 +0100

    Count IPv6 connections in bridge and entry stats.
---
 changes/bug5053        |    5 +++++
 src/or/connection_or.c |    7 ++-----
 src/or/directory.c     |   25 ++++++++++---------------
 src/or/geoip.c         |   35 ++++++++++++++++++++++++++---------
 src/or/geoip.h         |    3 ++-
 src/test/test.c        |   46 +++++++++++++++++++++++++++++++---------------
 6 files changed, 76 insertions(+), 45 deletions(-)

diff --git a/changes/bug5053 b/changes/bug5053
new file mode 100644
index 0000000..88d82cd
--- /dev/null
+++ b/changes/bug5053
@@ -0,0 +1,5 @@
+  o Minor bugfixes:
+    - Resolve IPv6 addresses in bridge and entry statistics to country code
+      "??" which means we at least count them. Fixes bug 5053; bugfix on
+      0.2.3.9-alpha.
+
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index a815928..30d92b2 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1713,11 +1713,8 @@ connection_or_set_state_open(or_connection_t *conn)
   } else {
     /* only report it to the geoip module if it's not a known router */
     if (!router_get_by_id_digest(conn->identity_digest)) {
-      if (tor_addr_family(&TO_CONN(conn)->addr) == AF_INET) {
-        /*XXXX IP6 support ipv6 geoip.*/
-        uint32_t a = tor_addr_to_ipv4h(&TO_CONN(conn)->addr);
-        geoip_note_client_seen(GEOIP_CLIENT_CONNECT, a, now);
-      }
+      geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &TO_CONN(conn)->addr,
+                             now);
     }
   }
 
diff --git a/src/or/directory.c b/src/or/directory.c
index c6a527c..8d4ac63 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2843,21 +2843,16 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       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;
diff --git a/src/or/geoip.c b/src/or/geoip.c
index 6d33c39..d3dcc4f 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -261,6 +261,22 @@ geoip_get_country_by_ip(uint32_t ipaddr)
   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)
@@ -303,7 +319,7 @@ geoip_db_digest(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
@@ -325,13 +341,14 @@ static HT_HEAD(clientmap, clientmap_entry_t) client_history =
 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,
@@ -417,12 +434,12 @@ geoip_get_mean_shares(time_t now, double *v2_share_out,
   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;
@@ -437,12 +454,12 @@ geoip_note_client_seen(geoip_client_action_t action,
       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);
   }
@@ -453,7 +470,7 @@ geoip_note_client_seen(geoip_client_action_t action,
 
   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)) {
@@ -823,7 +840,7 @@ geoip_get_client_history(geoip_client_action_t action)
     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);
diff --git a/src/or/geoip.h b/src/or/geoip.h
index ce38419..7c2eddc 100644
--- a/src/or/geoip.h
+++ b/src/or/geoip.h
@@ -18,6 +18,7 @@ int geoip_parse_entry(const char *line);
 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_get_country_by_addr(const tor_addr_t *addr);
 int geoip_get_n_countries(void);
 const char *geoip_get_country_name(country_t num);
 int geoip_is_loaded(void);
@@ -25,7 +26,7 @@ const char *geoip_db_digest(void);
 country_t geoip_get_country(const char *countrycode);
 
 void geoip_note_client_seen(geoip_client_action_t action,
-                            uint32_t addr, time_t now);
+                            const tor_addr_t *addr, time_t now);
 void geoip_remove_old_clients(time_t cutoff);
 
 void geoip_note_ns_response(geoip_client_action_t action,
diff --git a/src/test/test.c b/src/test/test.c
index 2ecf6ff..7f196aa 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1452,6 +1452,7 @@ test_geoip(void)
   *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
@@ -1480,16 +1481,23 @@ test_geoip(void)
   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);
@@ -1528,14 +1536,16 @@ test_geoip(void)
 
   /* 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);
@@ -1543,14 +1553,16 @@ test_geoip(void)
   /* 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);
@@ -1577,14 +1589,16 @@ test_geoip(void)
 
   /* 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);
@@ -1592,14 +1606,16 @@ test_geoip(void)
   /* 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);





More information about the tor-commits mailing list