ntpd: truly ignore high delay packet

Before this cahnge, sometimes they were used after the next packet
from another peer was received, because we did updare some peer stats
from high delay packet before dropping it.

function                                             old     new   delta
recv_and_process_peer_pkt                            922     966     +44

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2014-04-19 19:00:16 +02:00
parent 6116cb23cc
commit d531f93f64

View File

@ -252,6 +252,9 @@ typedef struct {
* or when receive times out (if p_fd >= 0): */
double next_action_time;
double p_xmttime;
double p_raw_delay;
/* p_raw_delay is set even by "high delay" packets */
/* lastpkt_delay isn't */
double lastpkt_recv_time;
double lastpkt_delay;
double lastpkt_rootdelay;
@ -1685,7 +1688,8 @@ recv_and_process_peer_pkt(peer_t *p)
ssize_t size;
msg_t msg;
double T1, T2, T3, T4;
double dv, offset;
double offset;
double prev_delay, delay;
unsigned interval;
datapoint_t *datapoint;
peer_t *q;
@ -1745,12 +1749,6 @@ recv_and_process_peer_pkt(peer_t *p)
// if (msg.m_rootdelay / 2 + msg.m_rootdisp >= MAXDISP || p->lastpkt_reftime > msg.m_xmt)
// return; /* invalid header values */
p->lastpkt_status = msg.m_status;
p->lastpkt_stratum = msg.m_stratum;
p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);
p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);
p->lastpkt_refid = msg.m_refid;
/*
* From RFC 2030 (with a correction to the delay math):
*
@ -1770,28 +1768,35 @@ recv_and_process_peer_pkt(peer_t *p)
T3 = lfp_to_d(msg.m_xmttime);
T4 = G.cur_time;
p->lastpkt_recv_time = T4;
VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_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.
*/
dv = p->lastpkt_delay;
p->lastpkt_delay = (T4 - T1) - (T3 - T2);
if (p->lastpkt_delay < G_precision_sec)
p->lastpkt_delay = G_precision_sec;
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.
*/
if (p->reachable_bits && p->lastpkt_delay > dv * BAD_DELAY_GROWTH) {
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, p->lastpkt_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);
p->lastpkt_status = msg.m_status;
p->lastpkt_stratum = msg.m_stratum;
p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);
p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);
p->lastpkt_refid = msg.m_refid;
p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;
datapoint = &p->filter_datapoint[p->datapoint_idx];
datapoint->d_recv_time = T4;