diff --git a/doc/TODO b/doc/TODO index b61304dd80..09f8319d16 100644 --- a/doc/TODO +++ b/doc/TODO @@ -71,7 +71,7 @@ Things we'd like to do in 0.2.0.x: - Dump certificates with the wrong time. Or just warn? - Warn authority ops when their certs are nearly invalid. - When checking a consensus, make sure that its times are plausible. - - Add a function that will eventually tell us about our clock skew. + o Add a function that will eventually tell us about our clock skew. For now, just require that authorities not be skewed. - Start caching consensus documents once authorities make them - Start downloading and using consensus documents once caches serve them diff --git a/src/common/util.c b/src/common/util.c index d8e89395ad..e0eeee282a 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1250,6 +1250,70 @@ parse_http_time(const char *date, struct tm *tm) return 0; } +/* ===== + * Fuzzy time + * ===== */ + +/* In a perfect world, everybody would run ntp, and ntp would be perfect, so + * if we wanted to know "Is the current time before time X?" we could just say + * "time(NULL) < X". + * + * But unfortunately, many users are running Tor in an imperfect world, on + * even more imperfect computers. Hence, we need to track time oddly. We + * model the user's computer as being "skewed" from accurate time by + * -ftime_skew seconds, such that our best guess of the current time is + * time(NULL)+ftime_skew. We also assume that our measurements of time may + * have up to ftime_slop seconds of inaccuracy; hence, the + * measurements; + */ +static int ftime_skew = 0; +static int ftime_slop = 60; +void +ftime_set_maximum_sloppiness(int seconds) +{ + tor_assert(seconds >= 0); + ftime_slop = seconds; +} +void +ftime_set_estimated_skew(int seconds) +{ + ftime_skew = seconds; +} +#if 0 +void +ftime_get_window(time_t now, ftime_t *ft_out) +{ + ft_out->earliest = now + ftime_skew - ftime_slop; + ft_out->latest = now + ftime_skew + ftime_slop; +} +#endif +int +ftime_maybe_after(time_t now, time_t when) +{ + /* It may be after when iff the latest possible current time is after when. */ + return (now + ftime_skew + ftime_slop) >= when; +} +int +ftime_maybe_before(time_t now, time_t when) +{ + /* It may be before when iff the earliest possible current time is before. */ + return (now + ftime_skew - ftime_slop) < when; +} +int +ftime_definitely_after(time_t now, time_t when) +{ + /* It is definitely after when if the earliest time it could be is still + * after when. */ + return (now + ftime_skew - ftime_slop) >= when; +} +int +ftime_definitely_before(time_t now, time_t when) +{ + /* It is definitely before when if the latest time it could be is still + * before when. */ + return (now + ftime_skew + ftime_slop) < when; +} + /* ===== * File helpers * ===== */ diff --git a/src/common/util.h b/src/common/util.h index d973948c50..950de9bacc 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -206,6 +206,15 @@ void format_local_iso_time(char *buf, time_t t); void format_iso_time(char *buf, time_t t); int parse_iso_time(const char *buf, time_t *t); int parse_http_time(const char *buf, struct tm *tm); +/* Fuzzy time. */ +void ftime_set_maximum_sloppiness(int seconds); +void ftime_set_estimated_skew(int seconds); +/* typedef struct ftime_t { time_t earliest; time_t latest; } ftime_t; */ +/* void ftime_get_window(time_t now, ftime_t *ft_out); */ +int ftime_maybe_after(time_t now, time_t when); +int ftime_maybe_before(time_t now, time_t when); +int ftime_definitely_after(time_t now, time_t when); +int ftime_definitely_before(time_t now, time_t when); /* File helpers */ int write_all(int fd, const char *buf, size_t count, int isSocket);