[ntp:bk-ntp-dev-send] BitKeeper diffs

Harlan Stenn stenn at whimsy.udel.edu
Sat Feb 13 11:04:30 UTC 2010


#### ChangeSet ####
2010-02-09 18:19:12+00:00, davehart at shiny.ad.hartbrothers.com 
  [Bug 1483] hostname in ntp.conf "restrict" parameter rejected.
  Use all addresses for each restrict by hostname.
  Use async DNS to resolve trap directive hostnames.
  

==== ChangeLog ====
2010-02-09 18:19:11+00:00, davehart at shiny.ad.hartbrothers.com +3 -0
  [Bug 1483] hostname in ntp.conf "restrict" parameter rejected.
  Use all addresses for each restrict by hostname.
  Use async DNS to resolve trap directive hostnames.
  

--- 1.533/ChangeLog	2010-02-07 05:31:12 -05:00
+++ 1.533.2.1/ChangeLog	2010-02-09 13:19:11 -05:00
@@ -1,3 +1,6 @@
+* [Bug 1483] hostname in ntp.conf "restrict" parameter rejected.
+* Use all addresses for each restrict by hostname.
+* Use async DNS to resolve trap directive hostnames.
 (4.2.7p18) 2010/02/07 Released by Harlan Stenn <stenn at ntp.org>
 * Include (4.2.6p1-RC5) - [Bug 1480] snprintf() cleanup caused 
   unterminated refclock IDs.

==== include/ntp_config.h ====
2010-02-09 18:19:11+00:00, davehart at shiny.ad.hartbrothers.com +13 -2
  add settrap_params structure for trap_name_resolved()

--- 1.67/include/ntp_config.h	2009-12-24 02:25:57 -05:00
+++ 1.68/include/ntp_config.h	2010-02-09 13:19:11 -05:00
@@ -76,8 +76,8 @@ struct attr_val {
 
 /* Structure for nodes on the syntax tree */
 struct address_node {
-    char *address;
-    int type;
+	char *address;
+	short type;	/* family, AF_UNSPEC (0), AF_INET, AF_INET6 */
 };
 
 struct restrict_node {
@@ -197,6 +197,17 @@ struct REMOTE_CONFIG_INFO {
 	int err_pos;
 	int no_errors;
 };
+
+
+/*
+ * context for trap_name_resolved() to call ctlsettrap() once the 
+ * name->address resolution completes.
+ */
+typedef struct settrap_parms_tag {
+	sockaddr_u	ifaddr;
+	int		ifaddr_nonnull;
+} settrap_parms;
+
 
 /* get text from T_ tokens */
 const char * token_name(int token);

==== include/ntp_stdlib.h ====
2010-02-09 18:19:11+00:00, davehart at shiny.ad.hartbrothers.com +4 -0
  add localaddrtoa() alias latoa() macro evaluating to text of
    a given struct interface *'s local address, or <null> in the
    case of a NULL struct interface *.

--- 1.41/include/ntp_stdlib.h	2010-01-27 13:45:23 -05:00
+++ 1.42/include/ntp_stdlib.h	2010-02-09 13:19:11 -05:00
@@ -102,6 +102,10 @@ extern	sockaddr_u * netof	(sockaddr_u *)
 extern	char *	numtoa		(u_int32);
 extern	char *	numtohost	(u_int32);
 extern	char *	socktoa		(sockaddr_u *);
+#define	localaddrtoa(pif)	((NULL == (pif))		\
+				     ? "<null>"			\
+				     : socktoa(&((pif)->sin)))
+#define		latoa(pif)	localaddrtoa(pif)
 extern	char *	socktohost	(sockaddr_u *);
 extern	int	octtoint	(const char *, u_long *);
 extern	u_long	ranp2		(int);

==== ntpd/ntp_config.c ====
2010-02-09 18:19:11+00:00, davehart at shiny.ad.hartbrothers.com +177 -25
  [Bug 1483] use blocking DNS resolution for restrict hostnames.
  Use all addresses resolved from a restrict hostname, instead
    of only the first.
  Use async DNS for trap directive hostnames.

--- 1.246/ntpd/ntp_config.c	2010-02-06 00:22:43 -05:00
+++ 1.247/ntpd/ntp_config.c	2010-02-09 13:19:11 -05:00
@@ -269,6 +269,9 @@ void peer_name_resolved(int, int, void *
 void unpeer_name_resolved(int, int, void *, const char *, const char *,
 			  const struct addrinfo *,
 			  const struct addrinfo *);
+void trap_name_resolved(int, int, void *, const char *, const char *,
+			const struct addrinfo *,
+			const struct addrinfo *);
 #endif
 
 enum gnn_type {
@@ -1195,11 +1198,13 @@ create_address_node(
 	struct address_node *my_node;
 
 	NTP_REQUIRE(NULL != addr);
+	NTP_REQUIRE(AF_INET == type || 
+		    AF_INET6 == type || AF_UNSPEC == type);
 	
 	my_node = get_node(sizeof *my_node);
 
 	my_node->address = addr;
-	my_node->type = type;
+	my_node->type = (short)type;
 
 	return my_node;
 }
@@ -2062,6 +2067,10 @@ config_access(
 	int *			curr_flag;
 	sockaddr_u		addr_sock;
 	sockaddr_u		addr_mask;
+	struct addrinfo		hints;
+	struct addrinfo *	ai_list;
+	struct addrinfo *	pai;
+	int			rc;
 	int			flags;
 	int			mflags;
 	int			restrict_default;
@@ -2105,6 +2114,8 @@ config_access(
 	     my_node = next_node(my_node)) {
 
 		ZERO_SOCK(&addr_sock);
+		ai_list = NULL;
+		pai = NULL;
 
 		if (NULL == my_node->addr) {
 			/*
@@ -2120,11 +2131,41 @@ config_access(
 
 			if (getnetnum(my_node->addr->address,
 				      &addr_sock, 1, t_UNK) != 1) {
-
-				msyslog(LOG_ERR,
-					"restrict: error in address '%s' on line %d. Ignoring...",
-					my_node->addr->address, my_node->line_no);
-				continue;
+				/*
+				 * Attempt a blocking lookup.  This
+				 * is in violation of the nonblocking
+				 * design of ntpd's mainline code.  The
+				 * alternative of running without the
+				 * restriction until the name resolved
+				 * seems worse.
+				 * Ideally some scheme could be used for
+				 * restrict directives in the startup
+				 * ntp.conf to delay starting up the
+				 * protocol machinery until after all
+				 * restrict hosts have been resolved.
+				 */
+				ai_list = NULL;
+				memset(&hints, 0, sizeof(hints));
+				hints.ai_protocol = IPPROTO_UDP;
+				hints.ai_socktype = SOCK_DGRAM;
+				hints.ai_family = my_node->addr->type;
+				rc = getaddrinfo(my_node->addr->address,
+						 "ntp", &hints,
+						 &ai_list);
+				if (rc) {
+					msyslog(LOG_ERR,
+						"restrict: ignoring line %d, address/host '%s' unusable.",
+						my_node->line_no,
+						my_node->addr->address);
+					continue;
+				}
+				NTP_INSIST(ai_list != NULL);
+				pai = ai_list;
+				NTP_INSIST(pai->ai_addr != NULL);
+				NTP_INSIST(sizeof(addr_sock) >= pai->ai_addrlen);
+				memcpy(&addr_sock, pai->ai_addr, pai->ai_addrlen);
+				NTP_INSIST(AF_INET == AF(&addr_sock) ||
+					   AF_INET6 == AF(&addr_sock));
 			}
 
 			SET_HOSTMASK(&addr_mask, AF(&addr_sock));
@@ -2133,11 +2174,12 @@ config_access(
 			if (my_node->mask) {
 				ZERO_SOCK(&addr_mask);
 				AF(&addr_mask) = (u_short)my_node->mask->type;
-				if (getnetnum(my_node->mask->address, &addr_mask, 1, t_MSK) != 1) {
-
+				if (getnetnum(my_node->mask->address,
+					      &addr_mask, 1, t_MSK) != 1) {
 					msyslog(LOG_ERR,
-						"restrict: error in mask '%s' on line %d. Ignoring...",
-						my_node->mask->address, my_node->line_no);
+						"restrict: ignoring line %d, mask '%s' unusable.",
+						my_node->line_no,
+						my_node->mask->address);
 					continue;
 				}
 			}
@@ -2217,14 +2259,30 @@ config_access(
 		/* Set the flags */
 		if (restrict_default) {
 			AF(&addr_sock) = AF_INET;
-			hack_restrict(RESTRICT_FLAGS, &addr_sock, &addr_mask,
-				      mflags, flags);
-
+			AF(&addr_mask) = AF_INET;
+			hack_restrict(RESTRICT_FLAGS, &addr_sock,
+				      &addr_mask, mflags, flags);
 			AF(&addr_sock) = AF_INET6;
+			AF(&addr_mask) = AF_INET6;
 		}
 
-		hack_restrict(RESTRICT_FLAGS, &addr_sock, &addr_mask,
-			      mflags, flags);
+		do {
+			hack_restrict(RESTRICT_FLAGS, &addr_sock,
+				      &addr_mask, mflags, flags);
+			if (pai != NULL &&
+			    NULL != (pai = pai->ai_next)) {
+				NTP_INSIST(pai->ai_addr != NULL);
+				NTP_INSIST(sizeof(addr_sock) >= pai->ai_addrlen);
+				ZERO_SOCK(&addr_sock);
+				memcpy(&addr_sock, pai->ai_addr, pai->ai_addrlen);
+				NTP_INSIST(AF_INET == AF(&addr_sock) ||
+					   AF_INET6 == AF(&addr_sock));
+				SET_HOSTMASK(&addr_mask, AF(&addr_sock));
+			}
+		} while (pai != NULL);
+
+		if (ai_list != NULL)
+			freeaddrinfo(ai_list);
 
 		if ((RES_MSSNTP & flags) && !warned_signd) {
 			warned_signd = 1;
@@ -2819,8 +2877,12 @@ config_trap(
 	sockaddr_u peeraddr;
 	struct address_node *addr_node;
 	struct interface *localaddr;
-	u_short port_no;
+	struct addrinfo hints;
+	char port_text[8];
+	settrap_parms *pstp;
+	u_short port;
 	int err_flag;
+	int rc;
 
 	/* silence warning about addr_sock potentially uninitialized */
 	AF(&addr_sock) = AF_UNSPEC;
@@ -2830,7 +2892,7 @@ config_trap(
 	     curr_trap = next_node(curr_trap)) {
 
 		err_flag = 0;
-		port_no = 0;
+		port = 0;
 		localaddr = NULL;
 
 		curr_opt = queue_head(curr_trap->options);
@@ -2844,7 +2906,7 @@ config_trap(
 						curr_opt->value.i);
 					err_flag = 1;
 				}
-				port_no = (u_short)curr_opt->value.i;
+				port = (u_short)curr_opt->value.i;
 			}
 			else if (T_Interface == curr_opt->attr) {
 				addr_node = curr_opt->value.p;
@@ -2875,13 +2937,52 @@ config_trap(
 		 * and port number
 		 */
 		if (!err_flag) {
+			if (!port)
+				port = TRAPPORT;
 			ZERO_SOCK(&peeraddr);
-			if (1 != getnetnum(curr_trap->addr->address,
-					   &peeraddr, 1, t_UNK))
+			rc = getnetnum(curr_trap->addr->address,
+				       &peeraddr, 1, t_UNK);
+			if (1 != rc) {
+#ifndef WORKER
+				msyslog(LOG_ERR,
+					"trap: unable to use IP address %s.",
+					curr_trap->addr->address);
+#else	/* WORKER follows */
+				/*
+				 * save context and hand it off
+				 * for name resolution.
+				 */
+				memset(&hints, 0, sizeof(hints));
+				hints.ai_protocol = IPPROTO_UDP;
+				hints.ai_socktype = SOCK_DGRAM;
+				snprintf(port_text, sizeof(port_text),
+					 "%u", port);
+				hints.ai_flags = AI_NUMERICSERV;
+				pstp = emalloc(sizeof(*pstp));
+				memset(pstp, 0, sizeof(*pstp));
+				if (localaddr != NULL) {
+					hints.ai_family = localaddr->family;
+					pstp->ifaddr_nonnull = 1;
+					memcpy(&pstp->ifaddr,
+					       &localaddr->sin,
+					       sizeof(pstp->ifaddr));
+				}
+				rc = getaddrinfo_sometime(
+					curr_trap->addr->address,
+					port_text,
+					&hints,
+					&trap_name_resolved,
+					pstp);
+				if (!rc)
+					msyslog(LOG_ERR,
+						"config_trap: getaddrinfo_sometime(%s,%s): %m",
+						curr_trap->addr->address,
+						port_text);
+#endif	/* WORKER */
 				continue;
-
+			}
 			/* port is at same location for v4 and v6 */
-			SET_PORT(&peeraddr, port_no ? port_no : TRAPPORT);
+			SET_PORT(&peeraddr, port);
 
 			if (NULL == localaddr)
 				localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
@@ -2891,13 +2992,59 @@ config_trap(
 			if (!ctlsettrap(&peeraddr, localaddr, 0,
 					NTP_VERSION))
 				msyslog(LOG_ERR,
-					"can't set trap for %s",
+					"set trap %s -> %s failed.",
+					latoa(localaddr),
 					stoa(&peeraddr));
 		}
 	}
 }
 
 
+/*
+ * trap_name_resolved()
+ *
+ * Callback invoked when config_trap()'s DNS lookup completes.
+ */
+#ifdef WORKER
+void
+trap_name_resolved(
+	int			rescode,
+	int			gai_errno,
+	void *			context,
+	const char *		name,
+	const char *		service,
+	const struct addrinfo *	hints,
+	const struct addrinfo *	res
+	)
+{
+	settrap_parms *pstp;
+	struct interface *localaddr;
+	sockaddr_u peeraddr;
+
+	pstp = context;
+	if (rescode) {
+		msyslog(LOG_ERR,
+			"giving up resolving trap host %s: %s (%d)",
+			name, gai_strerror(rescode), rescode);
+		free(pstp);
+		return;
+	}
+	NTP_INSIST(sizeof(peeraddr) >= res->ai_addrlen);
+	memset(&peeraddr, 0, sizeof(peeraddr));
+	memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
+	localaddr = NULL;
+	if (pstp->ifaddr_nonnull)
+		localaddr = findinterface(&pstp->ifaddr);
+	if (NULL == localaddr)
+		localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
+	if (!ctlsettrap(&peeraddr, localaddr, 0, NTP_VERSION))
+		msyslog(LOG_ERR, "set trap %s -> %s failed.",
+			latoa(localaddr), stoa(&peeraddr));
+	free(pstp);
+}
+#endif	/* WORKER */
+
+
 #ifdef FREE_CFG_T
 static void
 free_config_trap(
@@ -4281,7 +4428,8 @@ gettokens_netinfo (
 /*
  * getnetnum - return a net number (this is crude, but careful)
  *
- * returns 1 for success, and mysteriously, 0 or -1 for failure
+ * returns 1 for success, and mysteriously, 0 for most failures, and
+ * -1 if the address found is IPv6 and we believe IPv6 isn't working.
  */
 static int
 getnetnum(
@@ -4293,7 +4441,11 @@ getnetnum(
 {
 	isc_netaddr_t ipaddr;
 
-	if (!is_ip_address(num, AF_UNSPEC, &ipaddr))
+	NTP_REQUIRE(AF_UNSPEC == AF(addr) ||
+		    AF_INET == AF(addr) ||
+		    AF_INET6 == AF(addr));
+
+	if (!is_ip_address(num, AF(addr), &ipaddr))
 		return 0;
 
 	if (AF_INET6 == ipaddr.family && !ipv6_works)

==== ntpd/ntp_peer.c ====
2010-02-09 18:19:11+00:00, davehart at shiny.ad.hartbrothers.com +4 -6
  use latoa(peer->dstadr) instead of more verbose equivalent.

--- 1.126/ntpd/ntp_peer.c	2009-11-24 09:51:37 -05:00
+++ 1.127/ntpd/ntp_peer.c	2010-02-09 13:19:11 -05:00
@@ -561,8 +561,7 @@ peer_refresh_interface(
 	{
 		printf(
 		    "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
-		    peer->dstadr == NULL ? "<null>" :
-		    stoa(&peer->dstadr->sin), stoa(&peer->srcadr),
+		    latoa(peer->dstadr), stoa(&peer->srcadr),
 		    peer->hmode, peer->version, peer->minpoll,
 		    peer->maxpoll, peer->flags, peer->cast_flags,
 		    peer->ttl, peer->keyid);
@@ -892,10 +891,9 @@ newpeer(
 	snprintf(tbuf, sizeof(tbuf), "assoc %d", peer->associd);
 	report_event(PEVNT_MOBIL, peer, tbuf);
 	DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
-	    peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
-	    stoa(&peer->srcadr), peer->hmode, peer->version,
-	    peer->minpoll, peer->maxpoll, peer->flags, peer->cast_flags,
-	    peer->ttl, peer->keyid));
+	    latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
+	    peer->version, peer->minpoll, peer->maxpoll, peer->flags,
+	    peer->cast_flags, peer->ttl, peer->keyid));
 	return (peer);
 }
 

==== ntpd/ntp_restrict.c ====
2010-02-09 18:19:12+00:00, davehart at shiny.ad.hartbrothers.com +5 -5
  DPRINTF args to hack_restrict() for v6 as well as v4 addresses.

--- 1.27/ntpd/ntp_restrict.c	2009-06-14 23:46:09 -04:00
+++ 1.28/ntpd/ntp_restrict.c	2010-02-09 13:19:12 -05:00
@@ -272,14 +272,14 @@ hack_restrict(
 	register struct restrictlist6 *rl6 = NULL;
 	register struct restrictlist6 *rlprev6 = NULL;
 	int i, addr_cmp, mask_cmp;
-	memset(&addr6, 0, sizeof(struct in6_addr)); 
-	memset(&mask6, 0, sizeof(struct in6_addr)); 
 
-	if (IS_IPV4(resaddr)) {
+	DPRINTF(1, ("restrict: addr %s mask %s mflags %08x flags %08x\n",
+		    stoa(resaddr), stoa(resmask), mflags, flags));
 
-		DPRINTF(1, ("restrict: addr %08x mask %08x mflags %08x flags %08x\n",
-			    SRCADR(resaddr), SRCADR(resmask), mflags, flags));
+	memset(&addr6, 0, sizeof(addr6)); 
+	memset(&mask6, 0, sizeof(mask6)); 
 
+	if (IS_IPV4(resaddr)) {
 		/*
 		 * Get address and mask in host byte order
 		 */


More information about the bk-ntp-dev-send mailing list