mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-23 20:03: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-testing.a
|
||||
/src/lib/libtor-trace.a
|
||||
/src/lib/libtor-wallclock.a
|
||||
/src/lib/libtor-wallclock-testing.a
|
||||
|
||||
# /src/or/
|
||||
/src/or/Makefile
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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) */
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
* ===== */
|
||||
|
@ -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
|
||||
|
@ -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
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