[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r12863: Sort GeoIP results in descending order of IP counts. (in tor/trunk: . src/or)
Author: nickm
Date: 2007-12-18 18:45:19 -0500 (Tue, 18 Dec 2007)
New Revision: 12863
Modified:
tor/trunk/
tor/trunk/src/or/geoip.c
tor/trunk/src/or/test.c
Log:
r17239@catbus: nickm | 2007-12-18 16:57:02 -0500
Sort GeoIP results in descending order of IP counts.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r17239] on 8246c3cf-6607-4228-993b-4d95d33730f1
Modified: tor/trunk/src/or/geoip.c
===================================================================
--- tor/trunk/src/or/geoip.c 2007-12-18 23:04:49 UTC (rev 12862)
+++ tor/trunk/src/or/geoip.c 2007-12-18 23:45:19 UTC (rev 12863)
@@ -294,6 +294,27 @@
return client_history_starts;
}
+/* Helper type: used to sort results by value. */
+typedef struct c_hist_t {
+ char country[3];
+ unsigned total;
+} c_hist_t;
+
+/** Sorting helper: return -1, 1, or 0 based on comparison of two
+ * geoip_entry_t. Sort in descending order of total, and then by country
+ * code. */
+static int
+_c_hist_compare(const void **_a, const void **_b)
+{
+ const c_hist_t *a = *_a, *b = *_b;
+ if (a->total > b->total)
+ return -1;
+ else if (a->total < b->total)
+ return 1;
+ else
+ return strcmp(a->country, b->country);
+}
+
/** Return a newly allocated comma-separated string containing entries for all
* the countries from which we've seen enough clients connect. The entry
* format is cc=num where num is the number of IPs we've seen connecting from
@@ -308,6 +329,7 @@
if (client_history_starts < (now - 12*60*60)) {
char buf[32];
smartlist_t *chunks = NULL;
+ smartlist_t *entries = NULL;
int n_countries = geoip_get_n_countries();
int i;
clientmap_entry_t **ent;
@@ -321,19 +343,35 @@
++counts[country];
++total;
}
+ /* Don't record anything if we haven't seen enough IPs. */
if (total < MIN_IPS_TO_NOTE_ANYTHING)
goto done;
- chunks = smartlist_create();
+ /* Make a list of c_hist_t */
+ entries = smartlist_create();
for (i = 0; i < n_countries; ++i) {
unsigned c = counts[i];
const char *countrycode;
+ c_hist_t *ent;
+ /* Only report a country if it has a minimum number of IPs. */
if (c >= MIN_IPS_TO_NOTE_COUNTRY) {
c -= c % IP_GRANULARITY;
countrycode = geoip_get_country_name(i);
- tor_snprintf(buf, sizeof(buf), "%s=%u", countrycode, c);
- smartlist_add(chunks, tor_strdup(buf));
+ ent = tor_malloc(sizeof(c_hist_t));
+ strlcpy(ent->country, countrycode, sizeof(ent->country));
+ ent->total = c;
+ smartlist_add(entries, ent);
}
}
+ /* Sort entries. Note that we must do this _AFTER_ rounding, or else
+ * the sort order could leak info. */
+ smartlist_sort(entries, _c_hist_compare);
+
+ /* Build the result. */
+ chunks = smartlist_create();
+ SMARTLIST_FOREACH(entries, c_hist_t *, ch, {
+ tor_snprintf(buf, sizeof(buf), "%s=%u", ch->country, ch->total);
+ smartlist_add(chunks, tor_strdup(buf));
+ });
result = smartlist_join_strings(chunks, ",", 0, NULL);
done:
tor_free(counts);
@@ -341,6 +379,10 @@
SMARTLIST_FOREACH(chunks, char *, c, tor_free(c));
smartlist_free(chunks);
}
+ if (entries) {
+ SMARTLIST_FOREACH(entries, c_hist_t *, c, tor_free(c));
+ smartlist_free(entries);
+ }
}
return result;
}
Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c 2007-12-18 23:04:49 UTC (rev 12862)
+++ tor/trunk/src/or/test.c 2007-12-18 23:45:19 UTC (rev 12863)
@@ -3414,7 +3414,7 @@
geoip_note_client_seen(i, now-7200);
s = geoip_get_client_history(now+5*24*60*60);
test_assert(s);
- test_streq("ab=8,zz=16", s);
+ test_streq("zz=16,ab=8", s);
tor_free(s);
/* Now clear out all the zz observations. */