summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2014-04-19 19:00:16 +0200
committerDenys Vlasenko2014-04-19 19:00:16 +0200
commitd531f93f646f4347b464730b80dfb34b8744a984 (patch)
treea125e1044d33cec06fac84dc9970067c79c9d839
parent6116cb23cc2074f232397b406fabab1606b28fb6 (diff)
downloadbusybox-d531f93f646f4347b464730b80dfb34b8744a984.zip
busybox-d531f93f646f4347b464730b80dfb34b8744a984.tar.gz
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>
-rw-r--r--networking/ntpd.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index adda6e5..2eec99f 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -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;