Bläddra i källkod

Recover better when our clock jumps back many hours

like might happen for Tails or Whonix users who start with a very wrong
hardware clock, use Tor to discover a more accurate time, and then
fix their clock.

Resolves part of ticket 8766.

(There are still some timers in various places that aren't addressed yet.)
Roger Dingledine 10 år sedan
förälder
incheckning
56061976db
4 ändrade filer med 21 tillägg och 2 borttagningar
  1. 7 0
      changes/ticket8766
  2. 4 0
      src/or/circuitbuild.c
  3. 9 2
      src/or/main.c
  4. 1 0
      src/or/main.h

+ 7 - 0
changes/ticket8766

@@ -0,0 +1,7 @@
+  o Minor features:
+    - Recover better when our clock jumps back many hours, like might
+      happen for Tails or Whonix users who start with a very wrong
+      hardware clock, use Tor to discover a more accurate time, and then
+      fix their clock. Resolves part of ticket 8766.
+      [I'd call this a major feature if it actually fixed all of the issues.]
+

+ 4 - 0
src/or/circuitbuild.c

@@ -1049,6 +1049,10 @@ circuit_note_clock_jumped(int seconds_elapsed)
                               "CLOCK_JUMPED");
   circuit_mark_all_unused_circs();
   circuit_mark_all_dirty_circs_as_unusable();
+  if (seconds_elapsed < 0) {
+    /* Restart all the timers in case we jumped a long way into the past. */
+    reset_all_main_loop_timers();
+  }
 }
 
 /** Take the 'extend' <b>cell</b>, pull out addr/port plus the onion

+ 9 - 2
src/or/main.c

@@ -1227,6 +1227,15 @@ typedef struct {
 
 static time_to_t time_to = { 0 };
 
+/** Reset all the time_to's so we'll do all our actions again as if we
+ * just started up.
+ * Useful if our clock just moved back a long time from the future,
+ * so we don't wait until that future arrives again before acting.
+ */
+void reset_all_main_loop_timers(void) {
+  memset(&time_to, 0, sizeof(time_to_t));
+}
+
 /**
  * Update our schedule so that we'll check whether we need to update our
  * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL
@@ -1768,8 +1777,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
   if (seconds_elapsed < -NUM_JUMPED_SECONDS_BEFORE_WARN ||
       seconds_elapsed >= NUM_JUMPED_SECONDS_BEFORE_WARN) {
     circuit_note_clock_jumped(seconds_elapsed);
-    /* XXX if the time jumps *back* many months, do our events in
-     * run_scheduled_events() recover? I don't think they do. -RD */
   } else if (seconds_elapsed > 0)
     stats_n_seconds_working += seconds_elapsed;
 

+ 1 - 0
src/or/main.h

@@ -52,6 +52,7 @@ void directory_info_has_arrived(time_t now, int from_cache);
 
 void ip_address_changed(int at_interface);
 void dns_servers_relaunch_checks(void);
+void reset_all_main_loop_timers(void);
 void reschedule_descriptor_update_check(void);
 
 MOCK_DECL(long,get_uptime,(void));