Browse Source

Extract our code for answering "what time is it right now".

The other time stuff is higher-level
Nick Mathewson 5 years ago
parent
commit
9426751b72

+ 2 - 0
.gitignore

@@ -178,6 +178,8 @@ uptime-*.json
 /src/lib/libtor-tls.a
 /src/lib/libtor-tls-testing.a
 /src/lib/libtor-trace.a
+/src/lib/libtor-wallclock.a
+/src/lib/libtor-wallclock-testing.a
 
 # /src/or/
 /src/or/Makefile

+ 2 - 0
Makefile.am

@@ -42,6 +42,7 @@ TOR_UTIL_LIBS = \
 	src/common/libor.a \
 	src/lib/libtor-container.a \
 	src/lib/libtor-malloc.a \
+        src/lib/libtor-wallclock.a \
         src/lib/libtor-err.a \
 	src/lib/libtor-ctime.a
 
@@ -51,6 +52,7 @@ TOR_UTIL_TESTING_LIBS = \
 	src/common/libor-testing.a \
 	src/lib/libtor-container-testing.a \
 	src/lib/libtor-malloc-testing.a \
+        src/lib/libtor-wallclock-testing.a \
         src/lib/libtor-err-testing.a \
         src/lib/libtor-ctime-testing.a
 

+ 0 - 53
src/common/compat_time.c

@@ -38,12 +38,6 @@
 #include "common/torlog.h"
 #include "common/util.h"
 
-#ifndef HAVE_GETTIMEOFDAY
-#ifdef HAVE_FTIME
-#include <sys/timeb.h>
-#endif
-#endif
-
 #ifdef _WIN32
 #undef HAVE_CLOCK_GETTIME
 #endif
@@ -68,53 +62,6 @@ tor_sleep_msec(int msec)
 }
 #endif /* defined(TOR_UNIT_TESTS) */
 
-/** Set *timeval to the current time of day.  On error, log and terminate.
- * (Same as gettimeofday(timeval,NULL), but never returns -1.)
- */
-MOCK_IMPL(void,
-tor_gettimeofday, (struct timeval *timeval))
-{
-#ifdef _WIN32
-  /* Epoch bias copied from perl: number of units between windows epoch and
-   * Unix epoch. */
-#define EPOCH_BIAS U64_LITERAL(116444736000000000)
-#define UNITS_PER_SEC U64_LITERAL(10000000)
-#define USEC_PER_SEC U64_LITERAL(1000000)
-#define UNITS_PER_USEC U64_LITERAL(10)
-  union {
-    uint64_t ft_64;
-    FILETIME ft_ft;
-  } ft;
-  /* number of 100-nsec units since Jan 1, 1601 */
-  GetSystemTimeAsFileTime(&ft.ft_ft);
-  if (ft.ft_64 < EPOCH_BIAS) {
-    /* LCOV_EXCL_START */
-    log_err(LD_GENERAL,"System time is before 1970; failing.");
-    exit(1); // exit ok: system clock is broken.
-    /* LCOV_EXCL_STOP */
-  }
-  ft.ft_64 -= EPOCH_BIAS;
-  timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
-  timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
-#elif defined(HAVE_GETTIMEOFDAY)
-  if (gettimeofday(timeval, NULL)) {
-    /* LCOV_EXCL_START */
-    /* If gettimeofday dies, we have either given a bad timezone (we didn't),
-       or segfaulted.*/
-    raw_assert_unreached_msg("gettimeofday failed");
-    /* LCOV_EXCL_STOP */
-  }
-#elif defined(HAVE_FTIME)
-  struct timeb tb;
-  ftime(&tb);
-  timeval->tv_sec = tb.time;
-  timeval->tv_usec = tb.millitm * 1000;
-#else
-#error "No way to get time."
-#endif /* defined(_WIN32) || ... */
-  return;
-}
-
 #define ONE_MILLION ((int64_t) (1000 * 1000))
 #define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
 

+ 2 - 3
src/common/compat_time.h

@@ -19,6 +19,8 @@
 #define TOR_COMPAT_TIME_H
 
 #include "orconfig.h"
+#include "lib/wallclock/tor_gettimeofday.h"
+
 #ifdef _WIN32
 #undef HAVE_CLOCK_GETTIME
 #endif
@@ -200,8 +202,6 @@ monotime_coarse_diff_msec32(const monotime_coarse_t *start,
 #endif
 }
 
-MOCK_DECL(void, tor_gettimeofday, (struct timeval *timeval));
-
 #ifdef TOR_UNIT_TESTS
 void tor_sleep_msec(int msec);
 
@@ -230,4 +230,3 @@ void monotime_reset_ratchets_for_testing(void);
 #endif /* defined(COMPAT_TIME_PRIVATE) */
 
 #endif /* !defined(TOR_COMPAT_TIME_H) */
-

+ 2 - 0
src/common/log.c

@@ -35,6 +35,8 @@
 #include "common/torlog.h"
 #include "lib/container/smartlist.h"
 #include "lib/err/torerr.h"
+#include "lib/wallclock/tor_gettimeofday.h"
+#include "lib/wallclock/approx_time.h"
 
 #ifdef HAVE_ANDROID_LOG_H
 #include <android/log.h>

+ 0 - 31
src/common/util.c

@@ -1798,37 +1798,6 @@ format_time_interval(char *out, size_t out_len, long interval)
   }
 }
 
-/* =====
- * Cached time
- * ===== */
-
-#ifndef TIME_IS_FAST
-/** Cached estimate of the current time.  Updated around once per second;
- * may be a few seconds off if we are really busy.  This is a hack to avoid
- * calling time(NULL) (which not everybody has optimized) on critical paths.
- */
-static time_t cached_approx_time = 0;
-
-/** Return a cached estimate of the current time from when
- * update_approx_time() was last called.  This is a hack to avoid calling
- * time(NULL) on critical paths: please do not even think of calling it
- * anywhere else. */
-time_t
-approx_time(void)
-{
-  return cached_approx_time;
-}
-
-/** Update the cached estimate of the current time.  This function SHOULD be
- * called once per second, and MUST be called before the first call to
- * get_approx_time. */
-void
-update_approx_time(time_t now)
-{
-  cached_approx_time = now;
-}
-#endif /* !defined(TIME_IS_FAST) */
-
 /* =====
  * Rate limiting
  * ===== */

+ 1 - 9
src/common/util.h

@@ -24,6 +24,7 @@
 #endif
 #include "lib/err/torerr.h"
 #include "lib/malloc/util_malloc.h"
+#include "lib/wallclock/approx_time.h"
 #include "common/util_bug.h"
 
 #ifndef O_BINARY
@@ -178,15 +179,6 @@ int parse_iso_time_nospace(const char *cp, time_t *t);
 int parse_http_time(const char *buf, struct tm *tm);
 int format_time_interval(char *out, size_t out_len, long interval);
 
-/* Cached time */
-#ifdef TIME_IS_FAST
-#define approx_time() time(NULL)
-#define update_approx_time(t) STMT_NIL
-#else
-time_t approx_time(void);
-void update_approx_time(time_t now);
-#endif /* defined(TIME_IS_FAST) */
-
 /* Rate-limiter */
 
 /** A ratelim_t remembers how often an event is occurring, and how often

+ 1 - 0
src/include.am

@@ -11,6 +11,7 @@ include src/lib/malloc/include.am
 include src/lib/testsupport/include.am
 include src/lib/tls/include.am
 include src/lib/trace/include.am
+include src/lib/wallclock/include.am
 include src/common/include.am
 include src/trunnel/include.am
 include src/or/include.am

+ 4 - 0
src/lib/wallclock/.may_include

@@ -0,0 +1,4 @@
+orconfig.h
+lib/err/*.h
+lib/wallclock/*.h
+lib/testsupport/*.h

+ 38 - 0
src/lib/wallclock/approx_time.c

@@ -0,0 +1,38 @@
+/* Copyright (c) 2003, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "lib/wallclock/approx_time.h"
+
+/* =====
+ * Cached time
+ * ===== */
+
+#ifndef TIME_IS_FAST
+/** Cached estimate of the current time.  Updated around once per second;
+ * may be a few seconds off if we are really busy.  This is a hack to avoid
+ * calling time(NULL) (which not everybody has optimized) on critical paths.
+ */
+static time_t cached_approx_time = 0;
+
+/** Return a cached estimate of the current time from when
+ * update_approx_time() was last called.  This is a hack to avoid calling
+ * time(NULL) on critical paths: please do not even think of calling it
+ * anywhere else. */
+time_t
+approx_time(void)
+{
+  return cached_approx_time;
+}
+
+/** Update the cached estimate of the current time.  This function SHOULD be
+ * called once per second, and MUST be called before the first call to
+ * get_approx_time. */
+void
+update_approx_time(time_t now)
+{
+  cached_approx_time = now;
+}
+#endif /* !defined(TIME_IS_FAST) */

+ 20 - 0
src/lib/wallclock/approx_time.h

@@ -0,0 +1,20 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_APPROX_TIME_H
+#define TOR_APPROX_TIME_H
+
+#include <time.h>
+
+/* Cached time */
+#ifdef TIME_IS_FAST
+#define approx_time() time(NULL)
+#define update_approx_time(t) STMT_NIL
+#else
+time_t approx_time(void);
+void update_approx_time(time_t now);
+#endif /* defined(TIME_IS_FAST) */
+
+#endif

+ 19 - 0
src/lib/wallclock/include.am

@@ -0,0 +1,19 @@
+
+noinst_LIBRARIES += src/lib/libtor-wallclock.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-wallclock-testing.a
+endif
+
+src_lib_libtor_wallclock_a_SOURCES =			\
+	src/lib/wallclock/approx_time.c			\
+	src/lib/wallclock/tor_gettimeofday.c
+
+src_lib_libtor_wallclock_testing_a_SOURCES = \
+	$(src_lib_libtor_wallclock_a_SOURCES)
+src_lib_libtor_wallclock_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_wallclock_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS +=					\
+	src/lib/wallclock/approx_time.h			\
+	src/lib/wallclock/tor_gettimeofday.h

+ 82 - 0
src/lib/wallclock/tor_gettimeofday.c

@@ -0,0 +1,82 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file compat_time.c
+ * \brief Portable wrappers for finding out the current time, running
+ *   timers, etc.
+ **/
+
+#include "orconfig.h"
+#include "lib/err/torerr.h"
+#include "lib/wallclock/tor_gettimeofday.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifndef HAVE_GETTIMEOFDAY
+#ifdef HAVE_FTIME
+#include <sys/timeb.h>
+#endif
+#endif
+
+/** Set *timeval to the current time of day.  On error, log and terminate.
+ * (Same as gettimeofday(timeval,NULL), but never returns -1.)
+ */
+MOCK_IMPL(void,
+tor_gettimeofday, (struct timeval *timeval))
+{
+#ifdef _WIN32
+  /* Epoch bias copied from perl: number of units between windows epoch and
+   * Unix epoch. */
+#define EPOCH_BIAS U64_LITERAL(116444736000000000)
+#define UNITS_PER_SEC U64_LITERAL(10000000)
+#define USEC_PER_SEC U64_LITERAL(1000000)
+#define UNITS_PER_USEC U64_LITERAL(10)
+  union {
+    uint64_t ft_64;
+    FILETIME ft_ft;
+  } ft;
+  /* number of 100-nsec units since Jan 1, 1601 */
+  GetSystemTimeAsFileTime(&ft.ft_ft);
+  if (ft.ft_64 < EPOCH_BIAS) {
+    /* LCOV_EXCL_START */
+    log_err(LD_GENERAL,"System time is before 1970; failing.");
+    exit(1); // exit ok: system clock is broken.
+    /* LCOV_EXCL_STOP */
+  }
+  ft.ft_64 -= EPOCH_BIAS;
+  timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
+  timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
+#elif defined(HAVE_GETTIMEOFDAY)
+  if (gettimeofday(timeval, NULL)) {
+    /* LCOV_EXCL_START */
+    /* If gettimeofday dies, we have either given a bad timezone (we didn't),
+       or segfaulted.*/
+    raw_assert_unreached_msg("gettimeofday failed");
+    /* LCOV_EXCL_STOP */
+  }
+#elif defined(HAVE_FTIME)
+  struct timeb tb;
+  ftime(&tb);
+  timeval->tv_sec = tb.time;
+  timeval->tv_usec = tb.millitm * 1000;
+#else
+#error "No way to get time."
+#endif /* defined(_WIN32) || ... */
+  return;
+}

+ 15 - 0
src/lib/wallclock/tor_gettimeofday.h

@@ -0,0 +1,15 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_GETTIMEOFDAY_H
+#define TOR_GETTIMEOFDAY_H
+
+#include "lib/testsupport/testsupport.h"
+
+struct timeval;
+
+MOCK_DECL(void, tor_gettimeofday, (struct timeval *timeval));
+
+#endif