[or-cvs] [tor/master] Some tweaks to directory request download times.

Nick Mathewson nickm at seul.org
Thu Jul 16 19:26:49 UTC 2009


Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Tue, 14 Jul 2009 22:24:50 +0200
Subject: Some tweaks to directory request download times.
Commit: 416940d93bac49f78b57a2cf561bd324d75b391f

- Use common prefixes DIRREQ_* and dirreq_*.
- Replace enums in structs with bitfields.
---
 src/or/connection.c      |    6 +-
 src/or/connection_edge.c |    4 +-
 src/or/directory.c       |   17 ++++---
 src/or/geoip.c           |  119 +++++++++++++++++++++++-----------------------
 src/or/or.h              |   34 ++++++-------
 src/or/relay.c           |   17 ++++---
 6 files changed, 98 insertions(+), 99 deletions(-)

diff --git a/src/or/connection.c b/src/or/connection.c
index 3094210..242a32c 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2305,9 +2305,9 @@ connection_handle_write(connection_t *conn, int force)
 #ifdef ENABLE_GEOIP_STATS
     /* If we just flushed the last bytes, check if this tunneled dir
      * request is done. */
-    if (buf_datalen(conn->outbuf) == 0 && conn->request_id)
-      geoip_change_dirreq_state(conn->request_id, REQUEST_TUNNELED,
-                                OR_CONN_BUFFER_FLUSHED);
+    if (buf_datalen(conn->outbuf) == 0 && conn->dirreq_id)
+      geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
+                                DIRREQ_OR_CONN_BUFFER_FLUSHED);
 #endif
     switch (result) {
       CASE_TOR_TLS_ERROR_ANY:
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index f32563b..f2b499f 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2554,7 +2554,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
 #ifdef ENABLE_GEOIP_STATS
   /* Remember the tunneled request ID in the new edge connection, so that
    * we can measure download times. */
-  TO_CONN(n_stream)->request_id = circ->request_id;
+  TO_CONN(n_stream)->dirreq_id = circ->dirreq_id;
 #endif
   n_stream->_base.purpose = EXIT_PURPOSE_CONNECT;
 
@@ -2795,7 +2795,7 @@ connection_exit_connect_dir(edge_connection_t *exitconn)
 #ifdef ENABLE_GEOIP_STATS
   /* Note that the new dir conn belongs to the same tunneled request as
    * the edge conn, so that we can measure download times. */
-  TO_CONN(dirconn)->request_id = TO_CONN(exitconn)->request_id;
+  TO_CONN(dirconn)->dirreq_id = TO_CONN(exitconn)->dirreq_id;
 #endif
   connection_link_connections(TO_CONN(dirconn), TO_CONN(exitconn));
 
diff --git a/src/or/directory.c b/src/or/directory.c
index e5230c2..c6faeae 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2570,12 +2570,12 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
         geoip_note_ns_response(act, GEOIP_SUCCESS);
         /* Note that a request for a network status has started, so that we
          * can measure the download time later on. */
-        if (TO_CONN(conn)->request_id)
-          geoip_start_dirreq(TO_CONN(conn)->request_id, dlen, act,
-                             REQUEST_TUNNELED);
+        if (TO_CONN(conn)->dirreq_id)
+          geoip_start_dirreq(TO_CONN(conn)->dirreq_id, dlen, act,
+                             DIRREQ_TUNNELED);
         else
           geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen, act,
-                             REQUEST_DIRECT);
+                             DIRREQ_DIRECT);
       }
     }
 #endif
@@ -3214,12 +3214,13 @@ connection_dir_finished_flushing(dir_connection_t *conn)
   /* Note that we have finished writing the directory response. For direct
    * connections this means we're done, for tunneled connections its only
    * an intermediate step. */
-  if (TO_CONN(conn)->request_id)
-    geoip_change_dirreq_state(TO_CONN(conn)->request_id, REQUEST_TUNNELED,
-                              FLUSHING_DIR_CONN_FINISHED);
+  if (TO_CONN(conn)->dirreq_id)
+    geoip_change_dirreq_state(TO_CONN(conn)->dirreq_id, DIRREQ_TUNNELED,
+                              DIRREQ_FLUSHING_DIR_CONN_FINISHED);
   else
     geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
-                              REQUEST_DIRECT, FLUSHING_DIR_CONN_FINISHED);
+                              DIRREQ_DIRECT,
+                              DIRREQ_FLUSHING_DIR_CONN_FINISHED);
 #endif
   switch (conn->_base.state) {
     case DIR_CONN_STATE_CLIENT_SENDING:
diff --git a/src/or/geoip.c b/src/or/geoip.c
index 819c9f0..0ecc466 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -580,107 +580,106 @@ _c_hist_compare(const void **_a, const void **_b)
  * response size, and completion time of a network status request. Used to
  * measure download times of requests to derive average client
  * bandwidths. */
-typedef struct dirreqdlmap_entry_t {
-  directory_request_state_t state; /**< State of this directory request. */
+typedef struct dirreq_map_entry_t {
   /** Unique identifier for this network status request; this is either the
    * conn->global_identifier of the dir conn (direct request) or a new
    * locally unique identifier of a circuit (tunneled request). This ID is
    * only unique among other direct or tunneled requests, respectively. */
-  uint64_t request_id;
-  /** Is this a direct or a tunneled request? */
-  directory_request_type_t type;
-  int completed:1; /**< Is this request complete? */
-  geoip_client_action_t action; /**< Is this a v2 or v3 request? */
+  uint64_t dirreq_id;
+  unsigned int state:3; /**< State of this directory request. */
+  unsigned int type:1; /**< Is this a direct or a tunneled request? */
+  unsigned int completed:1; /**< Is this request complete? */
+  unsigned int action:2; /**< Is this a v2 or v3 request? */
   /** When did we receive the request and started sending the response? */
   struct timeval request_time;
   size_t response_size; /**< What is the size of the response in bytes? */
   struct timeval completion_time; /**< When did the request succeed? */
-} dirreqdlmap_entry_t;
+} dirreq_map_entry_t;
 
 /** Map of all directory requests asking for v2 or v3 network statuses in
  * the current geoip-stats interval. Keys are strings starting with either
  * "dir" for direct requests or "tun" for tunneled requests, followed by
  * a unique uint64_t identifier represented as decimal string. Values are
- * of type *<b>dirreqdlmap_entry_t</b>. */
-static strmap_t *dirreqdlmap = NULL;
+ * of type *<b>dirreq_map_entry_t</b>. */
+static strmap_t *dirreq_map = NULL;
 
 /** Helper: Put <b>entry</b> into map of directory requests using
- * <b>tunneled</b> and <b>request_id</b> as key parts. If there is
+ * <b>tunneled</b> and <b>dirreq_id</b> as key parts. If there is
  * already an entry for that key, print out a BUG warning and return. */
 static void
-_dirreqdlmap_put(dirreqdlmap_entry_t *entry,
-                 directory_request_type_t type, uint64_t request_id)
+_dirreq_map_put(dirreq_map_entry_t *entry, dirreq_type_t type,
+               uint64_t dirreq_id)
 {
   char key[3+20+1]; /* dir|tun + 18446744073709551616 + \0 */
-  dirreqdlmap_entry_t *ent;
-  if (!dirreqdlmap)
-    dirreqdlmap = strmap_new();
+  dirreq_map_entry_t *ent;
+  if (!dirreq_map)
+    dirreq_map = strmap_new();
   tor_snprintf(key, sizeof(key), "%s"U64_FORMAT,
-               type == REQUEST_TUNNELED ? "tun" : "dir",
-               U64_PRINTF_ARG(request_id));
-  ent = strmap_get(dirreqdlmap, key);
+               type == DIRREQ_TUNNELED ? "tun" : "dir",
+               U64_PRINTF_ARG(dirreq_id));
+  ent = strmap_get(dirreq_map, key);
   if (ent) {
     log_warn(LD_BUG, "Error when putting directory request into local "
              "map. There is already an entry for the same identifier.");
     return;
   }
-  strmap_set(dirreqdlmap, key, entry);
+  strmap_set(dirreq_map, key, entry);
 }
 
 /** Helper: Look up and return an entry in the map of directory requests
- * using <b>tunneled</b> and <b>request_id</b> as key parts. If there
+ * using <b>tunneled</b> and <b>dirreq_id</b> as key parts. If there
  * is no such entry, return NULL. */
-static dirreqdlmap_entry_t *
-_dirreqdlmap_get(directory_request_type_t type, uint64_t request_id)
+static dirreq_map_entry_t *
+_dirreq_map_get(dirreq_type_t type, uint64_t dirreq_id)
 {
   char key[3+20+1]; /* dir|tun + 18446744073709551616 + \0 */
-  if (!dirreqdlmap)
-    dirreqdlmap = strmap_new();
+  if (!dirreq_map)
+    dirreq_map = strmap_new();
   tor_snprintf(key, sizeof(key), "%s"U64_FORMAT,
-               type == REQUEST_TUNNELED ? "tun" : "dir",
-               U64_PRINTF_ARG(request_id));
-  return strmap_get(dirreqdlmap, key);
+               type == DIRREQ_TUNNELED ? "tun" : "dir",
+               U64_PRINTF_ARG(dirreq_id));
+  return strmap_get(dirreq_map, key);
 }
 
 /** Note that an either direct or tunneled (see <b>type</b>) directory
- * request for a network status with unique ID <b>request_id</b> of size
+ * request for a network status with unique ID <b>dirreq_id</b> of size
  * <b>response_size</b> and action <b>action</b> (either v2 or v3) has
  * started. */
 void
-geoip_start_dirreq(uint64_t request_id, size_t response_size,
-                   geoip_client_action_t action,
-                   directory_request_type_t type)
+geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
+                   geoip_client_action_t action, dirreq_type_t type)
 {
-  dirreqdlmap_entry_t *ent = tor_malloc_zero(sizeof(dirreqdlmap_entry_t));
-  ent->request_id = request_id;
+  dirreq_map_entry_t *ent = tor_malloc_zero(sizeof(dirreq_map_entry_t));
+  ent->dirreq_id = dirreq_id;
   tor_gettimeofday(&ent->request_time);
   ent->response_size = response_size;
   ent->action = action;
   ent->type = type;
-  _dirreqdlmap_put(ent, type, request_id);
+  _dirreq_map_put(ent, type, dirreq_id);
 }
 
 /** Change the state of the either direct or tunneled (see <b>type</b>)
- * directory request with <b>request_id</b> to <b>new_state</b> and
+ * directory request with <b>dirreq_id</b> to <b>new_state</b> and
  * possibly mark it as completed. If no entry can be found for the given
  * key parts (e.g., if this is a directory request that we are not
  * measuring, or one that was started in the previous measurement period),
  * or if the state cannot be advanced to <b>new_state</b>, do nothing. */
 void
-geoip_change_dirreq_state(uint64_t request_id,
-                          directory_request_type_t type,
-                          directory_request_state_t new_state)
+geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
+                          dirreq_state_t new_state)
 {
-  dirreqdlmap_entry_t *ent = _dirreqdlmap_get(type, request_id);
+  dirreq_map_entry_t *ent = _dirreq_map_get(type, dirreq_id);
   if (!ent)
     return;
-  if (new_state == REQUEST_IS_FOR_NETWORK_STATUS)
+  if (new_state == DIRREQ_IS_FOR_NETWORK_STATUS)
     return;
   if (new_state - 1 != ent->state)
     return;
   ent->state = new_state;
-  if ((type == REQUEST_DIRECT && new_state == FLUSHING_DIR_CONN_FINISHED) ||
-      (type == REQUEST_TUNNELED && new_state == OR_CONN_BUFFER_FLUSHED)) {
+  if ((type == DIRREQ_DIRECT &&
+         new_state == DIRREQ_FLUSHING_DIR_CONN_FINISHED) ||
+      (type == DIRREQ_TUNNELED &&
+         new_state == DIRREQ_OR_CONN_BUFFER_FLUSHED)) {
     tor_gettimeofday(&ent->completion_time);
     ent->completed = 1;
   }
@@ -693,22 +692,22 @@ geoip_change_dirreq_state(uint64_t request_id,
  * times by deciles and quartiles. Return NULL if we have not observed
  * requests for long enough. */
 static char *
-geoip_get_dirreqdl_history(geoip_client_action_t action,
-                           directory_request_type_t type)
+geoip_get_dirreq_history(geoip_client_action_t action,
+                           dirreq_type_t type)
 {
   char *result = NULL;
-  smartlist_t *dirreqdl_times = NULL;
+  smartlist_t *dirreq_times = NULL;
   uint32_t complete = 0, timeouts = 0, running = 0;
   int i = 0, bufsize = 1024, written;
   struct timeval now;
   tor_gettimeofday(&now);
-  if (!dirreqdlmap)
+  if (!dirreq_map)
     return NULL;
   if (action != GEOIP_CLIENT_NETWORKSTATUS &&
       action != GEOIP_CLIENT_NETWORKSTATUS_V2)
     return NULL;
-  dirreqdl_times = smartlist_create();
-  STRMAP_FOREACH_MODIFY(dirreqdlmap, key, dirreqdlmap_entry_t *, ent) {
+  dirreq_times = smartlist_create();
+  STRMAP_FOREACH_MODIFY(dirreq_map, key, dirreq_map_entry_t *, ent) {
     if (ent->action == action && type == ent->type) {
       if (ent->completed) {
         uint32_t *bytes_per_second = tor_malloc_zero(sizeof(uint32_t));
@@ -718,7 +717,7 @@ geoip_get_dirreqdl_history(geoip_client_action_t action,
           time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
                           * anyway by law of nature or something.. */
         *bytes_per_second = 1000000 * ent->response_size / time_diff;
-        smartlist_add(dirreqdl_times, bytes_per_second);
+        smartlist_add(dirreq_times, bytes_per_second);
         complete++;
       } else {
         if (tv_udiff(&ent->request_time, &now) / 1000000 > DIRREQ_TIMEOUT)
@@ -745,7 +744,7 @@ geoip_get_dirreqdl_history(geoip_client_action_t action,
 #define MIN_DIR_REQ_RESPONSES 16
   if (complete >= MIN_DIR_REQ_RESPONSES) {
     uint32_t *dltimes = tor_malloc(sizeof(uint32_t) * complete);
-    SMARTLIST_FOREACH(dirreqdl_times, uint32_t *, dlt, {
+    SMARTLIST_FOREACH(dirreq_times, uint32_t *, dlt, {
       dltimes[i++] = *dlt;
       tor_free(dlt);
     });
@@ -770,7 +769,7 @@ geoip_get_dirreqdl_history(geoip_client_action_t action,
   }
   if (written < 0)
     result = NULL;
-  smartlist_free(dirreqdl_times);
+  smartlist_free(dirreq_times);
   return result;
 }
 #endif
@@ -990,19 +989,19 @@ dump_geoip_stats(void)
       goto done;
   }
 
-  data_v2 = geoip_get_dirreqdl_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
-                                       REQUEST_DIRECT);
-  data_v3 = geoip_get_dirreqdl_history(GEOIP_CLIENT_NETWORKSTATUS,
-                                       REQUEST_DIRECT);
+  data_v2 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
+                                       DIRREQ_DIRECT);
+  data_v3 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS,
+                                       DIRREQ_DIRECT);
   if (fprintf(out, "ns-direct-dl %s\nns-v2-direct-dl %s\n",
               data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
     goto done;
   tor_free(data_v2);
   tor_free(data_v3);
-  data_v2 = geoip_get_dirreqdl_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
-                                       REQUEST_TUNNELED);
-  data_v3 = geoip_get_dirreqdl_history(GEOIP_CLIENT_NETWORKSTATUS,
-                                       REQUEST_TUNNELED);
+  data_v2 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
+                                       DIRREQ_TUNNELED);
+  data_v3 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS,
+                                       DIRREQ_TUNNELED);
   if (fprintf(out, "ns-tunneled-dl %s\nns-v2-tunneled-dl %s\n",
               data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
     goto done;
diff --git a/src/or/or.h b/src/or/or.h
index 035d4ed..7b91ff7 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -972,7 +972,7 @@ typedef struct connection_t {
 
 #ifdef ENABLE_GEOIP_STATS
   /** Unique ID for measuring tunneled network status requests. */
-  uint64_t request_id;
+  uint64_t dirreq_id;
 #endif
 } connection_t;
 
@@ -1962,7 +1962,7 @@ typedef struct circuit_t {
   struct circuit_t *next; /**< Next circuit in linked list of all circuits. */
 #ifdef ENABLE_GEOIP_STATS
   /** Unique ID for measuring tunneled network status requests. */
-  uint64_t request_id;
+  uint64_t dirreq_id;
 #endif
 } circuit_t;
 
@@ -3683,9 +3683,9 @@ void geoip_free_all(void);
 /** Directory requests that we are measuring can be either direct or
  * tunneled. */
 typedef enum {
-  REQUEST_DIRECT = 0,
-  REQUEST_TUNNELED = 1,
-} directory_request_type_t;
+  DIRREQ_DIRECT = 0,
+  DIRREQ_TUNNELED = 1,
+} dirreq_type_t;
 
 /** Possible states for either direct or tunneled directory requests that
  * are relevant for determining network status download times. */
@@ -3693,28 +3693,26 @@ typedef enum {
   /** Found that the client requests a network status; applies to both
    * direct and tunneled requests; initial state of a request that we are
    * measuring. */
-  REQUEST_IS_FOR_NETWORK_STATUS = 0,
+  DIRREQ_IS_FOR_NETWORK_STATUS = 0,
   /** Finished writing a network status to the directory connection;
    * applies to both direct and tunneled requests; completes a direct
    * request. */
-  FLUSHING_DIR_CONN_FINISHED = 1,
+  DIRREQ_FLUSHING_DIR_CONN_FINISHED = 1,
   /** END cell sent to circuit that initiated a tunneled request. */
-  END_CELL_SENT = 2,
+  DIRREQ_END_CELL_SENT = 2,
   /** Flushed last cell from queue of the circuit that initiated a
     * tunneled request to the outbuf of the OR connection. */
-  CIRC_QUEUE_FLUSHED = 3,
+  DIRREQ_CIRC_QUEUE_FLUSHED = 3,
   /** Flushed last byte from buffer of the OR connection belonging to the
     * circuit that initiated a tunneled request; completes a tunneled
     * request. */
-  OR_CONN_BUFFER_FLUSHED = 4
-} directory_request_state_t;
-
-void geoip_start_dirreq(uint64_t request_id, size_t response_size,
-                        geoip_client_action_t action,
-                        directory_request_type_t type);
-void geoip_change_dirreq_state(uint64_t request_id,
-                               directory_request_type_t type,
-                               directory_request_state_t new_state);
+  DIRREQ_OR_CONN_BUFFER_FLUSHED = 4
+} dirreq_state_t;
+
+void geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
+                        geoip_client_action_t action, dirreq_type_t type);
+void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
+                               dirreq_state_t new_state);
 
 /********************************* hibernate.c **********************/
 
diff --git a/src/or/relay.c b/src/or/relay.c
index 580048b..5654736 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -535,9 +535,9 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
 #ifdef ENABLE_GEOIP_STATS
   /* If we are sending an END cell and this circuit is used for a tunneled
    * directory request, advance its state. */
-  if (relay_command == RELAY_COMMAND_END && circ->request_id)
-    geoip_change_dirreq_state(circ->request_id, REQUEST_TUNNELED,
-                              END_CELL_SENT);
+  if (relay_command == RELAY_COMMAND_END && circ->dirreq_id)
+    geoip_change_dirreq_state(circ->dirreq_id, DIRREQ_TUNNELED,
+                              DIRREQ_END_CELL_SENT);
 #endif
 
   if (cell_direction == CELL_DIRECTION_OUT && circ->n_conn) {
@@ -1047,8 +1047,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
          * connection will be assigned the same ID when they are created
          * and linked. */
         static uint64_t next_id = 0;
-        circ->request_id = ++next_id;
-        TO_CONN(TO_OR_CIRCUIT(circ)->p_conn)->request_id = circ->request_id;
+        circ->dirreq_id = ++next_id;
+        TO_CONN(TO_OR_CIRCUIT(circ)->p_conn)->dirreq_id = circ->dirreq_id;
       }
 #endif
 
@@ -1844,9 +1844,10 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
 #ifdef ENABLE_GEOIP_STATS
     /* If we just flushed our queue and this circuit is used for a
      * tunneled directory request, possibly advance its state. */
-    if (queue->n == 0 && TO_CONN(conn)->request_id)
-      geoip_change_dirreq_state(TO_CONN(conn)->request_id,
-                                REQUEST_TUNNELED, CIRC_QUEUE_FLUSHED);
+    if (queue->n == 0 && TO_CONN(conn)->dirreq_id)
+      geoip_change_dirreq_state(TO_CONN(conn)->dirreq_id,
+                                DIRREQ_TUNNELED,
+                                DIRREQ_CIRC_QUEUE_FLUSHED);
 #endif
 
     connection_write_to_buf(cell->body, CELL_NETWORK_SIZE, TO_CONN(conn));
-- 
1.5.6.5




More information about the tor-commits mailing list