[systemd-commits] 4 commits - src/timesync

Kay Sievers kay at kemper.freedesktop.org
Fri Aug 29 09:23:51 PDT 2014


 src/timesync/timesyncd-manager.c |   37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

New commits:
commit 3af0442c52090f34ae7a1c8e6b6587c540c06896
Author: Miroslav Lichvar <mlichvar at 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.

diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 2b0580c..9b8b7d3 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,

commit 487a36821ea214a73e1d0dcbd6d84123b50d1135
Author: Miroslav Lichvar <mlichvar at redhat.com>
Date:   Wed Aug 27 16:47:19 2014 +0200

    timesyncd: get kernel timestamp in nanoseconds

diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 3339606..2b0580c 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -136,10 +136,6 @@ static double ts_to_d(const struct timespec *ts) {
         return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
 }
 
-static double tv_to_d(const struct timeval *tv) {
-        return tv->tv_sec + (1.0e-6 * tv->tv_usec);
-}
-
 static double square(double d) {
         return d * d;
 }
@@ -500,7 +496,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 .msg_namelen = sizeof(server_addr),
         };
         struct cmsghdr *cmsg;
-        struct timeval *recv_time;
+        struct timespec *recv_time;
         ssize_t len;
         double origin, receive, trans, dest;
         double delay, offset;
@@ -543,8 +539,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                         continue;
 
                 switch (cmsg->cmsg_type) {
-                case SCM_TIMESTAMP:
-                        recv_time = (struct timeval *) CMSG_DATA(cmsg);
+                case SCM_TIMESTAMPNS:
+                        recv_time = (struct timespec *) CMSG_DATA(cmsg);
                         break;
                 }
         }
@@ -615,7 +611,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
         origin = ts_to_d(&m->trans_time) + OFFSET_1900_1970;
         receive = ntp_ts_to_d(&ntpmsg.recv_time);
         trans = ntp_ts_to_d(&ntpmsg.trans_time);
-        dest = tv_to_d(recv_time) + OFFSET_1900_1970;
+        dest = ts_to_d(recv_time) + OFFSET_1900_1970;
 
         offset = ((receive - origin) + (trans - dest)) / 2;
         delay = (dest - origin) - (trans - receive);
@@ -697,7 +693,7 @@ static int manager_listen_setup(Manager *m) {
         if (r < 0)
                 return -errno;
 
-        r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
+        r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMPNS, &on, sizeof(on));
         if (r < 0)
                 return -errno;
 

commit 73c76e6330d31e1d04454fd7408dd56b4eedca9f
Author: Miroslav Lichvar <mlichvar at redhat.com>
Date:   Wed Aug 27 16:47:18 2014 +0200

    timesyncd: fix calculation of transmit time
    
    The kernel timestamp (recv_time) is made earlier than current time
    (now_ts), use the timestamp captured before sending packet directly.

diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 60f39c6..3339606 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -500,7 +500,6 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 .msg_namelen = sizeof(server_addr),
         };
         struct cmsghdr *cmsg;
-        struct timespec now_ts;
         struct timeval *recv_time;
         ssize_t len;
         double origin, receive, trans, dest;
@@ -613,8 +612,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
          *  The round-trip delay, d, and system clock offset, t, are defined as:
          *  d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2"
          */
-        assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
-        origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
+        origin = ts_to_d(&m->trans_time) + OFFSET_1900_1970;
         receive = ntp_ts_to_d(&ntpmsg.recv_time);
         trans = ntp_ts_to_d(&ntpmsg.trans_time);
         dest = tv_to_d(recv_time) + OFFSET_1900_1970;

commit 07610e108e2d3f046da683a3a69c4d5cccd2cf8e
Author: Miroslav Lichvar <mlichvar at redhat.com>
Date:   Wed Aug 27 16:47:17 2014 +0200

    timesyncd: check if stratum is valid

diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index d80c72f..60f39c6 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -574,7 +574,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 return manager_connect(m);
         }
 
-        if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
+        if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC ||
+            ntpmsg.stratum == 0 || ntpmsg.stratum >= 16) {
                 log_debug("Server is not synchronized. Disconnecting.");
                 return manager_connect(m);
         }



More information about the systemd-commits mailing list