Hi,
as I was trying to reproduce the issue with DNS Service Discovery with
SRV records reported in issue #775 I encountered a different issue.
I am using bind as a dns server, and its answers contain an Authority
field before the Additional records that can be made use of since
13a9232eb ("MEDIUM: dns: use Additional records from SRV responses").
I found out that haproxy doesn't like that and would just consider the
whole response invalid, no address being set for my servers.
I've attached a patch to test for the type and just skip to the next
record, and it seems to work. I'm not sure it's the proper fix, as we
might want to test for the presence of an Authority field.
Note that the same config "works" before that commit. I understand
haproxy makes a lot more DNS requests before that commit, but what I
mean is that users migrating from earlier versions to 2.2 can have their
service break because of this.
--
Jérôme
>From 9637655e5ee0d4d51056cbdb948f4c2b1da272e4 Mon Sep 17 00:00:00 2001
From: Jerome Magnin <[email protected]>
Date: Sun, 26 Jul 2020 12:13:12 +0200
Subject: [PATCH] BUG/MAJOR: dns: don't treat Authority records as an error
Support for DNS Service Discovery by means of SRV records was enhanced with
commit 13a9232eb ("MEDIUM: dns: use Additional records from SRV responses")
to use the content of the answers Additional records when present.
If there are Authority records before the Additional records we mistakenly
treat that as an invalid response. To fix this, we can skip to the next
record when the type is DNS_RTYPE_NS for the current record.
---
include/haproxy/dns-t.h | 1 +
src/dns.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/include/haproxy/dns-t.h b/include/haproxy/dns-t.h
index b1b43976c..1a8e6e49f 100644
--- a/include/haproxy/dns-t.h
+++ b/include/haproxy/dns-t.h
@@ -71,6 +71,7 @@ extern struct pool_head *dns_requester_pool;
/* dns record types (non exhaustive list) */
#define DNS_RTYPE_A 1 /* IPv4 address */
+#define DNS_RTYPE_NS 2 /* NS record type */
#define DNS_RTYPE_CNAME 5 /* canonical name */
#define DNS_RTYPE_AAAA 28 /* IPv6 address */
#define DNS_RTYPE_SRV 33 /* SRV record */
diff --git a/src/dns.c b/src/dns.c
index 6a8ab831c..b840bf9de 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1076,6 +1076,12 @@ static int dns_validate_dns_response(unsigned char
*resp, unsigned char *bufend,
dns_answer_record->type = reader[0] * 256 + reader[1];
reader += 2;
+ /* skip if record type is NS */
+ if (dns_answer_record->type == DNS_RTYPE_NS) {
+ pool_free(dns_answer_item_pool, dns_answer_record);
+ dns_answer_record = NULL;
+ continue;
+ }
/* 2 bytes for class (2) */
if (reader + 2 > bufend)
goto invalid_resp;
--
2.27.0