]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: get TX timestamp after authentication
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 2 Jul 2020 13:18:23 +0000 (15:18 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Jul 2020 12:46:53 +0000 (14:46 +0200)
If the daemon transmit timestamp is saved for processing of a future
response or responding in the interleaved mode, get a more accurate
timestamp right before calling NIO_SendPacket(). Avoid unnecessary
reading of the clock for the transmit timestamp in the packet (i.e.
in interleaved modes and client basic mode).

This should improve accuracy and stability when authentication is
enabled in the client and symmetric basic modes and also interleaved
modes if kernel/hardware timestamps are not available.

doc/chrony.conf.adoc
ntp_core.c

index 3d8a681fe31ac1f8ae9db1dd16f8899623877c7d..3901400b9c000ac29a9cc42a986dafc2fd8e38a7 100644 (file)
@@ -200,10 +200,11 @@ authenticated source to be safely combined with unauthenticated sources in
 order to improve the accuracy of the clock. They can be selected and used for
 synchronisation only if they agree with the trusted and required source.
 *xleave*:::
-This option enables an interleaved mode which enables the server to
-send transmit timestamps captured after the actual transmission (e.g. when the
-server is running *chronyd* with software (kernel) or hardware
-timestamping). This can significantly improve the accuracy of the measurements.
+This option enables the interleaved mode of NTP. It enables the server to
+respond with more accurate transmit timestamps (e.g. kernel or hardware
+timestamps), which cannot be contained in the transmitted packet itself and
+need to refer to a previous packet instead. This can significantly improve the
+accuracy and stability of the measurements.
 +
 The interleaved mode is compatible with servers that support only the basic
 mode. Note that even
index e71c93fb5837d3f7e9b775a3ed35ceb04dbe09b0..ecd5f25476c6e54c71da6ca797a03d451c94ea91 100644 (file)
@@ -961,6 +961,10 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
   smooth_time = 0;
   smooth_offset = 0.0;
 
+  /* Get an initial transmit timestamp.  A more accurate timestamp will be
+     taken later in this function. */
+  SCH_GetLastEventTime(&local_transmit, NULL, NULL);
+
   if (my_mode == MODE_CLIENT) {
     /* Don't reveal local time or state of the clock in client packets */
     precision = 32;
@@ -968,10 +972,6 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
     our_root_delay = our_root_dispersion = 0.0;
     UTI_ZeroTimespec(&our_ref_time);
   } else {
-    /* This is accurate enough and cheaper than calling LCL_ReadCookedTime.
-       A more accurate timestamp will be taken later in this function. */
-    SCH_GetLastEventTime(&local_transmit, NULL, NULL);
-
     REF_GetReferenceParams(&local_transmit,
                            &are_we_synchronised, &leap_status,
                            &our_stratum,
@@ -1062,20 +1062,20 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
     /* Prepare random bits which will be added to the transmit timestamp */
     UTI_GetNtp64Fuzz(&ts_fuzz, precision);
 
-    /* Transmit - this our local time right now!  Also, we might need to
-       store this for our own use later, next time we receive a message
-       from the source we're sending to now. */
-    LCL_ReadCookedTime(&local_transmit, &local_transmit_err);
-
-    if (smooth_time)
-      UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
-
-    /* Pre-compensate the transmit time by approximately how long it will take
-       to generate the authentication data */
-    if (auth)
-      NAU_AdjustRequestTimestamp(auth, &local_transmit);
-    else
-      NAU_AdjustResponseTimestamp(request, request_info, &local_transmit);
+    /* Get a more accurate transmit timestamp if it needs to be saved in the
+       packet (i.e. in the server, symmetric, and broadcast basic modes) */
+    if (!interleaved && precision < 32) {
+      LCL_ReadCookedTime(&local_transmit, &local_transmit_err);
+      if (smooth_time)
+        UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
+
+      /* Pre-compensate the transmit time by approximately how long it will
+         take to generate the authentication data */
+      if (auth)
+        NAU_AdjustRequestTimestamp(auth, &local_transmit);
+      else
+        NAU_AdjustResponseTimestamp(request, request_info, &local_transmit);
+    }
 
     UTI_TimespecToNtp64(interleaved ? &local_tx->ts : &local_transmit,
                         &message.transmit_ts, &ts_fuzz);
@@ -1111,9 +1111,16 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
     return 0;
   }
 
+  /* If the transmit timestamp will be saved, get an even more
+     accurate daemon timestamp closer to the transmission */
+  if (local_tx)
+    LCL_ReadCookedTime(&local_transmit, &local_transmit_err);
+
   ret = NIO_SendPacket(&message, where_to, from, info.length, local_tx != NULL);
 
   if (local_tx) {
+    if (smooth_time)
+      UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
     local_tx->ts = local_transmit;
     local_tx->err = local_transmit_err;
     local_tx->source = NTP_TS_DAEMON;