summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKarsten Loesing <karsten.loesing@gmx.net>2009-05-26 21:32:56 +0200
committerKarsten Loesing <karsten.loesing@gmx.net>2009-05-26 21:32:56 +0200
commitbf7e5d6553acd8d8ce37e80586083620d66d0160 (patch)
treeffdeee753871b2f71316afd7aa14b86d73353077 /src
parentb805e5debf039fb7e48b8d846859f9f24d5c753a (diff)
downloadtor-bf7e5d6553acd8d8ce37e80586083620d66d0160.tar.gz
tor-bf7e5d6553acd8d8ce37e80586083620d66d0160.zip
Some cleanups on geoip.c.
Use two bitfields for last_seen and action in clientmap_entry_t rather than having both share a 32-bit. Also, documentation fixes.
Diffstat (limited to 'src')
-rw-r--r--src/or/geoip.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/src/or/geoip.c b/src/or/geoip.c
index eb0d7e43f4..fe847ed8d8 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -42,7 +42,7 @@ static strmap_t *country_idxplus1_by_lc_code = NULL;
static smartlist_t *geoip_entries = NULL;
/** Return the index of the <b>country</b>'s entry in the GeoIP DB
- * if it is a valid 2-letter country code, otherwise return zero.
+ * if it is a valid 2-letter country code, otherwise return -1.
*/
country_t
geoip_get_country(const char *country)
@@ -261,8 +261,8 @@ geoip_is_loaded(void)
typedef struct clientmap_entry_t {
HT_ENTRY(clientmap_entry_t) node;
uint32_t ipaddr;
- time_t last_seen; /* The last 2 bits of this value hold the client
- * operation. */
+ unsigned int last_seen_in_minutes:30;
+ unsigned int action:2;
} clientmap_entry_t;
#define ACTION_MASK 3
@@ -289,7 +289,7 @@ clientmap_entry_hash(const clientmap_entry_t *a)
static INLINE int
clientmap_entries_eq(const clientmap_entry_t *a, const clientmap_entry_t *b)
{
- return a->ipaddr == b->ipaddr;
+ return a->ipaddr == b->ipaddr && a->action == b->action;
}
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
@@ -298,7 +298,8 @@ HT_GENERATE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq, 0.6, malloc, realloc, free);
/** Note that we've seen a client connect from the IP <b>addr</b> (host order)
- * at time <b>now</b>. Ignored by all but bridges. */
+ * 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)
@@ -337,20 +338,18 @@ geoip_note_client_seen(geoip_client_action_t action,
current_request_period_starts += REQUEST_HIST_PERIOD;
if (n_old_request_periods < REQUEST_HIST_LEN-1)
++n_old_request_periods;
- }
+ }
- /* We use the low 3 bits of the time to encode the action. Since we're
- * potentially remembering tons of clients, we don't want to make
- * clientmap_entry_t larger than it has to be. */
- now = (now & ~ACTION_MASK) | (((int)action) & ACTION_MASK);
lookup.ipaddr = addr;
+ lookup.action = (int)action;
ent = HT_FIND(clientmap, &client_history, &lookup);
if (ent) {
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
} else {
ent = tor_malloc_zero(sizeof(clientmap_entry_t));
ent->ipaddr = addr;
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
+ ent->action = (int)action;
HT_INSERT(clientmap, &client_history, ent);
}
@@ -377,8 +376,8 @@ geoip_note_client_seen(geoip_client_action_t action,
static int
_remove_old_client_helper(struct clientmap_entry_t *ent, void *_cutoff)
{
- time_t cutoff = *(time_t*)_cutoff;
- if (ent->last_seen < cutoff) {
+ time_t cutoff = *(time_t*)_cutoff / 60;
+ if (ent->last_seen_in_minutes < cutoff) {
tor_free(ent);
return 1;
} else {
@@ -477,7 +476,7 @@ geoip_get_client_history(time_t now, geoip_client_action_t action)
#endif
HT_FOREACH(ent, clientmap, &client_history) {
int country;
- if (((*ent)->last_seen & ACTION_MASK) != (int)action)
+ if ((*ent)->action != (int)action)
continue;
country = geoip_get_country_by_ip((*ent)->ipaddr);
if (country < 0)