mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Extract our code for answering "what time is it right now".
The other time stuff is higher-level
This commit is contained in:
parent
d1cada5a8a
commit
9426751b72
2
.gitignore
vendored
2
.gitignore
vendored
@ -178,6 +178,8 @@ uptime-*.json
|
|||||||
/src/lib/libtor-tls.a
|
/src/lib/libtor-tls.a
|
||||||
/src/lib/libtor-tls-testing.a
|
/src/lib/libtor-tls-testing.a
|
||||||
/src/lib/libtor-trace.a
|
/src/lib/libtor-trace.a
|
||||||
|
/src/lib/libtor-wallclock.a
|
||||||
|
/src/lib/libtor-wallclock-testing.a
|
||||||
|
|
||||||
# /src/or/
|
# /src/or/
|
||||||
/src/or/Makefile
|
/src/or/Makefile
|
||||||
|
@ -42,6 +42,7 @@ TOR_UTIL_LIBS = \
|
|||||||
src/common/libor.a \
|
src/common/libor.a \
|
||||||
src/lib/libtor-container.a \
|
src/lib/libtor-container.a \
|
||||||
src/lib/libtor-malloc.a \
|
src/lib/libtor-malloc.a \
|
||||||
|
src/lib/libtor-wallclock.a \
|
||||||
src/lib/libtor-err.a \
|
src/lib/libtor-err.a \
|
||||||
src/lib/libtor-ctime.a
|
src/lib/libtor-ctime.a
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ TOR_UTIL_TESTING_LIBS = \
|
|||||||
src/common/libor-testing.a \
|
src/common/libor-testing.a \
|
||||||
src/lib/libtor-container-testing.a \
|
src/lib/libtor-container-testing.a \
|
||||||
src/lib/libtor-malloc-testing.a \
|
src/lib/libtor-malloc-testing.a \
|
||||||
|
src/lib/libtor-wallclock-testing.a \
|
||||||
src/lib/libtor-err-testing.a \
|
src/lib/libtor-err-testing.a \
|
||||||
src/lib/libtor-ctime-testing.a
|
src/lib/libtor-ctime-testing.a
|
||||||
|
|
||||||
|
@ -38,12 +38,6 @@
|
|||||||
#include "common/torlog.h"
|
#include "common/torlog.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
#ifndef HAVE_GETTIMEOFDAY
|
|
||||||
#ifdef HAVE_FTIME
|
|
||||||
#include <sys/timeb.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#undef HAVE_CLOCK_GETTIME
|
#undef HAVE_CLOCK_GETTIME
|
||||||
#endif
|
#endif
|
||||||
@ -68,53 +62,6 @@ tor_sleep_msec(int msec)
|
|||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#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_MILLION ((int64_t) (1000 * 1000))
|
||||||
#define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
|
#define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#define TOR_COMPAT_TIME_H
|
#define TOR_COMPAT_TIME_H
|
||||||
|
|
||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
|
#include "lib/wallclock/tor_gettimeofday.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#undef HAVE_CLOCK_GETTIME
|
#undef HAVE_CLOCK_GETTIME
|
||||||
#endif
|
#endif
|
||||||
@ -200,8 +202,6 @@ monotime_coarse_diff_msec32(const monotime_coarse_t *start,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_DECL(void, tor_gettimeofday, (struct timeval *timeval));
|
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
void tor_sleep_msec(int msec);
|
void tor_sleep_msec(int msec);
|
||||||
|
|
||||||
@ -230,4 +230,3 @@ void monotime_reset_ratchets_for_testing(void);
|
|||||||
#endif /* defined(COMPAT_TIME_PRIVATE) */
|
#endif /* defined(COMPAT_TIME_PRIVATE) */
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_TIME_H) */
|
#endif /* !defined(TOR_COMPAT_TIME_H) */
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#include "common/torlog.h"
|
#include "common/torlog.h"
|
||||||
#include "lib/container/smartlist.h"
|
#include "lib/container/smartlist.h"
|
||||||
#include "lib/err/torerr.h"
|
#include "lib/err/torerr.h"
|
||||||
|
#include "lib/wallclock/tor_gettimeofday.h"
|
||||||
|
#include "lib/wallclock/approx_time.h"
|
||||||
|
|
||||||
#ifdef HAVE_ANDROID_LOG_H
|
#ifdef HAVE_ANDROID_LOG_H
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
@ -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
|
* Rate limiting
|
||||||
* ===== */
|
* ===== */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "lib/err/torerr.h"
|
#include "lib/err/torerr.h"
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
|
#include "lib/wallclock/approx_time.h"
|
||||||
#include "common/util_bug.h"
|
#include "common/util_bug.h"
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#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 parse_http_time(const char *buf, struct tm *tm);
|
||||||
int format_time_interval(char *out, size_t out_len, long interval);
|
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 */
|
/* Rate-limiter */
|
||||||
|
|
||||||
/** A ratelim_t remembers how often an event is occurring, and how often
|
/** A ratelim_t remembers how often an event is occurring, and how often
|
||||||
|
@ -11,6 +11,7 @@ include src/lib/malloc/include.am
|
|||||||
include src/lib/testsupport/include.am
|
include src/lib/testsupport/include.am
|
||||||
include src/lib/tls/include.am
|
include src/lib/tls/include.am
|
||||||
include src/lib/trace/include.am
|
include src/lib/trace/include.am
|
||||||
|
include src/lib/wallclock/include.am
|
||||||
include src/common/include.am
|
include src/common/include.am
|
||||||
include src/trunnel/include.am
|
include src/trunnel/include.am
|
||||||
include src/or/include.am
|
include src/or/include.am
|
||||||
|
4
src/lib/wallclock/.may_include
Normal file
4
src/lib/wallclock/.may_include
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
orconfig.h
|
||||||
|
lib/err/*.h
|
||||||
|
lib/wallclock/*.h
|
||||||
|
lib/testsupport/*.h
|
38
src/lib/wallclock/approx_time.c
Normal file
38
src/lib/wallclock/approx_time.c
Normal file
@ -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
src/lib/wallclock/approx_time.h
Normal file
20
src/lib/wallclock/approx_time.h
Normal file
@ -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
src/lib/wallclock/include.am
Normal file
19
src/lib/wallclock/include.am
Normal file
@ -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
src/lib/wallclock/tor_gettimeofday.c
Normal file
82
src/lib/wallclock/tor_gettimeofday.c
Normal file
@ -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
src/lib/wallclock/tor_gettimeofday.h
Normal file
15
src/lib/wallclock/tor_gettimeofday.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user