Forráskód Böngészése

Fix dirreq and cell stats on 32-bit architectures.

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.
Karsten Loesing 15 éve
szülő
commit
7b716878cb
4 módosított fájl, 26 hozzáadás és 5 törlés
  1. 20 1
      src/common/util.c
  2. 1 0
      src/common/util.h
  3. 3 3
      src/or/geoip.c
  4. 2 1
      src/or/relay.c

+ 20 - 1
src/common/util.c

@@ -1032,7 +1032,8 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
   long secdiff = end->tv_sec - start->tv_sec;
   long secdiff = end->tv_sec - start->tv_sec;
 
 
   if (labs(secdiff+1) > LONG_MAX/1000000) {
   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;
     return LONG_MAX;
   }
   }
 
 
@@ -1040,6 +1041,24 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
   return udiff;
   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. */
 /** Yield true iff <b>y</b> is a leap-year. */
 #define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
 #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. */
 /** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */

+ 1 - 0
src/common/util.h

@@ -211,6 +211,7 @@ int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
 
 
 /* Time helpers */
 /* Time helpers */
 long tv_udiff(const struct timeval *start, const struct timeval *end);
 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);
 time_t tor_timegm(struct tm *tm);
 #define RFC1123_TIME_LEN 29
 #define RFC1123_TIME_LEN 29
 void format_rfc1123_time(char *buf, time_t t);
 void format_rfc1123_time(char *buf, time_t t);

+ 3 - 3
src/or/geoip.c

@@ -739,16 +739,16 @@ geoip_get_dirreq_history(geoip_client_action_t action,
     } else {
     } else {
       if (ent->completed) {
       if (ent->completed) {
         uint32_t *bytes_per_second = tor_malloc_zero(sizeof(uint32_t));
         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);
                                                  &ent->completion_time);
         if (time_diff == 0)
         if (time_diff == 0)
           time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
           time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
                           * anyway by law of nature or something.. */
                           * 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);
         smartlist_add(dirreq_times, bytes_per_second);
         complete++;
         complete++;
       } else {
       } else {
-        if (tv_udiff(&ent->request_time, &now) / 1000000 > DIRREQ_TIMEOUT)
+        if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT)
           timeouts++;
           timeouts++;
         else
         else
           running++;
           running++;

+ 2 - 1
src/or/relay.c

@@ -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);
       or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
       tor_gettimeofday(&flushed_from_queue);
       tor_gettimeofday(&flushed_from_queue);
       cell_waiting_time = (uint32_t)
       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->total_cell_waiting_time += cell_waiting_time;
       orcirc->processed_cells++;
       orcirc->processed_cells++;
     }
     }