Skip to content
Snippets Groups Projects
Commit 340849a9 authored by Daniel P. Berrangé's avatar Daniel P. Berrangé Committed by Paolo Bonzini
Browse files

util: retry getaddrinfo if getting EAI_BADFLAGS with AI_V4MAPPED


The FreeBSD header files define the AI_V4MAPPED but its
implementation of getaddrinfo() always returns an error
when that flag is set. eg

  address resolution failed for localhost:9000: Invalid value for ai_flags

There are also reports of the same problem on OS-X 10.6

Since AI_V4MAPPED is not critical functionality, if we
get an EAI_BADFLAGS error then just retry without the
AI_V4MAPPED flag set. Use a static var to cache this
status so we don't have to retry on every single call.

Also remove its use from the test suite since it serves
no useful purpose there.

Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
Message-Id: <1459786920-15961-1-git-send-email-berrange@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent f0707d2e
No related branches found
No related tags found
No related merge requests found
......@@ -27,9 +27,6 @@
#ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0
#endif
#ifndef AI_V4MAPPED
# define AI_V4MAPPED 0
#endif
#ifndef EAI_ADDRFAMILY
# define EAI_ADDRFAMILY 0
#endif
......@@ -42,7 +39,7 @@ static int check_bind(const char *hostname, bool *has_proto)
int ret = -1;
memset(&ai, 0, sizeof(ai));
ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG;
ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
ai.ai_family = AF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
......
......@@ -29,6 +29,7 @@
#ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0
#endif
#ifndef AI_V4MAPPED
# define AI_V4MAPPED 0
#endif
......@@ -354,10 +355,14 @@ static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr,
struct addrinfo ai, *res;
int rc;
Error *err = NULL;
static int useV4Mapped = 1;
memset(&ai, 0, sizeof(ai));
ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG;
ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
if (atomic_read(&useV4Mapped)) {
ai.ai_flags |= AI_V4MAPPED;
}
ai.ai_family = inet_ai_family_from_address(saddr, &err);
ai.ai_socktype = SOCK_STREAM;
......@@ -373,6 +378,18 @@ static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr,
/* lookup */
rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
/* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but
* then don't implement it in their getaddrinfo(). Detect
* this and retry without the flag since that's preferrable
* to a fatal error
*/
if (rc == EAI_BADFLAGS &&
(ai.ai_flags & AI_V4MAPPED)) {
atomic_set(&useV4Mapped, 0);
ai.ai_flags &= ~AI_V4MAPPED;
rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
}
if (rc != 0) {
error_setg(errp, "address resolution failed for %s:%s: %s",
saddr->host, saddr->port, gai_strerror(rc));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment