#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */
#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */
#define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */
+#define HOSTNAME_INTERVAL 5 /* hostname lookup failed. Wait N secs for next try */
/* Step threshold (sec). std ntpd uses 0.128.
*/
VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
}
-static void
-resolve_peer_hostname(peer_t *p, int loop_on_fail)
+static len_and_sockaddr*
+resolve_peer_hostname(peer_t *p)
{
- len_and_sockaddr *lsa;
-
- again:
- lsa = host2sockaddr(p->p_hostname, 123);
- if (!lsa) {
- /* error message already emitted by host2sockaddr() */
- if (!loop_on_fail)
- return;
-//FIXME: do this to avoid infinite looping on typo in a hostname?
-//well... in which case, what is a good value for loop_on_fail?
- //if (--loop_on_fail == 0)
- // xfunc_die();
- sleep(5);
- goto again;
+ len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123);
+ if (lsa) {
+ free(p->p_lsa);
+ free(p->p_dotted);
+ p->p_lsa = lsa;
+ p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
+ } else {
+ /* error message is emitted by host2sockaddr() */
+ set_next(p, HOSTNAME_INTERVAL);
}
- free(p->p_lsa);
- free(p->p_dotted);
- p->p_lsa = lsa;
- p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
+ return lsa;
}
static void
p = xzalloc(sizeof(*p) + strlen(s));
strcpy(p->p_hostname, s);
- resolve_peer_hostname(p, /*loop_on_fail=*/ 1);
+ p->p_fd = -1;
+ p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
+ p->next_action_time = G.cur_time; /* = set_next(p, 0); */
+ reset_peer_stats(p, STEP_THRESHOLD);
/* Names like N.<country2chars>.pool.ntp.org are randomly resolved
* to a pool of machines. Sometimes different N's resolve to the same IP.
* It is not useful to have two peers with same IP. We skip duplicates.
*/
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *pp = (peer_t *) item->data;
- if (strcmp(p->p_dotted, pp->p_dotted) == 0) {
- bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted);
- free(p->p_lsa);
- free(p->p_dotted);
- free(p);
- return;
+ if (resolve_peer_hostname(p)) {
+ for (item = G.ntp_peers; item != NULL; item = item->link) {
+ peer_t *pp = (peer_t *) item->data;
+ if (pp->p_dotted && strcmp(p->p_dotted, pp->p_dotted) == 0) {
+ bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted);
+ free(p->p_lsa);
+ free(p->p_dotted);
+ free(p);
+ return;
+ }
}
}
- p->p_fd = -1;
- p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
- p->next_action_time = G.cur_time; /* = set_next(p, 0); */
- reset_peer_stats(p, STEP_THRESHOLD);
-
llist_add_to(&G.ntp_peers, p);
G.peer_cnt++;
}
static void
send_query_to_peer(peer_t *p)
{
+ if (!p->p_lsa) {
+ if (!resolve_peer_hostname(p))
+ return;
+ }
+
/* Why do we need to bind()?
* See what happens when we don't bind:
*
IF_FEATURE_NTPD_SERVER("I:") /* compat */
"d" /* compat */
"46aAbgL", /* compat, ignored */
- &peers,&G.script_name,
+ &peers, &G.script_name,
#if ENABLE_FEATURE_NTPD_SERVER
&G.if_name,
#endif
if (opts & OPT_N)
setpriority(PRIO_PROCESS, 0, -15);
- /* add_peers() calls can retry DNS resolution (possibly forever).
- * Daemonize before them, or else boot can stall forever.
- */
if (!(opts & OPT_n)) {
bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);
logmode = LOGMODE_NONE;
/* What if don't see it because it changed its IP? */
if (p->reachable_bits == 0)
- resolve_peer_hostname(p, /*loop_on_fail=*/ 0);
+ resolve_peer_hostname(p);
set_next(p, timeout);
}