]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: refactor timestamp selection and interval calculation
authorMiroslav Lichvar <mlichvar@redhat.com>
Fri, 21 Jul 2017 08:17:42 +0000 (10:17 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 21 Jul 2017 14:27:03 +0000 (16:27 +0200)
Prepare the code for a third option in the timestamp selection and clean
it up a bit.

ntp_core.c

index 9bf102c15276945d980aeb3988dca5b775eeebee..884a16d4bdeb2ebd16ddf15f7c65c2c3bedcfa47 100644 (file)
@@ -178,6 +178,9 @@ struct NCR_Instance_Record {
   NTP_int64 local_ntp_tx;
   NTP_Local_Timestamp local_tx;
 
+  /* Previous local transmit timestamp for the interleaved mode */
+  NTP_Local_Timestamp prev_local_tx;
+
   /* The instance record in the main source management module.  This
      performs the statistical analysis on the samples we generate */
 
@@ -643,6 +646,7 @@ NCR_ResetInstance(NCR_Instance instance)
   UTI_ZeroNtp64(&instance->local_ntp_rx);
   UTI_ZeroNtp64(&instance->local_ntp_tx);
   zero_local_timestamp(&instance->local_rx);
+  zero_local_timestamp(&instance->prev_local_tx);
 }
 
 /* ================================================== */
@@ -1349,9 +1353,9 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
      measurement in seconds */
   double error_in_estimate;
 
-  double remote_interval, local_interval, server_interval;
+  NTP_Local_Timestamp local_receive, local_transmit;
+  double remote_interval, local_interval, response_time;
   double delay_time, precision;
-  NTP_Timestamp_Source sample_rx_tss;
 
   /* ==================== */
 
@@ -1421,39 +1425,34 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
 
   if (synced_packet && (!interleaved_packet || inst->valid_timestamps)) {
     /* These are the timespec equivalents of the remote and local epochs */
-    struct timespec remote_receive, remote_transmit, prev_remote_receive;
+    struct timespec remote_receive, remote_transmit, remote_request_receive;
     struct timespec local_average, remote_average;
-    double rx_ts_err;
-
-    precision = LCL_GetSysPrecisionAsQuantum() +
-                UTI_Log2ToDouble(message->precision);
-
-    SST_GetFrequencyRange(stats, &source_freq_lo, &source_freq_hi);
-    
-    UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
-    UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
 
-    /* Calculate intervals between remote and local timestamps */
+    /* Select remote and local timestamps for the new sample */
     if (interleaved_packet) {
-      UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &prev_remote_receive);
-      UTI_AverageDiffTimespecs(&remote_transmit, &remote_receive,
-                               &remote_average, &remote_interval);
-      UTI_AverageDiffTimespecs(&inst->local_rx.ts, &inst->local_tx.ts,
-                               &local_average, &local_interval);
-      server_interval = UTI_DiffTimespecsToDouble(&remote_transmit,
-                                                  &prev_remote_receive);
-      rx_ts_err = inst->local_rx.err;
-      sample_rx_tss = inst->local_rx.source;
+      UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
+      UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
+      UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_request_receive);
+      local_receive = inst->local_rx;
+      local_transmit = inst->local_tx;
     } else {
-      UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
-                               &remote_average, &remote_interval);
-      UTI_AverageDiffTimespecs(&inst->local_tx.ts, &rx_ts->ts,
-                               &local_average, &local_interval);
-      server_interval = remote_interval;
-      rx_ts_err = rx_ts->err;
-      sample_rx_tss = rx_ts->source;
+      UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
+      UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
+      remote_request_receive = remote_receive;
+      local_receive = *rx_ts;
+      local_transmit = inst->local_tx;
     }
 
+    /* Calculate intervals between remote and local timestamps */
+    UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
+                             &remote_average, &remote_interval);
+    UTI_AverageDiffTimespecs(&local_transmit.ts, &local_receive.ts,
+                             &local_average, &local_interval);
+    response_time = fabs(UTI_DiffTimespecsToDouble(&remote_transmit,
+                                                   &remote_request_receive));
+
+    precision = LCL_GetSysPrecisionAsQuantum() + UTI_Log2ToDouble(message->precision);
+
     /* Calculate delay */
     delay = fabs(local_interval - remote_interval);
     if (delay < precision)
@@ -1473,11 +1472,13 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
        sample pair. */
     sample_time = local_average;
     
+    SST_GetFrequencyRange(stats, &source_freq_lo, &source_freq_hi);
+
     /* Calculate skew */
     skew = (source_freq_hi - source_freq_lo) / 2.0;
     
     /* and then calculate peer dispersion */
-    dispersion = MAX(precision, MAX(inst->local_tx.err, rx_ts_err)) +
+    dispersion = MAX(precision, MAX(local_transmit.err, local_receive.err)) +
                  skew * fabs(local_interval);
     
     /* Additional tests required to pass before accumulating the sample */
@@ -1488,7 +1489,7 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
        the delay is not longer than half of the remote polling interval to
        detect missed packets */
     testA = delay - dispersion <= inst->max_delay && precision <= inst->max_delay &&
-            !(inst->mode == MODE_CLIENT && server_interval > MAX_SERVER_INTERVAL) &&
+            !(inst->mode == MODE_CLIENT && response_time > MAX_SERVER_INTERVAL) &&
             !(inst->mode == MODE_ACTIVE && interleaved_packet &&
               delay > UTI_Log2ToDouble(message->poll - 1));
 
@@ -1512,10 +1513,11 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
     testD = message->stratum <= 1 || REF_GetMode() != REF_ModeNormal ||
             pkt_refid != UTI_IPToRefid(&local_addr->ip_addr);
   } else {
-    remote_interval = local_interval = server_interval = 0.0;
+    remote_interval = local_interval = response_time = 0.0;
     offset = delay = dispersion = 0.0;
     sample_time = rx_ts->ts;
-    sample_rx_tss = rx_ts->source;
+    local_receive = *rx_ts;
+    local_transmit = inst->local_tx;
     testA = testB = testC = testD = 0;
   }
   
@@ -1561,8 +1563,8 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
     inst->valid_rx = 1;
   }
 
-  if ((int)sample_rx_tss < 0 || sample_rx_tss >= sizeof (tss_chars) ||
-      (int)inst->local_tx.source < 0 || inst->local_tx.source >= sizeof (tss_chars))
+  if ((unsigned int)local_receive.source >= sizeof (tss_chars) ||
+      (unsigned int)local_transmit.source >= sizeof (tss_chars))
     assert(0);
 
   DEBUG_LOG("NTP packet lvm=%o stratum=%d poll=%d prec=%d root_delay=%f root_disp=%f refid=%"PRIx32" [%s]",
@@ -1576,9 +1578,9 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
             UTI_Ntp64ToString(&message->transmit_ts));
   DEBUG_LOG("offset=%.9f delay=%.9f dispersion=%f root_delay=%f root_dispersion=%f",
             offset, delay, dispersion, root_delay, root_dispersion);
-  DEBUG_LOG("remote_interval=%.9f local_interval=%.9f server_interval=%.9f txs=%c rxs=%c",
-            remote_interval, local_interval, server_interval,
-            tss_chars[inst->local_tx.source], tss_chars[sample_rx_tss]);
+  DEBUG_LOG("remote_interval=%.9f local_interval=%.9f response_time=%.9f txs=%c rxs=%c",
+            remote_interval, local_interval, response_time,
+            tss_chars[local_transmit.source], tss_chars[local_receive.source]);
   DEBUG_LOG("test123=%d%d%d test567=%d%d%d testABCD=%d%d%d%d kod_rate=%d interleaved=%d presend=%d valid=%d good=%d updated=%d",
             test1, test2, test3, test5, test6, test7, testA, testB, testC, testD,
             kod_rate, interleaved_packet, inst->presend_done, valid_packet, good_packet,
@@ -1682,15 +1684,15 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
     inst->report.offset = offset;
     inst->report.peer_delay = delay;
     inst->report.peer_dispersion = dispersion;
-    inst->report.response_time = server_interval;
+    inst->report.response_time = response_time;
     inst->report.jitter_asymmetry = SST_GetJitterAsymmetry(stats);
     inst->report.tests = ((((((((test1 << 1 | test2) << 1 | test3) << 1 |
                                test5) << 1 | test6) << 1 | test7) << 1 |
                             testA) << 1 | testB) << 1 | testC) << 1 | testD;
     inst->report.interleaved = interleaved_packet;
     inst->report.authenticated = inst->auth_mode != AUTH_NONE;
-    inst->report.tx_tss_char = tss_chars[inst->local_tx.source];
-    inst->report.rx_tss_char = tss_chars[sample_rx_tss];
+    inst->report.tx_tss_char = tss_chars[local_transmit.source];
+    inst->report.rx_tss_char = tss_chars[local_receive.source];
 
     inst->report.total_valid_count++;
   }
@@ -1708,8 +1710,8 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
             offset, delay, dispersion,
             pkt_root_delay, pkt_root_dispersion, pkt_refid,
             NTP_LVM_TO_MODE(message->lvm), interleaved_packet ? 'I' : 'B',
-            tss_chars[inst->local_tx.source],
-            tss_chars[sample_rx_tss]);
+            tss_chars[local_transmit.source],
+            tss_chars[local_receive.source]);
   }            
 
   return good_packet;