[or-cvs] [tor/master] Write number of rejected requests to geoip-stats file.

Nick Mathewson nickm at seul.org
Tue Jul 14 16:21:38 UTC 2009


Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Fri, 10 Jul 2009 13:37:25 +0200
Subject: Write number of rejected requests to geoip-stats file.
Commit: 59dd9de8581c0cf0a0bd572f8d67b1be2b2a4274

---
 src/or/directory.c |   10 ++++++-
 src/or/geoip.c     |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/or.h        |   20 ++++++++++++++++
 3 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/src/or/directory.c b/src/or/directory.c
index daf2a15..aa225d0 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2493,6 +2493,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
     /* v2 or v3 network status fetch. */
     smartlist_t *dir_fps = smartlist_create();
     int is_v3 = !strcmpstart(url, "/tor/status-vote");
+    geoip_client_action_t act =
+        is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
     const char *request_type = NULL;
     const char *key = url + strlen("/tor/status/");
     long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
@@ -2517,6 +2519,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
         write_http_status_line(conn, 404, "Consensus not signed by sufficient "
                                           "number of requested authorities");
         smartlist_free(dir_fps);
+        geoip_note_ns_response(act, GEOIP_REJECT_NOT_ENOUGH_SIGS);
         goto done;
       }
 
@@ -2529,6 +2532,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
     if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
       write_http_status_line(conn, 503, "Network status object unavailable");
       smartlist_free(dir_fps);
+      geoip_note_ns_response(act, GEOIP_REJECT_UNAVAILABLE);
       goto done;
     }
 
@@ -2536,11 +2540,13 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       write_http_status_line(conn, 404, "Not found");
       SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
       smartlist_free(dir_fps);
+      geoip_note_ns_response(act, GEOIP_REJECT_NOT_FOUND);
       goto done;
     } else if (!smartlist_len(dir_fps)) {
       write_http_status_line(conn, 304, "Not modified");
       SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
       smartlist_free(dir_fps);
+      geoip_note_ns_response(act, GEOIP_REJECT_NOT_MODIFIED);
       goto done;
     }
 
@@ -2552,16 +2558,16 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       write_http_status_line(conn, 503, "Directory busy, try again later");
       SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
       smartlist_free(dir_fps);
+      geoip_note_ns_response(act, GEOIP_REJECT_BUSY);
       goto done;
     }
 
 #ifdef ENABLE_GEOIP_STATS
     {
-      geoip_client_action_t act =
-        is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
       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);
     }
 #endif
 
diff --git a/src/or/geoip.c b/src/or/geoip.c
index aac4893..0a0fc08 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -418,6 +418,43 @@ geoip_remove_old_clients(time_t cutoff)
     client_history_starts = cutoff;
 }
 
+#ifdef ENABLE_GEOIP_STATS
+/** How many responses are we giving to clients requesting v2 network
+ * statuses? */
+static uint32_t ns_v2_responses[GEOIP_NS_RESPONSE_NUM];
+
+/** How many responses are we giving to clients requesting v3 network
+ * statuses? */
+static uint32_t ns_v3_responses[GEOIP_NS_RESPONSE_NUM];
+#endif
+
+/** Note that we've rejected a client's request for a v2 or v3 network
+ * status, encoded in <b>action</b> for reason <b>reason</b> at time
+ * <b>now</b>. */
+void
+geoip_note_ns_response(geoip_client_action_t action,
+                       geoip_ns_response_t response)
+{
+#ifdef ENABLE_GEOIP_STATS
+  static int arrays_initialized = 0;
+  if (!arrays_initialized) {
+    memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
+    memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
+    arrays_initialized = 1;
+  }
+  tor_assert(action == GEOIP_CLIENT_NETWORKSTATUS ||
+             action == GEOIP_CLIENT_NETWORKSTATUS_V2);
+  tor_assert(response < GEOIP_NS_RESPONSE_NUM);
+  if (action == GEOIP_CLIENT_NETWORKSTATUS)
+    ns_v3_responses[response]++;
+  else
+    ns_v2_responses[response]++;
+#else
+  (void) action;
+  (void) response;
+#endif
+}
+
 /** Do not mention any country from which fewer than this number of IPs have
  * connected.  This conceivably avoids reporting information that could
  * deanonymize users, though analysis is lacking. */
@@ -612,6 +649,7 @@ dump_geoip_stats(void)
   open_file_t *open_file = NULL;
   double v2_share = 0.0, v3_share = 0.0;
   FILE *out;
+  int i;
 
   data_v2 = geoip_get_client_history(now, GEOIP_CLIENT_NETWORKSTATUS_V2);
   data_v3 = geoip_get_client_history(now, GEOIP_CLIENT_NETWORKSTATUS);
@@ -637,6 +675,33 @@ dump_geoip_stats(void)
               since,
               data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
     goto done;
+#define RESPONSE_GRANULARITY 8
+  for (i = 0; i < GEOIP_NS_RESPONSE_NUM; i++) {
+    ns_v2_responses[i] = round_to_next_multiple_of(ns_v2_responses[i],
+                                                   RESPONSE_GRANULARITY);
+    ns_v3_responses[i] = round_to_next_multiple_of(ns_v3_responses[i],
+                                                   RESPONSE_GRANULARITY);
+  }
+#undef RESPONSE_GRANULARITY
+  if (fprintf(out, "n-ns-resp ok=%d,not-enough-sigs=%d,unavailable=%d,"
+                   "not-found=%d,not-modified=%d,busy=%d\n",
+                   ns_v3_responses[GEOIP_SUCCESS],
+                   ns_v3_responses[GEOIP_REJECT_NOT_ENOUGH_SIGS],
+                   ns_v3_responses[GEOIP_REJECT_UNAVAILABLE],
+                   ns_v3_responses[GEOIP_REJECT_NOT_FOUND],
+                   ns_v3_responses[GEOIP_REJECT_NOT_MODIFIED],
+                   ns_v3_responses[GEOIP_REJECT_BUSY]) < 0)
+    goto done;
+  if (fprintf(out, "n-v2-ns-resp ok=%d,unavailable=%d,"
+                   "not-found=%d,not-modified=%d,busy=%d\n",
+                   ns_v2_responses[GEOIP_SUCCESS],
+                   ns_v2_responses[GEOIP_REJECT_UNAVAILABLE],
+                   ns_v2_responses[GEOIP_REJECT_NOT_FOUND],
+                   ns_v2_responses[GEOIP_REJECT_NOT_MODIFIED],
+                   ns_v2_responses[GEOIP_REJECT_BUSY]) < 0)
+    goto done;
+  memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
+  memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
   if (!router_get_my_share_of_directory_requests(&v2_share, &v3_share)) {
     if (fprintf(out, "v2-ns-share %0.2lf%%\n", v2_share*100) < 0)
       goto done;
diff --git a/src/or/or.h b/src/or/or.h
index f298d53..a6aca94 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3647,6 +3647,26 @@ typedef enum {
 void geoip_note_client_seen(geoip_client_action_t action,
                             uint32_t addr, time_t now);
 void geoip_remove_old_clients(time_t cutoff);
+/** Indicates either a positive reply or a reason for rejectng a network
+ * status request that will be included in geoip statistics. */
+typedef enum {
+  /** Request is answered successfully. */
+  GEOIP_SUCCESS = 0,
+  /** V3 network status is not signed by a sufficient number of requested
+   * authorities. */
+  GEOIP_REJECT_NOT_ENOUGH_SIGS = 1,
+  /** Requested network status object is unavailable. */
+  GEOIP_REJECT_UNAVAILABLE = 2,
+  /** Requested network status not found. */
+  GEOIP_REJECT_NOT_FOUND = 3,
+  /** Network status has not been modified since If-Modified-Since time. */
+  GEOIP_REJECT_NOT_MODIFIED = 4,
+  /** Directory is busy. */
+  GEOIP_REJECT_BUSY = 5,
+} geoip_ns_response_t;
+#define GEOIP_NS_RESPONSE_NUM 6
+void geoip_note_ns_response(geoip_client_action_t action,
+                            geoip_ns_response_t response);
 time_t geoip_get_history_start(void);
 char *geoip_get_client_history(time_t now, geoip_client_action_t action);
 char *geoip_get_request_history(time_t now, geoip_client_action_t action);
-- 
1.5.6.5




More information about the tor-commits mailing list