diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2017-01-06 16:18:45 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-06 16:21:09 +0100 |
commit | b62ea34afed7d3bf60a6c8ef5a030fea52f55b10 (patch) | |
tree | c35f49e40a487b16dc82cb00fd2f4c85d37ab74e | |
parent | e6add210b220bd8fe56ca711279b44e111bdd8f0 (diff) | |
download | busybox-w32-b62ea34afed7d3bf60a6c8ef5a030fea52f55b10.tar.gz busybox-w32-b62ea34afed7d3bf60a6c8ef5a030fea52f55b10.tar.bz2 busybox-w32-b62ea34afed7d3bf60a6c8ef5a030fea52f55b10.zip |
ntpd: improve postponed hostname resolution
Run the namelookup from the main loop so a misspelled first ntp server
name does not block everything forever.
This fixes the following situation which would block forever:
$ sudo ./busybox ntpd -dn -p foobar -p pool.ntp.org
ntpd: bad address 'foobar'
ntpd: bad address 'foobar'
ntpd: bad address 'foobar'
...
New behavior:
ntpd: bad address 'foobar'
ntpd: sending query to 137.190.2.4
ntpd: reply from 137.190.2.4: offset:-1.009775 delay:0.175550 status:0x24 strat:1 refid:0x00535047 rootdelay:0.000000 reach:0x01
ntpd: sending query to 137.190.2.4
ntpd: reply from 137.190.2.4: offset:-1.009605 delay:0.175461 status:0x24 strat:1 refid:0x00535047 rootdelay:0.000000 reach:0x03
ntpd: sending query to 137.190.2.4
ntpd: reply from 137.190.2.4: offset:-1.005327 delay:0.167027 status:0x24 strat:1 refid:0x00535047 rootdelay:0.000000 reach:0x07
ntpd: sending query to 137.190.2.4
ntpd: bad address 'foobar'
ntpd: reply from 137.190.2.4: offset:-1.046349 delay:0.248705 status:0x24 strat:1 refid:0x00535047 rootdelay:0.000000 reach:0x0f
This patch is based on Kaarle Ritvanens work.
http://lists.busybox.net/pipermail/busybox/2016-May/084197.html
function old new delta
ntpd_main 1061 1079 +18
ntp_init 556 560 +4
resolve_peer_hostname 81 75 -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 22/-6) Total: 16 bytes
Signed-off-by: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/ntpd.c | 73 |
1 files changed, 34 insertions, 39 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c index b7fa5dce9..bfd5705fc 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -155,6 +155,7 @@ | |||
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 | 159 | ||
159 | /* Step threshold (sec). std ntpd uses 0.128. | 160 | /* Step threshold (sec). std ntpd uses 0.128. |
160 | */ | 161 | */ |
@@ -790,28 +791,20 @@ reset_peer_stats(peer_t *p, double offset) | |||
790 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); | 791 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); |
791 | } | 792 | } |
792 | 793 | ||
793 | static void | 794 | static len_and_sockaddr* |
794 | resolve_peer_hostname(peer_t *p, int loop_on_fail) | 795 | resolve_peer_hostname(peer_t *p) |
795 | { | 796 | { |
796 | len_and_sockaddr *lsa; | 797 | len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); |
797 | 798 | if (lsa) { | |
798 | again: | 799 | free(p->p_lsa); |
799 | lsa = host2sockaddr(p->p_hostname, 123); | 800 | free(p->p_dotted); |
800 | if (!lsa) { | 801 | p->p_lsa = lsa; |
801 | /* error message already emitted by host2sockaddr() */ | 802 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
802 | if (!loop_on_fail) | 803 | } else { |
803 | return; | 804 | /* error message is emitted by host2sockaddr() */ |
804 | //FIXME: do this to avoid infinite looping on typo in a hostname? | 805 | set_next(p, HOSTNAME_INTERVAL); |
805 | //well... in which case, what is a good value for loop_on_fail? | ||
806 | //if (--loop_on_fail == 0) | ||
807 | // xfunc_die(); | ||
808 | sleep(5); | ||
809 | goto again; | ||
810 | } | 806 | } |
811 | free(p->p_lsa); | 807 | return lsa; |
812 | free(p->p_dotted); | ||
813 | p->p_lsa = lsa; | ||
814 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | ||
815 | } | 808 | } |
816 | 809 | ||
817 | static void | 810 | static void |
@@ -822,28 +815,28 @@ add_peers(const char *s) | |||
822 | 815 | ||
823 | p = xzalloc(sizeof(*p) + strlen(s)); | 816 | p = xzalloc(sizeof(*p) + strlen(s)); |
824 | strcpy(p->p_hostname, s); | 817 | strcpy(p->p_hostname, s); |
825 | resolve_peer_hostname(p, /*loop_on_fail=*/ 1); | 818 | p->p_fd = -1; |
819 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | ||
820 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | ||
821 | reset_peer_stats(p, STEP_THRESHOLD); | ||
826 | 822 | ||
827 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved | 823 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved |
828 | * to a pool of machines. Sometimes different N's resolve to the same IP. | 824 | * to a pool of machines. Sometimes different N's resolve to the same IP. |
829 | * It is not useful to have two peers with same IP. We skip duplicates. | 825 | * It is not useful to have two peers with same IP. We skip duplicates. |
830 | */ | 826 | */ |
831 | for (item = G.ntp_peers; item != NULL; item = item->link) { | 827 | if (resolve_peer_hostname(p)) { |
832 | peer_t *pp = (peer_t *) item->data; | 828 | for (item = G.ntp_peers; item != NULL; item = item->link) { |
833 | if (strcmp(p->p_dotted, pp->p_dotted) == 0) { | 829 | peer_t *pp = (peer_t *) item->data; |
834 | bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); | 830 | if (pp->p_dotted && strcmp(p->p_dotted, pp->p_dotted) == 0) { |
835 | free(p->p_lsa); | 831 | bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); |
836 | free(p->p_dotted); | 832 | free(p->p_lsa); |
837 | free(p); | 833 | free(p->p_dotted); |
838 | return; | 834 | free(p); |
835 | return; | ||
836 | } | ||
839 | } | 837 | } |
840 | } | 838 | } |
841 | 839 | ||
842 | p->p_fd = -1; | ||
843 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | ||
844 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | ||
845 | reset_peer_stats(p, STEP_THRESHOLD); | ||
846 | |||
847 | llist_add_to(&G.ntp_peers, p); | 840 | llist_add_to(&G.ntp_peers, p); |
848 | G.peer_cnt++; | 841 | G.peer_cnt++; |
849 | } | 842 | } |
@@ -871,6 +864,11 @@ do_sendto(int fd, | |||
871 | static void | 864 | static void |
872 | send_query_to_peer(peer_t *p) | 865 | send_query_to_peer(peer_t *p) |
873 | { | 866 | { |
867 | if (!p->p_lsa) { | ||
868 | if (!resolve_peer_hostname(p)) | ||
869 | return; | ||
870 | } | ||
871 | |||
874 | /* Why do we need to bind()? | 872 | /* Why do we need to bind()? |
875 | * See what happens when we don't bind: | 873 | * See what happens when we don't bind: |
876 | * | 874 | * |
@@ -2238,7 +2236,7 @@ static NOINLINE void ntp_init(char **argv) | |||
2238 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ | 2236 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ |
2239 | "d" /* compat */ | 2237 | "d" /* compat */ |
2240 | "46aAbgL", /* compat, ignored */ | 2238 | "46aAbgL", /* compat, ignored */ |
2241 | &peers,&G.script_name, | 2239 | &peers, &G.script_name, |
2242 | #if ENABLE_FEATURE_NTPD_SERVER | 2240 | #if ENABLE_FEATURE_NTPD_SERVER |
2243 | &G.if_name, | 2241 | &G.if_name, |
2244 | #endif | 2242 | #endif |
@@ -2263,9 +2261,6 @@ static NOINLINE void ntp_init(char **argv) | |||
2263 | if (opts & OPT_N) | 2261 | if (opts & OPT_N) |
2264 | setpriority(PRIO_PROCESS, 0, -15); | 2262 | setpriority(PRIO_PROCESS, 0, -15); |
2265 | 2263 | ||
2266 | /* add_peers() calls can retry DNS resolution (possibly forever). | ||
2267 | * Daemonize before them, or else boot can stall forever. | ||
2268 | */ | ||
2269 | if (!(opts & OPT_n)) { | 2264 | if (!(opts & OPT_n)) { |
2270 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); | 2265 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); |
2271 | logmode = LOGMODE_NONE; | 2266 | logmode = LOGMODE_NONE; |
@@ -2400,7 +2395,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2400 | 2395 | ||
2401 | /* What if don't see it because it changed its IP? */ | 2396 | /* What if don't see it because it changed its IP? */ |
2402 | if (p->reachable_bits == 0) | 2397 | if (p->reachable_bits == 0) |
2403 | resolve_peer_hostname(p, /*loop_on_fail=*/ 0); | 2398 | resolve_peer_hostname(p); |
2404 | 2399 | ||
2405 | set_next(p, timeout); | 2400 | set_next(p, timeout); |
2406 | } | 2401 | } |