svn commit: r223667 - head/contrib/ntp/ntpd

Bjoern A. Zeeb bz at FreeBSD.org
Wed Jun 29 13:01:10 UTC 2011


Author: bz
Date: Wed Jun 29 13:01:10 2011
New Revision: 223667
URL: http://svn.freebsd.org/changeset/base/223667

Log:
  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

Modified:
  head/contrib/ntp/ntpd/ntp_config.c
  head/contrib/ntp/ntpd/ntp_intres.c

Modified: head/contrib/ntp/ntpd/ntp_config.c
==============================================================================
--- head/contrib/ntp/ntpd/ntp_config.c	Wed Jun 29 10:06:58 2011	(r223666)
+++ head/contrib/ntp/ntpd/ntp_config.c	Wed Jun 29 13:01:10 2011	(r223667)
@@ -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
 

Modified: head/contrib/ntp/ntpd/ntp_intres.c
==============================================================================
--- head/contrib/ntp/ntpd/ntp_intres.c	Wed Jun 29 10:06:58 2011	(r223666)
+++ head/contrib/ntp/ntpd/ntp_intres.c	Wed Jun 29 13:01:10 2011	(r223667)
@@ -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 
  * 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 wit
 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


More information about the svn-src-all mailing list