[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