From 9b1c8bf89be668a533505e5fb4405bac6eed651c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 3 Aug 2018 11:03:55 +0200 Subject: ntpd: show real, unclamped delays on low-latency networks On fast network, I've seen "delay:0.002000" shown for all packets, thus completely losing information on what real delays are. The new code is careful to not reject packets with tiny delays if the delay "grows a lot" but is still tiny: 0.000009 is "much larger" than 0.000001 (nine times larger), but is still very good small delay. function old new delta recv_and_process_peer_pkt 863 889 +26 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 7462113ce..991c518f6 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -150,7 +150,7 @@ #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ #define MIN_FREQHOLD 12 /* adjust offset, but not freq in this many first adjustments */ -#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ +#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this factor */ #define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ #define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ @@ -1819,7 +1819,7 @@ update_local_clock(peer_t *p) VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", p->p_dotted, offset, - p->lastpkt_delay, + p->p_raw_delay, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant @@ -1976,27 +1976,30 @@ recv_and_process_peer_pkt(peer_t *p) T2 = lfp_to_d(msg.m_rectime); T3 = lfp_to_d(msg.m_xmttime); T4 = G.cur_time; - - /* The delay calculation is a special case. In cases where the - * server and client clocks are running at different rates and - * with very fast networks, the delay can appear negative. In - * order to avoid violating the Principle of Least Astonishment, - * the delay is clamped not less than the system precision. - */ delay = (T4 - T1) - (T3 - T2); - if (delay < G_precision_sec) - delay = G_precision_sec; + /* * If this packet's delay is much bigger than the last one, * it's better to just ignore it than use its much less precise value. */ prev_delay = p->p_raw_delay; - p->p_raw_delay = delay; - if (p->reachable_bits && delay > prev_delay * BAD_DELAY_GROWTH) { + p->p_raw_delay = (delay < 0 ? 0.0 : delay); + if (p->reachable_bits + && delay > prev_delay * BAD_DELAY_GROWTH + && delay > 1.0 / (8 * 1024) /* larger than ~0.000122 */ + ) { bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay); goto pick_normal_interval; } + /* The delay calculation is a special case. In cases where the + * server and client clocks are running at different rates and + * with very fast networks, the delay can appear negative. In + * order to avoid violating the Principle of Least Astonishment, + * the delay is clamped not less than the system precision. + */ + if (delay < G_precision_sec) + delay = G_precision_sec; p->lastpkt_delay = delay; p->lastpkt_recv_time = T4; VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); @@ -2024,7 +2027,7 @@ recv_and_process_peer_pkt(peer_t *p) bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", p->p_dotted, offset, - p->lastpkt_delay, + p->p_raw_delay, p->lastpkt_status, p->lastpkt_stratum, p->lastpkt_refid, -- cgit v1.2.3