[tor-commits] [tor/release-0.3.1] geoip: Add a lookup function for client map entry

nickm at torproject.org nickm at torproject.org
Fri Feb 16 14:56:21 UTC 2018


commit 93b826faaa7cca351c68256ce60a7f7e6c5fda5b
Author: David Goulet <dgoulet at torproject.org>
Date:   Thu Jan 25 15:44:48 2018 -0500

    geoip: Add a lookup function for client map entry
    
    The upcoming DoS mitigation subsytem needs to keep information on a per-IP
    basis which is also what the geoip clientmap does.
    
    For another subsystem to access that clientmap, this commit adds a lookup
    function that returns the entry. For this, the clientmap_entry_t had to be
    moved to the header file.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/geoip.c | 46 +++++++++++++++++++++-------------------------
 src/or/geoip.h | 22 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/src/or/geoip.c b/src/or/geoip.c
index 00c055bbe..e2a1b1cee 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -472,24 +472,6 @@ geoip_db_digest(sa_family_t family)
     return hex_str(geoip6_digest, DIGEST_LEN);
 }
 
-/** Entry in a map from IP address to the last time we've seen an incoming
- * connection from that IP address. Used by bridges only, to track which
- * countries have them blocked. */
-typedef struct clientmap_entry_t {
-  HT_ENTRY(clientmap_entry_t) node;
-  tor_addr_t addr;
- /* Name of pluggable transport used by this client. NULL if no
-    pluggable transport was used. */
-  char *transport_name;
-
-  /** 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
-   * 4000 CE, please remember to add more bits to last_seen_in_minutes.) */
-  unsigned int last_seen_in_minutes:30;
-  unsigned int action:2;
-} clientmap_entry_t;
-
 /** Largest allowable value for last_seen_in_minutes.  (It's a 30-bit field,
  * so it can hold up to (1u<<30)-1, or 0x3fffffffu.
  */
@@ -564,8 +546,7 @@ geoip_note_client_seen(geoip_client_action_t action,
                        time_t now)
 {
   const or_options_t *options = get_options();
-  clientmap_entry_t lookup, *ent;
-  memset(&lookup, 0, sizeof(clientmap_entry_t));
+  clientmap_entry_t *ent;
 
   if (action == GEOIP_CLIENT_CONNECT) {
     /* Only remember statistics as entry guard or as bridge. */
@@ -583,11 +564,7 @@ geoip_note_client_seen(geoip_client_action_t action,
             safe_str_client(fmt_addr((addr))),
             transport_name ? transport_name : "<no transport>");
 
-  tor_addr_copy(&lookup.addr, addr);
-  lookup.action = (int)action;
-  lookup.transport_name = (char*) transport_name;
-  ent = HT_FIND(clientmap, &client_history, &lookup);
-
+  ent = geoip_lookup_client(addr, transport_name, action);
   if (! ent) {
     ent = tor_malloc_zero(sizeof(clientmap_entry_t));
     tor_addr_copy(&ent->addr, addr);
@@ -635,6 +612,25 @@ geoip_remove_old_clients(time_t cutoff)
                           &cutoff);
 }
 
+/* Return a client entry object matching the given address, transport name and
+ * geoip action from the clientmap. NULL if not found. The transport_name can
+ * be NULL. */
+clientmap_entry_t *
+geoip_lookup_client(const tor_addr_t *addr, const char *transport_name,
+                    geoip_client_action_t action)
+{
+  clientmap_entry_t lookup;
+
+  tor_assert(addr);
+
+  /* We always look for a client connection with no transport. */
+  tor_addr_copy(&lookup.addr, addr);
+  lookup.action = action;
+  lookup.transport_name = (char *) transport_name;
+
+  return HT_FIND(clientmap, &client_history, &lookup);
+}
+
 /** How many responses are we giving to clients requesting v3 network
  * statuses? */
 static uint32_t ns_v3_responses[GEOIP_NS_RESPONSE_NUM];
diff --git a/src/or/geoip.h b/src/or/geoip.h
index 070296dd0..b80efceb3 100644
--- a/src/or/geoip.h
+++ b/src/or/geoip.h
@@ -20,6 +20,25 @@ STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr);
 STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr);
 STATIC void clear_geoip_db(void);
 #endif
+
+/** Entry in a map from IP address to the last time we've seen an incoming
+ * connection from that IP address. Used by bridges only to track which
+ * countries have them blocked, or the DoS mitigation subsystem if enabled. */
+typedef struct clientmap_entry_t {
+  HT_ENTRY(clientmap_entry_t) node;
+  tor_addr_t addr;
+  /* Name of pluggable transport used by this client. NULL if no
+     pluggable transport was used. */
+  char *transport_name;
+
+  /** 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
+   * 4000 CE, please remember to add more bits to last_seen_in_minutes.) */
+  unsigned int last_seen_in_minutes:30;
+  unsigned int action:2;
+} clientmap_entry_t;
+
 int should_record_bridge_info(const or_options_t *options);
 int geoip_load_file(sa_family_t family, const char *filename);
 MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
@@ -33,6 +52,9 @@ void geoip_note_client_seen(geoip_client_action_t action,
                             const tor_addr_t *addr, const char *transport_name,
                             time_t now);
 void geoip_remove_old_clients(time_t cutoff);
+clientmap_entry_t *geoip_lookup_client(const tor_addr_t *addr,
+                                       const char *transport_name,
+                                       geoip_client_action_t action);
 
 void geoip_note_ns_response(geoip_ns_response_t response);
 char *geoip_get_transport_history(void);





More information about the tor-commits mailing list