In case ntp cannot resolve a hostname on startup it will queue the entry
for resolving by a child process that, upon success, will add the entry to the config of the running running parent process. Unfortunately there are a couple of bugs with this, fixed in various later versions of upstream in potentially different ways due to other code changes: 1) Upon server [-46] <FQDN> the [-46] are used as FQDN for later resolving which does not work. Make sure we always pass the name (or IP there). 2) The intermediate file to carry the information to the child process does not know about -4/-6 restrictions, so that a dual-stacked host could resolve to an IPv6 address but that might be unreachable (see r223626) leading to no working synchronization ignoring a IPv4 record. Thus alter the intermediate format to also pass the address family (AF_UNSPEC (default), AF_INET or AF_INET6) to the child process depending on -4 or -6. 3) Make the child process to parse the new intermediate file format and save the address family for getaddrinfo() hints flags. 4) Change child to always reload resolv.conf calling res_init() before trying to resolve names. This will pick up resolv.conf changes or new resolv.confs should they have not existed or been empty or unusable on ntp startup. This fix is more conditional in upstream versions but given FreeBSD has res_init there is no need for the configure logic as well. Approved by: roberto Sponsored by: Sandvine Incorporated MFC after: 9 days
This commit is contained in:
parent
9527ec6e52
commit
2bddeb8538
@ -414,7 +414,7 @@ enum gnn_type {
|
||||
static int getnetnum P((const char *, struct sockaddr_storage *, int,
|
||||
enum gnn_type));
|
||||
static void save_resolve P((char *, int, int, int, int, u_int, int,
|
||||
keyid_t, u_char *));
|
||||
keyid_t, u_char *, u_char));
|
||||
static void do_resolve_internal P((void));
|
||||
static void abort_resolve P((void));
|
||||
#if !defined(VMS) && !defined(SYS_WINNT)
|
||||
@ -870,9 +870,9 @@ getconfig(
|
||||
stoa(&peeraddr));
|
||||
}
|
||||
} else if (errflg == -1) {
|
||||
save_resolve(tokens[1], hmode, peerversion,
|
||||
save_resolve(tokens[istart - 1], hmode, peerversion,
|
||||
minpoll, maxpoll, peerflags, ttl,
|
||||
peerkey, peerkeystr);
|
||||
peerkey, peerkeystr, peeraddr.ss_family);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2325,7 +2325,8 @@ save_resolve(
|
||||
u_int flags,
|
||||
int ttl,
|
||||
keyid_t keyid,
|
||||
u_char *keystr
|
||||
u_char *keystr,
|
||||
u_char peeraf
|
||||
)
|
||||
{
|
||||
#ifndef SYS_VXWORKS
|
||||
@ -2365,11 +2366,11 @@ save_resolve(
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)fprintf(res_fp, "%s %d %d %d %d %d %d %u %s\n", name,
|
||||
(void)fprintf(res_fp, "%s %u %d %d %d %d %d %d %u %s\n", name, peeraf,
|
||||
mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr);
|
||||
#ifdef DEBUG
|
||||
if (debug > 1)
|
||||
printf("config: %s %d %d %d %d %x %d %u %s\n", name, mode,
|
||||
printf("config: %s %u %d %d %d %d %x %d %u %s\n", name, peeraf, mode,
|
||||
version, minpoll, maxpoll, flags, ttl, keyid, keystr);
|
||||
#endif
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <signal.h>
|
||||
|
||||
/**/
|
||||
@ -111,15 +112,16 @@ static int resolve_value; /* next value of resolve timer */
|
||||
* is supposed to consist of entries in the following order
|
||||
*/
|
||||
#define TOK_HOSTNAME 0
|
||||
#define TOK_HMODE 1
|
||||
#define TOK_VERSION 2
|
||||
#define TOK_MINPOLL 3
|
||||
#define TOK_MAXPOLL 4
|
||||
#define TOK_FLAGS 5
|
||||
#define TOK_TTL 6
|
||||
#define TOK_KEYID 7
|
||||
#define TOK_KEYSTR 8
|
||||
#define NUMTOK 9
|
||||
#define TOK_PEERAF 1
|
||||
#define TOK_HMODE 2
|
||||
#define TOK_VERSION 3
|
||||
#define TOK_MINPOLL 4
|
||||
#define TOK_MAXPOLL 5
|
||||
#define TOK_FLAGS 6
|
||||
#define TOK_TTL 7
|
||||
#define TOK_KEYID 8
|
||||
#define TOK_KEYSTR 9
|
||||
#define NUMTOK 10
|
||||
|
||||
#define MAXLINESIZE 512
|
||||
|
||||
@ -140,7 +142,7 @@ char *req_file; /* name of the file with configuration info */
|
||||
static void checkparent P((void));
|
||||
static void removeentry P((struct conf_entry *));
|
||||
static void addentry P((char *, int, int, int, int, u_int,
|
||||
int, keyid_t, char *));
|
||||
int, keyid_t, char *, u_char));
|
||||
static int findhostaddr P((struct conf_entry *));
|
||||
static void openntp P((void));
|
||||
static int request P((struct conf_peer *));
|
||||
@ -397,7 +399,8 @@ addentry(
|
||||
u_int flags,
|
||||
int ttl,
|
||||
keyid_t keyid,
|
||||
char *keystr
|
||||
char *keystr,
|
||||
u_char peeraf
|
||||
)
|
||||
{
|
||||
register char *cp;
|
||||
@ -407,7 +410,7 @@ addentry(
|
||||
#ifdef DEBUG
|
||||
if (debug > 1)
|
||||
msyslog(LOG_INFO,
|
||||
"intres: <%s> %d %d %d %d %x %d %x %s\n", name,
|
||||
"intres: <%s> %u %d %d %d %d %x %d %x %s\n", name, peeraf,
|
||||
mode, version, minpoll, maxpoll, flags, ttl, keyid,
|
||||
keystr);
|
||||
#endif
|
||||
@ -422,6 +425,7 @@ addentry(
|
||||
ce->ce_peeraddr6 = in6addr_any;
|
||||
#endif
|
||||
ANYSOCK(&ce->peer_store);
|
||||
ce->peer_store.ss_family = peeraf; /* Save AF for getaddrinfo hints. */
|
||||
ce->ce_hmode = (u_char)mode;
|
||||
ce->ce_version = (u_char)version;
|
||||
ce->ce_minpoll = (u_char)minpoll;
|
||||
@ -482,7 +486,8 @@ findhostaddr(
|
||||
entry->ce_name));
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_family = entry->peer_store.ss_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
/*
|
||||
* If the IPv6 stack is not available look only for IPv4 addresses
|
||||
*/
|
||||
@ -1051,6 +1056,13 @@ readconf(
|
||||
}
|
||||
}
|
||||
|
||||
if (intval[TOK_PEERAF] != AF_UNSPEC && intval[TOK_PEERAF] !=
|
||||
AF_INET && intval[TOK_PEERAF] != AF_INET6) {
|
||||
msyslog(LOG_ERR, "invalid peer address family (%u) in "
|
||||
"file %s", intval[TOK_PEERAF], name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (intval[TOK_HMODE] != MODE_ACTIVE &&
|
||||
intval[TOK_HMODE] != MODE_CLIENT &&
|
||||
intval[TOK_HMODE] != MODE_BROADCAST) {
|
||||
@ -1107,7 +1119,7 @@ readconf(
|
||||
addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE],
|
||||
(int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL],
|
||||
(int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL],
|
||||
intval[TOK_KEYID], token[TOK_KEYSTR]);
|
||||
intval[TOK_KEYID], token[TOK_KEYSTR], (u_char)intval[TOK_PEERAF]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1129,6 +1141,9 @@ doconfigure(
|
||||
dores ? "with" : "without" );
|
||||
#endif
|
||||
|
||||
if (dores) /* Reload /etc/resolv.conf - bug 1226 */
|
||||
res_init();
|
||||
|
||||
ce = confentries;
|
||||
while (ce != NULL) {
|
||||
#ifdef DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user