Ben,

I found a couple of bugs:
#1 an incomplete end of processing when the queried hostname can't be
found in the response. This lead to the query loop you may have
observed.
#2 an error in the way we parse CNAME responses, leading to return an
error when validating a CNAME (this triggers bug #1).

Please find in attachment a couple of patches you could give a try and
report whether you still have an issue or not.

Baptiste
From 67687363df5e2b5c82f12ecf2c560d22f9da795c Mon Sep 17 00:00:00 2001
From: Baptiste Assmann <bed...@gmail.com>
Date: Wed, 28 Oct 2015 02:03:32 +0100
Subject: [PATCH 1/2] BUG/MAJOR: dns: DNS response packet not matching queried
 hostname may lead to a loop

The status DNS_UPD_NAME_ERROR returned by dns_get_ip_from_response and
which means the queried name can't be found in the response was
improperly processed (fell into the default case).
This lead to a loop where HAProxy simply resend a new query as soon as
it got a response for this status

This should be backported into 1.6 branch
---
 src/server.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/server.c b/src/server.c
index dcc5961..0e0cab3 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2603,6 +2603,7 @@ int snr_resolution_cb(struct dns_resolution *resolution, struct dns_nameserver *
 			}
 			goto stop_resolution;
 
+		case DNS_UPD_NAME_ERROR:
 		case DNS_UPD_SRVIP_NOT_FOUND:
 			goto save_ip;
 
-- 
2.5.0

From c5f95cda9cf66db99d6088af4ecf82568a4602b4 Mon Sep 17 00:00:00 2001
From: Baptiste Assmann <bed...@gmail.com>
Date: Wed, 28 Oct 2015 02:10:02 +0100
Subject: [PATCH 2/2] BUG/MINOR: dns: unable to parse CNAMEs response

A bug lied in the parsing of DNS CNAME response, leading HAProxy to
think the CNAME was improperly resolved in the response.

This should be backported into 1.6 branch
---
 src/dns.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/dns.c b/src/dns.c
index 53b65ab..e28e2a9 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -628,8 +628,11 @@ int dns_get_ip_from_response(unsigned char *resp, unsigned char *resp_end,
 		else
 			ptr = reader;
 
-		if (cname && memcmp(ptr, cname, cnamelen))
-			return DNS_UPD_NAME_ERROR;
+		if (cname) {
+		       if (memcmp(ptr, cname, cnamelen)) {
+				return DNS_UPD_NAME_ERROR;
+			}
+		}
 		else if (memcmp(ptr, dn_name, dn_name_len))
 			return DNS_UPD_NAME_ERROR;
 
-- 
2.5.0

Reply via email to