Hello,

On 04/11/2014 12:23 PM, Manuel Bauer wrote:
> Good idea, but that seems to work only with ip addresses, and not hostnames. 
> If I try it haproxy complains about an error in its config and refuses to 
> start.
> 
> 
> On Fri, 11 Apr 2014 12:04:40 +0200, Nenad Merdanovic <ni...@nimzo.info> wrote:
> 
>> Hello,
>>
>> On 04/11/2014 11:15 AM, Manuel Bauer wrote:
>>> sorry for what is probably a pretty noob question, but could anyone tell me 
>>> why haproxy resolves the hostnames in my config to ipv4 addresses, and not 
>>> ipv6? If I run a tcpdump on port 53 during a haproxy restart I can see that 
>>> only the A records are being queried.
>>>
>>> However, if I curl one of the URLs manually on that server I see that both 
>>> A and AAAA records are queried, and that ipv6 is being used successfully 
>>> when making the connection. 
>>>
>>> Is there a setting or patch I can use to convince haproxy to use ipv6?
>>>
>>> I use haproxy 1.5-dev22, compiled it with GETADDRINFO=1, and run it on 
>>> Debian 7 stable, 32-bit
>>>
>>> Thanks
>>>
>>
>> Try adding the 'ipv6@' keyword in front of the hostname as shown here:
>> http://cbonte.github.io/haproxy-dconv/snapshot/configuration-1.5.html#4.2-server
>>
>> Regards,
>> -- 
>> Nenad Merdanovic | PGP: 0x423edcb2 | Web: http://nimzo.info
>> Linkedin: http://www.linkedin.com/in/nenadmerdanovic
> 

// CCing Willy

Why are we using gethostbyname() first if USE_GETADDRINFO is enabled?
This causes problems with IPv6 lookups in a sense that IPv4 will get
returned if it exists, before trying IPv6 (If options inet6 is not set
in /etc/resolv.conf). When this happens, we fail on (src/standard.c):

561                else if (sa->ss_family != he->h_addrtype)
562                        goto fail;

Since gethostbyname() is depreciated, I think we should be using
getaddrinfo() first (if USE_GETADDRINFO=1)

I have attached a quick and super-dirty fix, so whoever wants to rewrite
it go ahead. If it's OK, I'll submit it properly.

Regards,
-- 
Nenad Merdanovic | PGP: 0x423edcb2 | Web: http://nimzo.info
Linkedin: http://www.linkedin.com/in/nenadmerdanovic
diff --git a/src/standard.c b/src/standard.c
index 569ecaa..5f43a4e 100644
--- a/src/standard.c
+++ b/src/standard.c
@@ -520,7 +520,12 @@ const char *invalid_domainchar(const char *name) {
  */
 static struct sockaddr_storage *str2ip(const char *str, struct sockaddr_storage *sa)
 {
+
+#ifdef USE_GETADDRINFO
+	struct addrinfo hints, *result;
+#else
 	struct hostent *he;
+#endif
 
 	/* Any IPv6 address */
 	if (str[0] == ':' && str[1] == ':' && !str[2]) {
@@ -552,6 +557,33 @@ static struct sockaddr_storage *str2ip(const char *str, struct sockaddr_storage
 		return sa;
 	}
 
+#ifdef USE_GETADDRINFO
+    memset(&result, 0, sizeof(result));
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = sa->ss_family ? sa->ss_family : AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_flags = AI_PASSIVE;
+    hints.ai_protocol = 0;
+
+    if (getaddrinfo(str, NULL, &hints, &result) == 0) {
+        if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
+            sa->ss_family = result->ai_family;
+        else if (sa->ss_family != result->ai_family)
+            goto fail;
+
+        switch (result->ai_family) {
+        case AF_INET:
+            memcpy((struct sockaddr_in *)sa, result->ai_addr, result->ai_addrlen);
+            return sa;
+        case AF_INET6:
+            memcpy((struct sockaddr_in6 *)sa, result->ai_addr, result->ai_addrlen);
+            return sa;
+        }
+    }
+
+    if (result)
+        freeaddrinfo(result);
+#else
 	/* try to resolve an IPv4/IPv6 hostname */
 	he = gethostbyname(str);
 	if (he) {
@@ -569,36 +601,7 @@ static struct sockaddr_storage *str2ip(const char *str, struct sockaddr_storage
 			return sa;
 		}
 	}
-#ifdef USE_GETADDRINFO
-	else {
-		struct addrinfo hints, *result;
-
-		memset(&result, 0, sizeof(result));
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = sa->ss_family ? sa->ss_family : AF_UNSPEC;
-		hints.ai_socktype = SOCK_DGRAM;
-		hints.ai_flags = AI_PASSIVE;
-		hints.ai_protocol = 0;
-
-		if (getaddrinfo(str, NULL, &hints, &result) == 0) {
-			if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
-				sa->ss_family = result->ai_family;
-			else if (sa->ss_family != result->ai_family)
-				goto fail;
-
-			switch (result->ai_family) {
-			case AF_INET:
-				memcpy((struct sockaddr_in *)sa, result->ai_addr, result->ai_addrlen);
-				return sa;
-			case AF_INET6:
-				memcpy((struct sockaddr_in6 *)sa, result->ai_addr, result->ai_addrlen);
-				return sa;
-			}
-		}
 
-		if (result)
-			freeaddrinfo(result);
-	}
 #endif
 	/* unsupported address family */
  fail:

Reply via email to