78 lines
3.2 KiB
Diff
78 lines
3.2 KiB
Diff
From 3af0442c52090f34ae7a1c8e6b6587c540c06896 Mon Sep 17 00:00:00 2001
|
|
From: Miroslav Lichvar <mlichvar@redhat.com>
|
|
Date: Wed, 27 Aug 2014 16:47:20 +0200
|
|
Subject: [PATCH] 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-manager.c | 16 ++++++++++++++++
|
|
1 file changed, 16 insertions(+)
|
|
|
|
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
|
|
index 2b0580cf01..9b8b7d3eb6 100644
|
|
--- a/src/timesync/timesyncd-manager.c
|
|
+++ b/src/timesync/timesyncd-manager.c
|
|
@@ -89,6 +89,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."
|
|
@@ -128,6 +131,10 @@ struct ntp_msg {
|
|
static int manager_arm_timer(Manager *m, usec_t next);
|
|
static int manager_clock_watch_setup(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);
|
|
}
|
|
@@ -500,6 +507,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;
|
|
@@ -585,6 +593,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;
|
|
@@ -626,6 +640,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"
|
|
@@ -641,6 +656,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,
|