From 59dd9de8581c0cf0a0bd572f8d67b1be2b2a4274 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Fri, 10 Jul 2009 13:37:25 +0200 Subject: [PATCH] Write number of rejected requests to geoip-stats file. --- 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 daf2a15762..aa225d0c43 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 aac4893117..0a0fc08f84 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 action for reason reason at time + * now. */ +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 f298d53c27..a6aca94f82 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); -- 2.11.4.GIT