From 0baa35eade72183a989022c43de85c13f43d811b Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Fri, 21 Jul 2017 10:45:46 +0200 Subject: [PATCH] ntp: select timestamps in interleaved mode Use previous local TX and remote RX timestamps for the new sample in the interleaved mode if it will make the local and remote intervals significantly shorter in order to improve the accuracy of the measured delay. --- ntp_core.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/ntp_core.c b/ntp_core.c index 884a16d..02bc3b8 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -266,6 +266,10 @@ static ARR_Instance broadcasts; /* Maximum number of missed responses to follow peer's polling interval */ #define MAX_PEER_POLL_TX 8 +/* Maximum ratio of local intervals in the timestamp selection of the + interleaved mode to prefer a sample using previous timestamps */ +#define MAX_INTERLEAVED_L2L_RATIO 0.1 + /* Invalid socket, different from the one in ntp_io.c */ #define INVALID_SOCK_FD -2 @@ -1430,11 +1434,23 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr, /* Select remote and local timestamps for the new sample */ if (interleaved_packet) { - UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive); + /* Prefer previous local TX and remote RX timestamps if it will make + the intervals significantly shorter in order to improve the accuracy + of the measured delay */ + if (!UTI_IsZeroTimespec(&inst->prev_local_tx.ts) && + MAX_INTERLEAVED_L2L_RATIO * + UTI_DiffTimespecsToDouble(&inst->local_tx.ts, &inst->local_rx.ts) > + UTI_DiffTimespecsToDouble(&inst->local_rx.ts, &inst->prev_local_tx.ts)) { + UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_receive); + remote_request_receive = remote_receive; + local_transmit = inst->prev_local_tx; + } else { + UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive); + UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_request_receive); + local_transmit = inst->local_tx; + } 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_Ntp64ToTimespec(&message->receive_ts, &remote_receive); UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit); @@ -1546,6 +1562,12 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr, inst->local_rx = *rx_ts; inst->valid_timestamps = synced_packet; inst->updated_timestamps = 1; + + /* Don't use the same set of timestamps for the next sample */ + if (interleaved_packet) + inst->prev_local_tx = inst->local_tx; + else + zero_local_timestamp(&inst->prev_local_tx); } /* Accept at most one response per request. The NTP specification recommends @@ -2070,6 +2092,9 @@ NCR_SlewTimes(NCR_Instance inst, struct timespec *when, double dfreq, double dof UTI_AdjustTimespec(&inst->local_rx.ts, when, &inst->local_rx.ts, &delta, dfreq, doffset); if (!UTI_IsZeroTimespec(&inst->local_tx.ts)) UTI_AdjustTimespec(&inst->local_tx.ts, when, &inst->local_tx.ts, &delta, dfreq, doffset); + if (!UTI_IsZeroTimespec(&inst->prev_local_tx.ts)) + UTI_AdjustTimespec(&inst->prev_local_tx.ts, when, &inst->prev_local_tx.ts, &delta, dfreq, + doffset); } /* ================================================== */