diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-05-22 17:48:19 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-05-22 17:48:19 +0200 |
commit | d99ef636f6e41acda164fc94c6bf87d1c14f9794 (patch) | |
tree | 663a1ecd7834cd2cc70c1cc53799f39a1fc33c6b | |
parent | b6dc13c2d3754704b1bf5af4e6b957b48585102f (diff) | |
download | busybox-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.c | 42 |
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"); |