diff options
author | Denys Vlasenko | 2014-04-19 19:00:16 +0200 |
---|---|---|
committer | Denys Vlasenko | 2014-04-19 19:00:16 +0200 |
commit | d531f93f646f4347b464730b80dfb34b8744a984 (patch) | |
tree | a125e1044d33cec06fac84dc9970067c79c9d839 /networking | |
parent | 6116cb23cc2074f232397b406fabab1606b28fb6 (diff) | |
download | busybox-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>
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ntpd.c | 35 |
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; |