]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
util: add functions for zeroing and comparing NTP timestamps
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 24 Oct 2016 14:46:29 +0000 (16:46 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 10 Nov 2016 14:26:56 +0000 (15:26 +0100)
clientlog.c
ntp_core.c
util.c
util.h

index a9f2634e08c24ba2468b41d4efef33f45ec0ed3a..9dca9f13f6178060467d837e0d67c558e15e9881 100644 (file)
@@ -209,8 +209,8 @@ get_record(IPAddr *ip)
   record->ntp_rate = record->cmd_rate = INVALID_RATE;
   record->ntp_timeout_rate = INVALID_RATE;
   record->flags = 0;
-  record->ntp_rx_ts.hi = record->ntp_rx_ts.lo = 0;
-  record->ntp_tx_ts.hi = record->ntp_tx_ts.lo = 0;
+  UTI_ZeroNtp64(&record->ntp_rx_ts);
+  UTI_ZeroNtp64(&record->ntp_tx_ts);
 
   return record;
 }
index 2829ebbe0d999ea91f8d40aeb419d48705f1faff..066077a6ebc4467e73459c252b8ace759e23e1b1 100644 (file)
@@ -599,14 +599,10 @@ NCR_ResetInstance(NCR_Instance instance)
 
   instance->valid_rx = 0;
   instance->valid_timestamps = 0;
-  instance->remote_ntp_rx.hi = 0;
-  instance->remote_ntp_rx.lo = 0;
-  instance->remote_ntp_tx.hi = 0;
-  instance->remote_ntp_tx.lo = 0;
-  instance->local_ntp_rx.hi = 0;
-  instance->local_ntp_rx.lo = 0;
-  instance->local_ntp_tx.hi = 0;
-  instance->local_ntp_tx.lo = 0;
+  UTI_ZeroNtp64(&instance->remote_ntp_rx);
+  UTI_ZeroNtp64(&instance->remote_ntp_tx);
+  UTI_ZeroNtp64(&instance->local_ntp_rx);
+  UTI_ZeroNtp64(&instance->local_ntp_tx);
   UTI_ZeroTimespec(&instance->local_rx.ts);
   instance->local_rx.err = 0.0;
   instance->local_rx.source = NTP_TS_DAEMON;
@@ -1286,24 +1282,21 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
      The test values are 1 when passed and 0 when failed. */
   
   /* Test 1 checks for duplicate packet */
-  test1 = message->transmit_ts.hi != inst->remote_ntp_tx.hi ||
-          message->transmit_ts.lo != inst->remote_ntp_tx.lo;
+  test1 = !!UTI_CompareNtp64(&message->transmit_ts, &inst->remote_ntp_tx);
 
   /* Test 2 checks for bogus packet in the basic and interleaved modes.  This
      ensures the source is responding to the latest packet we sent to it. */
-  test2n = message->originate_ts.hi == inst->local_ntp_tx.hi &&
-           message->originate_ts.lo == inst->local_ntp_tx.lo;
+  test2n = !UTI_CompareNtp64(&message->originate_ts, &inst->local_ntp_tx);
   test2i = inst->interleaved &&
-           message->originate_ts.hi == inst->local_ntp_rx.hi &&
-           message->originate_ts.lo == inst->local_ntp_rx.lo;
+           !UTI_CompareNtp64(&message->originate_ts, &inst->local_ntp_rx);
   test2 = test2n || test2i;
   interleaved_packet = !test2n && test2i;
   
   /* Test 3 checks for invalid timestamps.  This can happen when the
      association if not properly 'up'. */
-  test3 = (message->originate_ts.hi || message->originate_ts.lo) &&
-          (message->receive_ts.hi || message->receive_ts.lo) &&
-          (message->transmit_ts.hi || message->transmit_ts.lo);
+  test3 = !UTI_IsZeroNtp64(&message->originate_ts) &&
+          !UTI_IsZeroNtp64(&message->receive_ts) &&
+          !UTI_IsZeroNtp64(&message->transmit_ts);
 
   /* Test 4 would check for denied access.  It would always pass as this
      function is called only for known sources. */
@@ -1817,18 +1810,17 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
      on clients that are not using the interleaved mode. */
   if (log_index >= 0) {
     CLG_GetNtpTimestamps(log_index, &local_ntp_rx, &local_ntp_tx);
-    interleaved = (local_ntp_rx->hi || local_ntp_rx->lo) &&
-                  message->originate_ts.hi == local_ntp_rx->hi &&
-                  message->originate_ts.lo == local_ntp_rx->lo;
+    interleaved = !UTI_IsZeroNtp64(local_ntp_rx) &&
+                  !UTI_CompareNtp64(&message->originate_ts, local_ntp_rx);
 
     if (interleaved) {
-      if (local_ntp_tx->hi || local_ntp_tx->lo)
+      if (!UTI_IsZeroNtp64(local_ntp_tx))
         UTI_Ntp64ToTimespec(local_ntp_tx, &local_tx.ts);
       else
         interleaved = 0;
       tx_ts = &local_tx;
     } else {
-      local_ntp_tx->hi = local_ntp_tx->lo = 0;
+      UTI_ZeroNtp64(local_ntp_tx);
       local_ntp_tx = NULL;
     }
   }
@@ -1857,10 +1849,8 @@ update_tx_timestamp(NTP_Local_Timestamp *tx_ts, NTP_Local_Timestamp *new_tx_ts,
   }
 
   /* Check if this is the last packet that was sent */
-  if ((local_ntp_rx && (message->receive_ts.hi != local_ntp_rx->hi ||
-                        message->receive_ts.lo != local_ntp_rx->lo)) ||
-      (local_ntp_tx && (message->transmit_ts.hi != local_ntp_tx->hi ||
-                        message->transmit_ts.lo != local_ntp_tx->lo))) {
+  if ((local_ntp_rx && UTI_CompareNtp64(&message->receive_ts, local_ntp_rx)) ||
+      (local_ntp_tx && UTI_CompareNtp64(&message->transmit_ts, local_ntp_tx))) {
     DEBUG_LOG(LOGF_NtpCore, "RX/TX timestamp mismatch");
     return;
   }
@@ -2236,8 +2226,7 @@ broadcast_timeout(void *arg)
 
   destination = ARR_GetElement(broadcasts, (long)arg);
 
-  orig_ts.hi = 0;
-  orig_ts.lo = 0;
+  UTI_ZeroNtp64(&orig_ts);
   UTI_ZeroTimespec(&recv_ts.ts);
   recv_ts.source = NTP_TS_DAEMON;
   recv_ts.err = 0.0;
diff --git a/util.c b/util.c
index a054b7963e305ff406bf32016b5c3ef551980391..7626a5cc17ced9d533fe1f9b36e91f54ed072112 100644 (file)
--- a/util.c
+++ b/util.c
@@ -679,6 +679,42 @@ UTI_DoubleToNtp32(double x)
 
 /* ================================================== */
 
+void
+UTI_ZeroNtp64(NTP_int64 *ts)
+{
+  ts->hi = ts->lo = htonl(0);
+}
+
+/* ================================================== */
+
+int
+UTI_IsZeroNtp64(NTP_int64 *ts)
+{
+  return !ts->hi && !ts->lo;
+}
+
+/* ================================================== */
+
+int
+UTI_CompareNtp64(NTP_int64 *a, NTP_int64 *b)
+{
+  int32_t diff;
+
+  if (a->hi == b->hi && a->lo == b->lo)
+    return 0;
+
+  diff = ntohl(a->hi) - ntohl(b->hi);
+
+  if (diff < 0)
+    return -1;
+  if (diff > 0)
+    return 1;
+
+  return ntohl(a->lo) < ntohl(b->lo) ? -1 : 1;
+}
+
+/* ================================================== */
+
 /* Seconds part of NTP timestamp correponding to the origin of the time_t format */
 #define JAN_1970 0x83aa7e80UL
 
diff --git a/util.h b/util.h
index 2f2332a91f3aa50bdaa9f71df982d1370de7d072..8ab1400e0b9a3886988f4fb8476cbd1b6e1d6079 100644 (file)
--- a/util.h
+++ b/util.h
@@ -126,8 +126,20 @@ extern void UTI_GetNtp64Fuzz(NTP_int64 *ts, int precision);
 extern double UTI_Ntp32ToDouble(NTP_int32 x);
 extern NTP_int32 UTI_DoubleToNtp32(double x);
 
+/* Zero an NTP timestamp */
+extern void UTI_ZeroNtp64(NTP_int64 *ts);
+
+/* Check if an NTP timestamp is zero */
+extern int UTI_IsZeroNtp64(NTP_int64 *ts);
+
+/* Compare two NTP timestamps.  Returns -1 if a is before b, 0 if a is equal to
+   b, and 1 if a is after b. */
+extern int UTI_CompareNtp64(NTP_int64 *a, NTP_int64 *b);
+
+/* Convert a timespec into an NTP timestamp */
 extern void UTI_TimespecToNtp64(struct timespec *src, NTP_int64 *dest, NTP_int64 *fuzz);
 
+/* Convert an NTP timestamp into a timespec */
 extern void UTI_Ntp64ToTimespec(NTP_int64 *src, struct timespec *dest);
 
 /* Check if time + offset is sane */