commit 93b826faaa7cca351c68256ce60a7f7e6c5fda5b Author: David Goulet dgoulet@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@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);
tor-commits@lists.torproject.org