]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
clientlog: save source of transmit timestamps
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 16 Mar 2023 15:51:12 +0000 (16:51 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 22 Mar 2023 08:42:06 +0000 (09:42 +0100)
Add the timestamp source to the data kept for clients using interleaved
mode to allow extending server statistics.

clientlog.c
clientlog.h
ntp.h
ntp_core.c
ntp_core.h
test/unit/clientlog.c

index adf0c59ba223c1603bfdd925ec62969dad727e1a..a6b199e72783b2527749d37084f73e39b78b702c 100644 (file)
@@ -126,7 +126,8 @@ static int active;
 /* RX and TX timestamp saved for clients using interleaved mode */
 typedef struct {
   uint64_t rx_ts;
-  uint16_t flags;
+  uint8_t flags;
+  uint8_t tx_ts_source;
   uint16_t slew_epoch;
   int32_t tx_ts_offset;
 } NtpTimestamps;
@@ -155,6 +156,9 @@ static NtpTimestampMap ntp_ts_map;
 /* Maximum number of timestamps moved in the array to insert a new timestamp */
 #define NTPTS_INSERT_LIMIT 64
 
+/* Maximum expected value of the timestamp source */
+#define MAX_NTP_TS NTP_TS_HARDWARE
+
 /* Global statistics */
 static uint32_t total_hits[MAX_SERVICES];
 static uint32_t total_drops[MAX_SERVICES];
@@ -773,7 +777,8 @@ push_ntp_tss(uint32_t index)
 /* ================================================== */
 
 static void
-set_ntp_tx_offset(NtpTimestamps *tss, NTP_int64 *rx_ts, struct timespec *tx_ts)
+set_ntp_tx(NtpTimestamps *tss, NTP_int64 *rx_ts, struct timespec *tx_ts,
+           NTP_Timestamp_Source tx_src)
 {
   struct timespec ts;
 
@@ -792,12 +797,13 @@ set_ntp_tx_offset(NtpTimestamps *tss, NTP_int64 *rx_ts, struct timespec *tx_ts)
 
   tss->tx_ts_offset = (int32_t)ts.tv_nsec + (int32_t)ts.tv_sec * (int32_t)NSEC_PER_SEC;
   tss->flags |= NTPTS_VALID_TX;
+  tss->tx_ts_source = tx_src;
 }
 
 /* ================================================== */
 
 static void
-get_ntp_tx(NtpTimestamps *tss, struct timespec *tx_ts)
+get_ntp_tx(NtpTimestamps *tss, struct timespec *tx_ts, NTP_Timestamp_Source *tx_src)
 {
   int32_t offset = tss->tx_ts_offset;
   NTP_int64 ntp_ts;
@@ -814,12 +820,14 @@ get_ntp_tx(NtpTimestamps *tss, struct timespec *tx_ts)
   } else {
     UTI_ZeroTimespec(tx_ts);
   }
+
+  *tx_src = tss->tx_ts_source;
 }
 
 /* ================================================== */
 
 void
-CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts)
+CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts, NTP_Timestamp_Source tx_src)
 {
   NtpTimestamps *tss;
   uint32_t i, index;
@@ -877,7 +885,7 @@ CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts)
   tss->rx_ts = rx;
   tss->flags = 0;
   tss->slew_epoch = ntp_ts_map.slew_epoch;
-  set_ntp_tx_offset(tss, rx_ts, tx_ts);
+  set_ntp_tx(tss, rx_ts, tx_ts, tx_src);
 
   DEBUG_LOG("Saved RX+TX index=%"PRIu32" first=%"PRIu32" size=%"PRIu32,
             index, ntp_ts_map.first, ntp_ts_map.size);
@@ -921,7 +929,8 @@ CLG_UndoNtpTxTimestampSlew(NTP_int64 *rx_ts, struct timespec *tx_ts)
 /* ================================================== */
 
 void
-CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
+CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts,
+                         NTP_Timestamp_Source tx_src)
 {
   uint32_t index;
 
@@ -931,13 +940,14 @@ CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
   if (!find_ntp_rx_ts(ntp64_to_int64(rx_ts), &index))
     return;
 
-  set_ntp_tx_offset(get_ntp_tss(index), rx_ts, tx_ts);
+  set_ntp_tx(get_ntp_tss(index), rx_ts, tx_ts, tx_src);
 }
 
 /* ================================================== */
 
 int
-CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
+CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts,
+                      NTP_Timestamp_Source *tx_src)
 {
   NtpTimestamps *tss;
   uint32_t index;
@@ -953,7 +963,7 @@ CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
   if (tss->flags & NTPTS_DISABLED)
     return 0;
 
-  get_ntp_tx(tss, tx_ts);
+  get_ntp_tx(tss, tx_ts, tx_src);
 
   return 1;
 }
index 2a5565e02d99ba97291a9e5ff07c1c6461f787a7..f7d8a4827beb5f61a471ae1e2ea667717353f2b4 100644 (file)
@@ -46,10 +46,13 @@ extern void CLG_LogAuthNtpRequest(void);
 extern int CLG_GetNtpMinPoll(void);
 
 /* Functions to save and retrieve timestamps for server interleaved mode */
-extern void CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts);
+extern void CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts,
+                                  NTP_Timestamp_Source tx_src);
 extern void CLG_UndoNtpTxTimestampSlew(NTP_int64 *rx_ts, struct timespec *tx_ts);
-extern void CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts);
-extern int CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts);
+extern void CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts,
+                                     NTP_Timestamp_Source tx_src);
+extern int CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts,
+                                 NTP_Timestamp_Source *tx_src);
 extern void CLG_DisableNtpTimestamps(NTP_int64 *rx_ts);
 
 /* And some reporting functions, for use by chronyc. */
diff --git a/ntp.h b/ntp.h
index 52b2ab579562a12a586d5d1e5e9d481a7a0e79aa..906adc387e9ace83bdbf3ac9ab9a962c76470208 100644 (file)
--- a/ntp.h
+++ b/ntp.h
@@ -179,4 +179,11 @@ typedef struct {
   double root_dispersion;
 } NTP_Sample;
 
+/* Possible sources of timestamps */
+typedef enum {
+  NTP_TS_DAEMON = 0,
+  NTP_TS_KERNEL,
+  NTP_TS_HARDWARE
+} NTP_Timestamp_Source;
+
 #endif /* GOT_NTP_H */
index 57bda81997d00b83b5ca257b2def5b4e05b0d3eb..05eab948a02ee680a72ab8c3651cc2a69af414e0 100644 (file)
@@ -2477,7 +2477,8 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
     ntp_rx = message->originate_ts;
     local_ntp_rx = &ntp_rx;
     UTI_ZeroTimespec(&local_tx.ts);
-    interleaved = CLG_GetNtpTxTimestamp(&ntp_rx, &local_tx.ts);
+    local_tx.source = NTP_TS_DAEMON;
+    interleaved = CLG_GetNtpTxTimestamp(&ntp_rx, &local_tx.ts, &local_tx.source);
 
     tx_ts = &local_tx;
     if (interleaved)
@@ -2500,7 +2501,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
     return;
 
   if (local_ntp_rx)
-    CLG_SaveNtpTimestamps(local_ntp_rx, &tx_ts->ts);
+    CLG_SaveNtpTimestamps(local_ntp_rx, &tx_ts->ts, tx_ts->source);
 }
 
 /* ================================================== */
@@ -2578,7 +2579,7 @@ NCR_ProcessTxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
   local_ntp_rx = &message->receive_ts;
   new_tx = *tx_ts;
 
-  if (!CLG_GetNtpTxTimestamp(local_ntp_rx, &old_tx.ts))
+  if (!CLG_GetNtpTxTimestamp(local_ntp_rx, &old_tx.ts, &old_tx.source))
     return;
 
   /* Undo a clock adjustment between the RX and TX timestamps to minimise error
@@ -2587,7 +2588,7 @@ NCR_ProcessTxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
 
   update_tx_timestamp(&old_tx, &new_tx, local_ntp_rx, NULL, message);
 
-  CLG_UpdateNtpTxTimestamp(local_ntp_rx, &new_tx.ts);
+  CLG_UpdateNtpTxTimestamp(local_ntp_rx, &new_tx.ts, new_tx.source);
 }
 
 /* ================================================== */
index 33f2bb8d47fe4ff182f6737296b1972b51201d8e..a3c554688a4c84c81695d24fce3bd91bd612536b 100644 (file)
@@ -38,12 +38,6 @@ typedef enum {
   NTP_SERVER, NTP_PEER
 } NTP_Source_Type;
 
-typedef enum {
-  NTP_TS_DAEMON = 0,
-  NTP_TS_KERNEL,
-  NTP_TS_HARDWARE
-} NTP_Timestamp_Source;
-
 typedef struct {
   struct timespec ts;
   double err;
index f59e13040a738f4570d49550ed990eb03a0195e5..e5bf1f4b6eacd58cbb0ca992d625e0a883e2e25b 100644 (file)
@@ -36,6 +36,7 @@ test_unit(void)
 {
   uint64_t ts64, prev_first_ts64, prev_last_ts64, max_step;
   uint32_t index2, prev_first, prev_size;
+  NTP_Timestamp_Source ts_src, ts_src2;
   struct timespec ts, ts2;
   int i, j, k, index, shift;
   CLG_Service s;
@@ -95,7 +96,7 @@ test_unit(void)
   TEST_CHECK(!ntp_ts_map.timestamps);
 
   UTI_ZeroNtp64(&ntp_ts);
-  CLG_SaveNtpTimestamps(&ntp_ts, NULL);
+  CLG_SaveNtpTimestamps(&ntp_ts, NULL, 0);
   TEST_CHECK(ntp_ts_map.timestamps);
   TEST_CHECK(ntp_ts_map.first == 0);
   TEST_CHECK(ntp_ts_map.size == 0);
@@ -132,8 +133,10 @@ test_unit(void)
         UTI_ZeroTimespec(&ts);
       }
 
+      ts_src = random() % (MAX_NTP_TS + 1);
       CLG_SaveNtpTimestamps(&ntp_ts,
-                            UTI_IsZeroTimespec(&ts) ? (random() % 2 ? &ts : NULL) : &ts);
+                            UTI_IsZeroTimespec(&ts) ? (random() % 2 ? &ts : NULL) : &ts,
+                            ts_src);
 
       if (j < ntp_ts_map.max_size) {
         TEST_CHECK(ntp_ts_map.size == j + 1);
@@ -144,14 +147,15 @@ test_unit(void)
       }
       TEST_CHECK(ntp_ts_map.cached_index == ntp_ts_map.size - 1);
       TEST_CHECK(get_ntp_tss(ntp_ts_map.size - 1)->slew_epoch == ntp_ts_map.slew_epoch);
-      TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts2));
+      TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts2, &ts_src2));
       TEST_CHECK(UTI_CompareTimespecs(&ts, &ts2) == 0);
+      TEST_CHECK(UTI_IsZeroTimespec(&ts) || ts_src == ts_src2);
 
       for (k = random() % 4; k > 0; k--) {
         index2 = random() % ntp_ts_map.size;
         int64_to_ntp64(get_ntp_tss(index2)->rx_ts, &ntp_ts);
         if (random() % 2)
-          TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
+          TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
 
         UTI_Ntp64ToTimespec(&ntp_ts, &ts);
         UTI_AddDoubleToTimespec(&ts, TST_GetRandomDouble(-1.999, 1.999), &ts);
@@ -165,10 +169,12 @@ test_unit(void)
                      1.0e-9);
         }
 
-        CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts);
+        ts_src = random() % (MAX_NTP_TS + 1);
+        CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts, ts_src);
 
-        TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts2));
+        TEST_CHECK(CLG_GetNtpTxTimestamp(&ntp_ts, &ts2, &ts_src2));
         TEST_CHECK(UTI_CompareTimespecs(&ts, &ts2) == 0);
+        TEST_CHECK(ts_src == ts_src2);
 
         if (random() % 2) {
           uint16_t prev_epoch = ntp_ts_map.slew_epoch;
@@ -181,20 +187,20 @@ test_unit(void)
           index = random() % (ntp_ts_map.size - 1);
           if (get_ntp_tss(index)->rx_ts + 1 != get_ntp_tss(index + 1)->rx_ts) {
             int64_to_ntp64(get_ntp_tss(index)->rx_ts + 1, &ntp_ts);
-            TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
+            TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
             int64_to_ntp64(get_ntp_tss(index + 1)->rx_ts - 1, &ntp_ts);
-            TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
-            CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts);
+            TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
+            CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts, ts_src);
             CLG_UndoNtpTxTimestampSlew(&ntp_ts, &ts);
           }
         }
 
         if (random() % 2) {
           int64_to_ntp64(get_ntp_tss(0)->rx_ts - 1, &ntp_ts);
-          TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
+          TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
           int64_to_ntp64(get_ntp_tss(ntp_ts_map.size - 1)->rx_ts + 1, &ntp_ts);
-          TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
-          CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts);
+          TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
+          CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts, ts_src);
           CLG_UndoNtpTxTimestampSlew(&ntp_ts, &ts);
         }
       }
@@ -207,7 +213,7 @@ test_unit(void)
         while (ntp_ts_map.size < ntp_ts_map.max_size) {
           ts64 += get_random64() >> (shift + 8);
           int64_to_ntp64(ts64, &ntp_ts);
-          CLG_SaveNtpTimestamps(&ntp_ts, NULL);
+          CLG_SaveNtpTimestamps(&ntp_ts, NULL, 0);
           if (ntp_ts_map.cached_index + NTPTS_INSERT_LIMIT < ntp_ts_map.size)
             ts64 = get_ntp_tss(ntp_ts_map.size - 1)->rx_ts;
         }
@@ -228,7 +234,7 @@ test_unit(void)
       prev_size = ntp_ts_map.size;
       prev_first_ts64 = get_ntp_tss(0)->rx_ts;
       prev_last_ts64 = get_ntp_tss(prev_size - 1)->rx_ts;
-      CLG_SaveNtpTimestamps(&ntp_ts, NULL);
+      CLG_SaveNtpTimestamps(&ntp_ts, NULL, 0);
 
       TEST_CHECK(find_ntp_rx_ts(ts64, &index2));
 
@@ -259,13 +265,13 @@ test_unit(void)
 
       if (random() % 10 == 0) {
         CLG_DisableNtpTimestamps(&ntp_ts);
-        TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
+        TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
       }
 
       for (k = random() % 10; k > 0; k--) {
         ts64 = get_random64() >> shift;
         int64_to_ntp64(ts64, &ntp_ts);
-        CLG_GetNtpTxTimestamp(&ntp_ts, &ts);
+        CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2);
       }
     }
 
@@ -274,8 +280,8 @@ test_unit(void)
                   LCL_ChangeUnknownStep, NULL);
       TEST_CHECK(ntp_ts_map.size == 0);
       TEST_CHECK(ntp_ts_map.cached_rx_ts == 0ULL);
-      TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts));
-      CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts);
+      TEST_CHECK(!CLG_GetNtpTxTimestamp(&ntp_ts, &ts, &ts_src2));
+      CLG_UpdateNtpTxTimestamp(&ntp_ts, &ts, ts_src);
     }
   }