util: add support for other NTP eras
NTP timestamps use only 32 bits to count seconds and the current NTP era ends in 2036. Add support for converting NTP timestamps from other NTP eras on systems with 64-bit time_t. The earliest assumed NTP time is set by the configure script (by default to 50 years before the date of the build) and earlier NTP timestamps underflow to the following NTP era.
This commit is contained in:
parent
cb88cea3c4
commit
474b2af1a6
3 changed files with 75 additions and 6 deletions
33
configure
vendored
33
configure
vendored
|
@ -114,6 +114,8 @@ For better control, use the options below.
|
|||
--disable-linuxcaps Disable Linux capabilities support
|
||||
--disable-asyncdns Disable asynchronous name resolving
|
||||
--disable-forcednsretry Don't retry on permanent DNS error
|
||||
--with-ntp-era=SECONDS Specify earliest assumed NTP time in seconds
|
||||
since 1970-01-01 [50*365 days ago]
|
||||
--with-user=USER Specify default chronyd user [root]
|
||||
--with-sendmail=PATH Path to sendmail binary [/usr/lib/sendmail]
|
||||
--enable-debug Enable debugging support
|
||||
|
@ -194,6 +196,7 @@ try_setsched=0
|
|||
try_lockmem=0
|
||||
feat_asyncdns=1
|
||||
feat_forcednsretry=1
|
||||
ntp_era_split=""
|
||||
default_user="root"
|
||||
mail_program="/usr/lib/sendmail"
|
||||
|
||||
|
@ -275,6 +278,9 @@ do
|
|||
--disable-forcednsretry)
|
||||
feat_forcednsretry=0
|
||||
;;
|
||||
--with-ntp-era=* )
|
||||
ntp_era_split=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--with-user=* )
|
||||
default_user=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
|
@ -381,6 +387,33 @@ if test_code '64-bit time_t' 'time.h' '' '' '
|
|||
return x[0];'
|
||||
then
|
||||
add_def HAVE_LONG_TIME_T 1
|
||||
|
||||
if [ "x$ntp_era_split" != "x" ]; then
|
||||
split_seconds=$ntp_era_split
|
||||
split_days=0
|
||||
else
|
||||
split_seconds=`date '+%s'`
|
||||
if [ "x$split_seconds" = "" ]; then
|
||||
echo "Could not get current time, --with-ntp-era option is needed"
|
||||
exit 1
|
||||
fi
|
||||
split_days=$((50 * 365))
|
||||
fi
|
||||
|
||||
add_def NTP_ERA_SPLIT "(${split_seconds}LL - $split_days * 24 * 3600)"
|
||||
|
||||
date_format='+%Y-%m-%dT%H:%M:%SZ'
|
||||
|
||||
# Print the full NTP interval if a suitable date is found
|
||||
if [ "x`date -u -d '1970-01-01 UTC 9 days ago 5 seconds 3 seconds' \
|
||||
$date_format 2> /dev/null`" = "x1969-12-23T00:00:08Z" ]
|
||||
then
|
||||
time1="`date -u -d "1970-01-01 UTC $split_days days ago $split_seconds seconds" \
|
||||
$date_format`"
|
||||
time2="`date -u -d "1970-01-01 UTC $split_days days ago $split_seconds seconds 4294967296 seconds" \
|
||||
$date_format`"
|
||||
echo "NTP time mapped to $time1/$time2"
|
||||
fi
|
||||
fi
|
||||
|
||||
MATHCODE='return (int) pow(2.0, log(sqrt((double)argc)));'
|
||||
|
|
25
ntp_core.c
25
ntp_core.c
|
@ -258,10 +258,35 @@ do_size_checks(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
do_time_checks(void)
|
||||
{
|
||||
#ifdef HAVE_LONG_TIME_T
|
||||
/* Check that time before NTP_ERA_SPLIT underflows correctly */
|
||||
|
||||
struct timeval tv1 = {NTP_ERA_SPLIT, 1}, tv2 = {NTP_ERA_SPLIT - 1, 1};
|
||||
NTP_int64 ntv1, ntv2;
|
||||
int r;
|
||||
|
||||
UTI_TimevalToInt64(&tv1, &ntv1, 0);
|
||||
UTI_TimevalToInt64(&tv2, &ntv2, 0);
|
||||
UTI_Int64ToTimeval(&ntv1, &tv1);
|
||||
UTI_Int64ToTimeval(&ntv2, &tv2);
|
||||
|
||||
r = tv1.tv_sec == NTP_ERA_SPLIT &&
|
||||
tv1.tv_sec + (1ULL << 32) - 1 == tv2.tv_sec;
|
||||
|
||||
assert(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NCR_Initialise(void)
|
||||
{
|
||||
do_size_checks();
|
||||
do_time_checks();
|
||||
|
||||
logfileid = CNF_GetLogMeasurements() ? LOG_FileOpen("measurements",
|
||||
" Date (UTC) Time IP Address L St 1234 abc 5678 LP RP Score Offset Peer del. Peer disp. Root del. Root disp.")
|
||||
|
|
23
util.c
23
util.c
|
@ -498,16 +498,17 @@ void
|
|||
UTI_TimevalToInt64(struct timeval *src,
|
||||
NTP_int64 *dest, uint32_t fuzz)
|
||||
{
|
||||
unsigned long usec = src->tv_usec;
|
||||
unsigned long sec = src->tv_sec;
|
||||
uint32_t lo;
|
||||
uint32_t lo, sec, usec;
|
||||
|
||||
sec = (uint32_t)src->tv_sec;
|
||||
usec = (uint32_t)src->tv_usec;
|
||||
|
||||
/* Recognize zero as a special case - it always signifies
|
||||
an 'unknown' value */
|
||||
if (!usec && !sec) {
|
||||
dest->hi = dest->lo = 0;
|
||||
} else {
|
||||
dest->hi = htonl(src->tv_sec + JAN_1970);
|
||||
dest->hi = htonl(sec + JAN_1970);
|
||||
|
||||
/* This formula gives an error of about 0.1us worst case */
|
||||
lo = 4295 * usec - (usec>>5) - (usec>>9);
|
||||
|
@ -525,13 +526,23 @@ void
|
|||
UTI_Int64ToTimeval(NTP_int64 *src,
|
||||
struct timeval *dest)
|
||||
{
|
||||
uint32_t ntp_sec, ntp_frac;
|
||||
|
||||
/* As yet, there is no need to check for zero - all processing that
|
||||
has to detect that case is in the NTP layer */
|
||||
|
||||
dest->tv_sec = ntohl(src->hi) - JAN_1970;
|
||||
ntp_sec = ntohl(src->hi);
|
||||
ntp_frac = ntohl(src->lo);
|
||||
|
||||
#ifdef HAVE_LONG_TIME_T
|
||||
dest->tv_sec = ntp_sec - (uint32_t)(NTP_ERA_SPLIT + JAN_1970) +
|
||||
(time_t)NTP_ERA_SPLIT;
|
||||
#else
|
||||
dest->tv_sec = ntp_sec - JAN_1970;
|
||||
#endif
|
||||
|
||||
/* Until I invent a slick way to do this, just do it the obvious way */
|
||||
dest->tv_usec = (int)(0.5 + (double)(ntohl(src->lo)) / 4294.967296);
|
||||
dest->tv_usec = (int)(0.5 + (double)(ntp_frac) / 4294.967296);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
Loading…
Reference in a new issue