From cf479e7190f4a2a86eb56946b672202ee7868639 Mon Sep 17 00:00:00 2001 From: Dmitry Chistikov Date: Fri, 3 Aug 2012 19:19:56 +0400 Subject: [PATCH] client.c: hackaround termination on EAFNOSUPPORT When socket() returns -1 with EAFNOSUPPORT, it does not necessarily mean that no future actions are possible. For instance, an IPv6 address may be included in DNS records while the environment has no support for it. In such a case, we continue as if socket() returned a correct descriptor, but the consequent connect() was unsuccessful. A better solution would forget an address from an unsupported family for good, since now we will stumble across it over and over again. Since client_nextaddr may now be given a peer with no open file descriptor, it will always check whether this is the case. --- openntpd/client.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/openntpd/client.c b/openntpd/client.c index 159a4cb..e534a1e 100644 --- a/openntpd/client.c +++ b/openntpd/client.c @@ -94,8 +94,10 @@ client_addr_init(struct ntp_peer *p) int client_nextaddr(struct ntp_peer *p) { - close(p->query->fd); - p->query->fd = -1; + if (p->query->fd != -1) { + close(p->query->fd); + p->query->fd = -1; + } if (p->addr_head.a == NULL) { priv_host_dns(p->addr_head.name, p->id); @@ -129,8 +131,14 @@ client_query(struct ntp_peer *p) struct sockaddr *sa = (struct sockaddr *)&p->addr->ss; if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM, - 0)) == -1) - fatal("client_query socket"); + 0)) == -1) { + if (errno == EAFNOSUPPORT) { + client_nextaddr(p); + set_next(p, error_interval()); + return (-1); + } else + fatal("client_query socket"); + } if (connect(p->query->fd, sa, SA_LEN(sa)) == -1) { if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH) { -- 1.7.8.4