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 <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-08-03 11:03:55 +02:00
parent a380aacca6
commit 9b1c8bf89b

View File

@ -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,6 +1976,21 @@ 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;
delay = (T4 - T1) - (T3 - T2);
/*
* 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 < 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
@ -1983,20 +1998,8 @@ recv_and_process_peer_pkt(peer_t *p)
* 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) {
bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay);
goto pick_normal_interval;
}
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,