[ntp:hackers] gorilla wrangler with Unix chops soliticited

Dave Hart davehart at gmail.com
Mon Jun 1 07:31:51 UTC 2009


I have updated the code on pogo:~hart/ntp-dev-block with a lot of
cleanup of warnings and no longer leak any allocated memory on
Windows.  I added an async getnameinfo interface, but nothing in ntpd
currently does address to name lookups, so it's only exercised by test
code.  After ntp.conf is processed, a handful of pointless async
getaddrinfo name -> address lookups are started, and for each address
returned, a reverse lookup is performed using the new async
getnameinfo.

I'm still hoping for some help on the Unix side.  On the plus side, a
lingering ntpd on the previously mentioned system where i have sudo
ntpd privs but not root has been cleaned up, so I should be able to
bumble ahead myself.

To give the curious a flavor of the new interface, below is the only
non-test consumer, the ntp_config.c code which processes association
directives in ntp.conf.

Cheers,
Dave Hart


static void
config_peers(void)
{
	struct sockaddr_storage	peeraddr;
	isc_netaddr_t		i_netaddr;
	struct addrinfo		hints;
	struct peer_node *	curr_peer;
	int			hmode;
	int			num_needed;

	while (!empty(my_config.peers)) {
		curr_peer = (struct peer_node *) dequeue(my_config.peers);

		/* Find the number of associations needed.
		 * If a pool coomand is specified, then sys_maxclock needed
		 * else, only one is needed
		 */
		num_needed = (curr_peer->host_mode == T_Pool) ? sys_maxclock : 1;

		/* Find the correct host-mode */
		hmode = get_correct_host_mode(curr_peer->host_mode);

		/*
		 * If we have a numeric address, we can safely use
		 * getaddrinfo in the mainline with it.  Otherwise
		 * hand it off to the blocking child.
		 */
		memset(&i_netaddr, 0, sizeof(i_netaddr));
		i_netaddr.family = (u_short)curr_peer->addr->type;

		if (1 == num_needed
		    && is_ip_address(curr_peer->addr->address, &i_netaddr)) {

			peeraddr.ss_family = (u_short)i_netaddr.family;
			if (AF_INET6 == i_netaddr.family)
				((struct sockaddr_in6 *)&peeraddr)->sin6_addr =
					i_netaddr.type.in6;
			else
				((struct sockaddr_in *)&peeraddr)->sin_addr =
					i_netaddr.type.in;

			if (is_sane_resolved_address(peeraddr,
			    curr_peer->host_mode))
				peer_config(&peeraddr,
				ANY_INTERFACE_CHOOSE(&peeraddr),
				    hmode,
				    curr_peer->peerversion,
				    curr_peer->minpoll,
				    curr_peer->maxpoll,
				    curr_peer->peerflags,
				    curr_peer->ttl,
				    curr_peer->peerkey,
				    (u_char *)"*");
		} else {

			/* we have a hostname to resolve */
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = (u_short)curr_peer->addr->type;
			getaddrinfo_sometime(curr_peer->addr->address, "ntp",
					     &hints, 2, peer_name_resolved,
					     (void *)curr_peer);
			curr_peer = NULL;
		}

		/* Ok, everything done. Free up peer node memory */
		if (curr_peer != NULL) {
			destroy_address_node(curr_peer->addr);
			free_node(curr_peer);
		}
	}
}


void
peer_name_resolved(
	int			retcode,
	int			gai_errno,
	void *			context,
	const char *		name,
	const char *		service,
	const struct addrinfo *	ai_in,
	const struct addrinfo *	res
	)
{
	struct sockaddr_storage peeraddr;
	struct peer_node *curr_peer;
	int num_needed;
	int hmode;
	int i;

	curr_peer = context;

	if (retcode) {
		msyslog(LOG_ERR, "giving up on resolving host %s %s",
			name, gai_strerror(retcode));
		destroy_address_node(curr_peer->addr);
		free_node(curr_peer);
		return;
	}

	hmode = get_correct_host_mode(curr_peer->host_mode);
	num_needed = (T_Pool == curr_peer->host_mode)
			? sys_maxclock
			: 1;
	/*
	 * Loop to configure the desired number of
	 * associations
	 */
	for (i = 0;
	     res != NULL && i < num_needed;
	     res = res->ai_next) {

		memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
		if (is_sane_resolved_address(peeraddr, curr_peer->host_mode)) {
			i++;
			peer_config(
				&peeraddr,
				ANY_INTERFACE_CHOOSE(&peeraddr),
				hmode,
				curr_peer->peerversion,
				curr_peer->minpoll,
				curr_peer->maxpoll,
				curr_peer->peerflags,
				curr_peer->ttl,
				curr_peer->peerkey,
				(u_char *)"*");
		}
	}

	destroy_address_node(curr_peer->addr);
	free_node(curr_peer);
}


More information about the hackers mailing list