85 lines
3.4 KiB
Diff
85 lines
3.4 KiB
Diff
From c5b5c6b8cbf326031ef2de87a2268ecb10a3a44c Mon Sep 17 00:00:00 2001
|
|
From: Michal Schmidt <mschmidt@redhat.com>
|
|
Date: Wed, 10 Sep 2014 19:13:40 +0200
|
|
Subject: [PATCH] timesyncd: check root distance
|
|
|
|
Upstream commit:
|
|
commit 3af0442c52090f34ae7a1c8e6b6587c540c06896
|
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
Date: Wed Aug 27 16:47:20 2014 +0200
|
|
|
|
timesyncd: check root distance
|
|
|
|
NTPv4 servers don't reply with unsynchronized status when they lost
|
|
synchronization, they only keep increasing the root dispersion and it's
|
|
up to the client to decide at which point they no longer consider it
|
|
synchronized.
|
|
|
|
Ignore replies with root distance over 5 seconds.
|
|
---
|
|
src/timesync/timesyncd.c | 16 ++++++++++++++++
|
|
1 file changed, 16 insertions(+)
|
|
|
|
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
|
|
index 436aeaea56..5187df58c2 100644
|
|
--- a/src/timesync/timesyncd.c
|
|
+++ b/src/timesync/timesyncd.c
|
|
@@ -91,6 +91,9 @@
|
|
#define NTP_FIELD_MODE(f) ((f) & 7)
|
|
#define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
|
|
|
|
+/* Maximum acceptable root distance in seconds. */
|
|
+#define NTP_MAX_ROOT_DISTANCE 5.0
|
|
+
|
|
/*
|
|
* "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
|
|
* in seconds relative to 0h on 1 January 1900."
|
|
@@ -136,6 +139,10 @@ static int manager_clock_watch_setup(Manager *m);
|
|
static int manager_connect(Manager *m);
|
|
static void manager_disconnect(Manager *m);
|
|
|
|
+static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) {
|
|
+ return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0);
|
|
+}
|
|
+
|
|
static double ntp_ts_to_d(const struct ntp_ts *ts) {
|
|
return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
|
|
}
|
|
@@ -565,6 +572,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
|
ssize_t len;
|
|
double origin, receive, trans, dest;
|
|
double delay, offset;
|
|
+ double root_distance;
|
|
bool spike;
|
|
int leap_sec;
|
|
int r;
|
|
@@ -650,6 +658,12 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
|
return manager_connect(m);
|
|
}
|
|
|
|
+ root_distance = ntp_ts_short_to_d(&ntpmsg.root_delay) / 2 + ntp_ts_short_to_d(&ntpmsg.root_dispersion);
|
|
+ if (root_distance > NTP_MAX_ROOT_DISTANCE) {
|
|
+ log_debug("Server has too large root distance. Disconnecting.");
|
|
+ return manager_connect(m);
|
|
+ }
|
|
+
|
|
/* valid packet */
|
|
m->pending = false;
|
|
m->retry_interval = 0;
|
|
@@ -691,6 +705,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
|
" mode : %u\n"
|
|
" stratum : %u\n"
|
|
" precision : %.6f sec (%d)\n"
|
|
+ " root distance: %.6f sec\n"
|
|
" reference : %.4s\n"
|
|
" origin : %.3f\n"
|
|
" receive : %.3f\n"
|
|
@@ -706,6 +721,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
|
NTP_FIELD_MODE(ntpmsg.field),
|
|
ntpmsg.stratum,
|
|
exp2(ntpmsg.precision), ntpmsg.precision,
|
|
+ root_distance,
|
|
ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
|
|
origin - OFFSET_1900_1970,
|
|
receive - OFFSET_1900_1970,
|