]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Fix dirreq and cell stats on 32-bit architectures.
authorKarsten Loesing <karsten.loesing@gmx.net>
Mon, 27 Jul 2009 14:23:53 +0000 (16:23 +0200)
committerKarsten Loesing <karsten.loesing@gmx.net>
Mon, 27 Jul 2009 14:23:53 +0000 (16:23 +0200)
When determining how long directory requests take or how long cells spend
in queues, we were comparing timestamps on microsecond detail only to
convert results to second or millisecond detail later on. But on 32-bit
architectures this means that 2^31 microseconds only cover time
differences of up to 36 minutes. Instead, compare timestamps on
millisecond detail.

src/common/util.c
src/common/util.h
src/or/geoip.c
src/or/relay.c

index 0e7f59e6200bc662c9c0e583c2ee4db8fbb31cfe..234180c4d470dc127f1a1b1aaec41e01377920a0 100644 (file)
@@ -1032,7 +1032,8 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
   long secdiff = end->tv_sec - start->tv_sec;
 
   if (labs(secdiff+1) > LONG_MAX/1000000) {
-    log_warn(LD_GENERAL, "comparing times too far apart.");
+    log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
+             "apart: %ld seconds", secdiff);
     return LONG_MAX;
   }
 
@@ -1040,6 +1041,24 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
   return udiff;
 }
 
+/** Return the number of milliseconds elapsed between *start and *end.
+ */
+long
+tv_mdiff(const struct timeval *start, const struct timeval *end)
+{
+  long mdiff;
+  long secdiff = end->tv_sec - start->tv_sec;
+
+  if (labs(secdiff+1) > LONG_MAX/1000) {
+    log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
+             "apart: %ld seconds", secdiff);
+    return LONG_MAX;
+  }
+
+  mdiff = secdiff*1000L + (end->tv_usec - start->tv_usec) / 1000L;
+  return mdiff;
+}
+
 /** Yield true iff <b>y</b> is a leap-year. */
 #define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
 /** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */
index 1c5643be39db7adb097a1d1a5be44442add14841..c7741a64ac3253701358ed5bc8c2540567c153e3 100644 (file)
@@ -211,6 +211,7 @@ int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
 
 /* Time helpers */
 long tv_udiff(const struct timeval *start, const struct timeval *end);
+long tv_mdiff(const struct timeval *start, const struct timeval *end);
 time_t tor_timegm(struct tm *tm);
 #define RFC1123_TIME_LEN 29
 void format_rfc1123_time(char *buf, time_t t);
index 3336401220a42df2eb5da9c58a6f9ebcf337d94a..5c131542051b1f015d0c8f2ded0514673362a62d 100644 (file)
@@ -739,16 +739,16 @@ geoip_get_dirreq_history(geoip_client_action_t action,
     } else {
       if (ent->completed) {
         uint32_t *bytes_per_second = tor_malloc_zero(sizeof(uint32_t));
-        uint32_t time_diff = (uint32_t) tv_udiff(&ent->request_time,
+        uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
                                                  &ent->completion_time);
         if (time_diff == 0)
           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;
+        *bytes_per_second = 1000 * ent->response_size / time_diff;
         smartlist_add(dirreq_times, bytes_per_second);
         complete++;
       } else {
-        if (tv_udiff(&ent->request_time, &now) / 1000000 > DIRREQ_TIMEOUT)
+        if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT)
           timeouts++;
         else
           running++;
index 098b95253e4846d769a6ccf75e40efa552bcb276..66b613cca08f641fcf2d45b50eb0ce81115069de 100644 (file)
@@ -1836,7 +1836,8 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
       or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
       tor_gettimeofday(&flushed_from_queue);
       cell_waiting_time = (uint32_t)
-            (tv_udiff(&cell->packed_timeval, &flushed_from_queue) / 1000);
+            tv_mdiff(&cell->packed_timeval, &flushed_from_queue);
+
       orcirc->total_cell_waiting_time += cell_waiting_time;
       orcirc->processed_cells++;
     }