aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-10-31 12:44:37 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-10-31 12:44:37 +0100
commit6a4f2231221c2c4f7ca82f081f442e31a6cfd051 (patch)
treef46898d1c966061177d82cb02be2ecf7aee0024f
parent518fb3ba193cddc1369090bfdf827618b42791db (diff)
downloadbusybox-w32-6a4f2231221c2c4f7ca82f081f442e31a6cfd051.tar.gz
busybox-w32-6a4f2231221c2c4f7ca82f081f442e31a6cfd051.tar.bz2
busybox-w32-6a4f2231221c2c4f7ca82f081f442e31a6cfd051.zip
ntpd: improve treatment of DNS resolution failures
function old new delta ntpd_main 1106 1177 +71 resolve_peer_hostname 122 127 +5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 76/0) Total: 76 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ntpd.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 8f792d16d..e0c9810a1 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -155,7 +155,8 @@
155#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ 155#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */
156#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ 156#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */
157#define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ 157#define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */
158#define HOSTNAME_INTERVAL 5 /* hostname lookup failed. Wait N secs for next try */ 158#define HOSTNAME_INTERVAL 4 /* hostname lookup failed. Wait N * peer->dns_errors secs for next try */
159#define DNS_ERRORS_CAP 0x3f /* peer->dns_errors is in [0..63] */
159 160
160/* Step threshold (sec). std ntpd uses 0.128. 161/* Step threshold (sec). std ntpd uses 0.128.
161 */ 162 */
@@ -301,6 +302,7 @@ typedef struct {
301 uint8_t lastpkt_status; 302 uint8_t lastpkt_status;
302 uint8_t lastpkt_stratum; 303 uint8_t lastpkt_stratum;
303 uint8_t reachable_bits; 304 uint8_t reachable_bits;
305 uint8_t dns_errors;
304 /* when to send new query (if p_fd == -1) 306 /* when to send new query (if p_fd == -1)
305 * or when receive times out (if p_fd >= 0): */ 307 * or when receive times out (if p_fd >= 0): */
306 double next_action_time; 308 double next_action_time;
@@ -802,10 +804,9 @@ resolve_peer_hostname(peer_t *p)
802 p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); 804 p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
803 VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0) 805 VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0)
804 bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted); 806 bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted);
805 } else { 807 p->dns_errors = 0;
806 /* error message is emitted by host2sockaddr() */
807 set_next(p, HOSTNAME_INTERVAL);
808 } 808 }
809 p->dns_errors = ((p->dns_errors << 1) | 1) & DNS_ERRORS_CAP;
809 return lsa; 810 return lsa;
810} 811}
811 812
@@ -2358,14 +2359,6 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2358 int nfds, timeout; 2359 int nfds, timeout;
2359 double nextaction; 2360 double nextaction;
2360 2361
2361 /* Resolve peer names to IPs, if not resolved yet */
2362 for (item = G.ntp_peers; item != NULL; item = item->link) {
2363 peer_t *p = (peer_t *) item->data;
2364
2365 if (p->next_action_time <= G.cur_time && !p->p_lsa)
2366 resolve_peer_hostname(p);
2367 }
2368
2369 /* Nothing between here and poll() blocks for any significant time */ 2362 /* Nothing between here and poll() blocks for any significant time */
2370 2363
2371 nextaction = G.cur_time + 3600; 2364 nextaction = G.cur_time + 3600;
@@ -2447,13 +2440,38 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2447 did_poll: 2440 did_poll:
2448 gettime1900d(); /* sets G.cur_time */ 2441 gettime1900d(); /* sets G.cur_time */
2449 if (nfds <= 0) { 2442 if (nfds <= 0) {
2450 if (!bb_got_signal /* poll wasn't interrupted by a signal */ 2443 double ct;
2451 && G.cur_time - G.last_script_run > 11*60 2444
2452 ) { 2445 if (bb_got_signal)
2446 break; /* poll was interrupted by a signal */
2447
2448 if (G.cur_time - G.last_script_run > 11*60) {
2453 /* Useful for updating battery-backed RTC and such */ 2449 /* Useful for updating battery-backed RTC and such */
2454 run_script("periodic", G.last_update_offset); 2450 run_script("periodic", G.last_update_offset);
2455 gettime1900d(); /* sets G.cur_time */ 2451 gettime1900d(); /* sets G.cur_time */
2456 } 2452 }
2453
2454 /* Resolve peer names to IPs, if not resolved yet.
2455 * We do it only when poll timed out:
2456 * this way, we almost never overlap DNS resolution with
2457 * "request-reply" packet round trip.
2458 */
2459 ct = G.cur_time;
2460 for (item = G.ntp_peers; item != NULL; item = item->link) {
2461 peer_t *p = (peer_t *) item->data;
2462 if (p->next_action_time <= ct && !p->p_lsa) {
2463 /* This can take up to ~10 sec per each DNS query */
2464 resolve_peer_hostname(p);
2465 }
2466 }
2467 gettime1900d(); /* sets G.cur_time (needed for set_next()) */
2468 /* Set next time for those which are still not resolved */
2469 for (item = G.ntp_peers; item != NULL; item = item->link) {
2470 peer_t *p = (peer_t *) item->data;
2471 if (p->next_action_time <= ct && !p->p_lsa) {
2472 set_next(p, HOSTNAME_INTERVAL * p->dns_errors);
2473 }
2474 }
2457 goto check_unsync; 2475 goto check_unsync;
2458 } 2476 }
2459 2477