aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-05-22 17:48:19 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-05-22 17:48:19 +0200
commitd99ef636f6e41acda164fc94c6bf87d1c14f9794 (patch)
tree663a1ecd7834cd2cc70c1cc53799f39a1fc33c6b
parentb6dc13c2d3754704b1bf5af4e6b957b48585102f (diff)
downloadbusybox-w32-d99ef636f6e41acda164fc94c6bf87d1c14f9794.tar.gz
busybox-w32-d99ef636f6e41acda164fc94c6bf87d1c14f9794.tar.bz2
busybox-w32-d99ef636f6e41acda164fc94c6bf87d1c14f9794.zip
ntpd: drop delay outliers; run "unsync" handler if no replies for some time
function old new delta ntpd_main 960 1029 +69 recv_and_process_peer_pkt 834 892 +58 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 127/0) Total: 127 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ntpd.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 0f4319ef2..9ec255814 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -95,6 +95,7 @@
95#define RETRY_INTERVAL 5 /* on error, retry in N secs */ 95#define RETRY_INTERVAL 5 /* on error, retry in N secs */
96#define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ 96#define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */
97#define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 97#define INITIAL_SAMPLES 4 /* how many samples do we want for init */
98#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */
98 99
99/* Clock discipline parameters and constants */ 100/* Clock discipline parameters and constants */
100 101
@@ -1616,6 +1617,7 @@ recv_and_process_peer_pkt(peer_t *p)
1616 ssize_t size; 1617 ssize_t size;
1617 msg_t msg; 1618 msg_t msg;
1618 double T1, T2, T3, T4; 1619 double T1, T2, T3, T4;
1620 double dv;
1619 unsigned interval; 1621 unsigned interval;
1620 datapoint_t *datapoint; 1622 datapoint_t *datapoint;
1621 peer_t *q; 1623 peer_t *q;
@@ -1665,9 +1667,8 @@ recv_and_process_peer_pkt(peer_t *p)
1665// TODO: stratum 0 responses may have commands in 32-bit m_refid field: 1667// TODO: stratum 0 responses may have commands in 32-bit m_refid field:
1666// "DENY", "RSTR" - peer does not like us at all 1668// "DENY", "RSTR" - peer does not like us at all
1667// "RATE" - peer is overloaded, reduce polling freq 1669// "RATE" - peer is overloaded, reduce polling freq
1668 interval = poll_interval(0); 1670 bb_error_msg("reply from %s: peer is unsynced", p->p_dotted);
1669 bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); 1671 goto pick_normal_interval;
1670 goto set_next_and_ret;
1671 } 1672 }
1672 1673
1673// /* Verify valid root distance */ 1674// /* Verify valid root distance */
@@ -1700,21 +1701,31 @@ recv_and_process_peer_pkt(peer_t *p)
1700 T4 = G.cur_time; 1701 T4 = G.cur_time;
1701 1702
1702 p->lastpkt_recv_time = T4; 1703 p->lastpkt_recv_time = T4;
1703
1704 VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 1704 VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
1705 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0; 1705
1706 datapoint = &p->filter_datapoint[p->datapoint_idx];
1707 datapoint->d_recv_time = T4;
1708 datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2;
1709 /* The delay calculation is a special case. In cases where the 1706 /* The delay calculation is a special case. In cases where the
1710 * server and client clocks are running at different rates and 1707 * server and client clocks are running at different rates and
1711 * with very fast networks, the delay can appear negative. In 1708 * with very fast networks, the delay can appear negative. In
1712 * order to avoid violating the Principle of Least Astonishment, 1709 * order to avoid violating the Principle of Least Astonishment,
1713 * the delay is clamped not less than the system precision. 1710 * the delay is clamped not less than the system precision.
1714 */ 1711 */
1712 dv = p->lastpkt_delay;
1715 p->lastpkt_delay = (T4 - T1) - (T3 - T2); 1713 p->lastpkt_delay = (T4 - T1) - (T3 - T2);
1716 if (p->lastpkt_delay < G_precision_sec) 1714 if (p->lastpkt_delay < G_precision_sec)
1717 p->lastpkt_delay = G_precision_sec; 1715 p->lastpkt_delay = G_precision_sec;
1716 /*
1717 * If this packet's delay is much bigger than the last one,
1718 * it's better to just ignore it than use its much less precise value.
1719 */
1720 if (p->reachable_bits && p->lastpkt_delay > dv * BAD_DELAY_GROWTH) {
1721 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, p->lastpkt_delay);
1722 goto pick_normal_interval;
1723 }
1724
1725 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;
1726 datapoint = &p->filter_datapoint[p->datapoint_idx];
1727 datapoint->d_recv_time = T4;
1728 datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2;
1718 datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec; 1729 datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec;
1719 if (!p->reachable_bits) { 1730 if (!p->reachable_bits) {
1720 /* 1st datapoint ever - replicate offset in every element */ 1731 /* 1st datapoint ever - replicate offset in every element */
@@ -1811,6 +1822,7 @@ recv_and_process_peer_pkt(peer_t *p)
1811 } 1822 }
1812 1823
1813 /* Decide when to send new query for this peer */ 1824 /* Decide when to send new query for this peer */
1825 pick_normal_interval:
1814 interval = poll_interval(0); 1826 interval = poll_interval(0);
1815 1827
1816 set_next_and_ret: 1828 set_next_and_ret:
@@ -2195,6 +2207,20 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2195 gettime1900d(); /* sets G.cur_time */ 2207 gettime1900d(); /* sets G.cur_time */
2196 } 2208 }
2197 } 2209 }
2210
2211 if (G.ntp_peers && G.stratum != MAXSTRAT) {
2212 for (item = G.ntp_peers; item != NULL; item = item->link) {
2213 peer_t *p = (peer_t *) item->data;
2214 if (p->reachable_bits)
2215 goto have_reachable_peer;
2216 }
2217 /* No peer responded for last 8 packets, panic */
2218 G.polladj_count = 0;
2219 G.poll_exp = MINPOLL;
2220 G.stratum = MAXSTRAT;
2221 run_script("unsync", G.last_update_offset);
2222 have_reachable_peer: ;
2223 }
2198 } /* while (!bb_got_signal) */ 2224 } /* while (!bb_got_signal) */
2199 2225
2200 remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); 2226 remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid");