commit 56061976dbe148dc615c8072c962ddfc0d719585 Author: Roger Dingledine arma@torproject.org Date: Mon Feb 9 01:05:31 2015 -0500
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.) --- changes/ticket8766 | 7 +++++++ src/or/circuitbuild.c | 4 ++++ src/or/main.c | 11 +++++++++-- src/or/main.h | 1 + 4 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/changes/ticket8766 b/changes/ticket8766 new file mode 100644 index 0000000..33bfc33 --- /dev/null +++ b/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.] + diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index fa5a2f5..fa9ac56 100644 --- a/src/or/circuitbuild.c +++ b/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 diff --git a/src/or/main.c b/src/or/main.c index d3ecf36..a299f98 100644 --- a/src/or/main.c +++ b/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;
diff --git a/src/or/main.h b/src/or/main.h index f77b471..542eab6 100644 --- a/src/or/main.h +++ b/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));