]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: dns: no expected DNS record type found
authorBaptiste Assmann <bedis9@gmail.com>
Tue, 8 Sep 2015 22:46:58 +0000 (00:46 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 10 Sep 2015 13:41:53 +0000 (15:41 +0200)
Some DNS responses may be valid from a protocol point of view, but may
not contain any information considered as interested by the requester..
Purpose of the flag DNS_RESP_NO_EXPECTED_RECORD introduced by this patch is
to allow reporting such situation.

When this happens, a new DNS query is sent with a new query type.

For now, the function only expect A and AAAA query types which is enough
to cover current cases.
In a next future, it will be up to the caller to tell the function which
query types are expected.

include/types/dns.h
src/dns.c
src/server.c

index 3ec3492520d78de441700f9625e3853b8c9a2f1b..59b59c7654c7df3d985b2d9614776daedbd3a0d6 100644 (file)
@@ -199,6 +199,7 @@ enum {
        DNS_RESP_CNAME_ERROR,           /* error when resolving a CNAME in an atomic response */
        DNS_RESP_TIMEOUT,               /* DNS server has not answered in time */
        DNS_RESP_TRUNCATED,             /* DNS response is truncated */
+       DNS_RESP_NO_EXPECTED_RECORD,    /* No expected records were found in the response */
 };
 
 /* return codes after searching an IP in a DNS response buffer, using a family preference */
index ec3c9d1ee3ad96987a577184595f8acb74051d19..4dfe697906f482665750d0e024ecee0d881cc20c 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -222,6 +222,11 @@ void dns_resolve_recv(struct dgram_conn *dgram)
                        nameserver->counters.truncated += 1;
                        resolution->requester_error_cb(resolution, DNS_RESP_TRUNCATED);
                        continue;
+
+               case DNS_RESP_NO_EXPECTED_RECORD:
+                       nameserver->counters.other += 1;
+                       resolution->requester_error_cb(resolution, DNS_RESP_NO_EXPECTED_RECORD);
+                       continue;
                }
 
                nameserver->counters.valid += 1;
@@ -334,12 +339,18 @@ void dns_update_resolvers_timeout(struct dns_resolvers *resolvers)
 int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char *dn_name, int dn_name_len)
 {
        unsigned char *reader, *cname, *ptr;
-       int i, len, flags, type, ancount, cnamelen;
+       int i, len, flags, type, ancount, cnamelen, expected_record;
 
        reader = resp;
        cname = NULL;
        cnamelen = 0;
        len = 0;
+       expected_record = 0; /* flag to report if at least one expected record type is found in the response.
+                             * For now, only records containing an IP address (A and AAAA) are
+                             * considered as expected.
+                             * Later, this function may be updated to let the caller decide what type
+                             * of record is expected to consider the response as valid. (SRV or TXT types)
+                             */
 
        /* move forward 2 bytes for the query id */
        reader += 2;
@@ -540,6 +551,7 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char *
                                /* ipv4 is stored on 4 bytes */
                                if (len != 4)
                                        return DNS_RESP_INVALID;
+                               expected_record = 1;
                                break;
 
                        case DNS_RTYPE_CNAME:
@@ -551,6 +563,7 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char *
                                /* ipv6 is stored on 16 bytes */
                                if (len != 16)
                                        return DNS_RESP_INVALID;
+                               expected_record = 1;
                                break;
                } /* switch (record type) */
 
@@ -558,6 +571,9 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char *
                reader += len;
        } /* for i 0 to ancount */
 
+       if (expected_record == 0)
+               return DNS_RESP_NO_EXPECTED_RECORD;
+
        return DNS_RESP_VALID;
 }
 
index f8fbe6a9a11e3bf20cbfe775a4e30367259e2c8f..4e06ad22af4a868a07d6dc5d00e79e9e4c6db5f0 100644 (file)
@@ -2120,6 +2120,7 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code)
                case DNS_RESP_ANCOUNT_ZERO:
                case DNS_RESP_TRUNCATED:
                case DNS_RESP_ERROR:
+               case DNS_RESP_NO_EXPECTED_RECORD:
                        qtype_any = resolution->query_type == DNS_RTYPE_ANY;
                        res_preferred_afinet = resolution->resolver_family_priority == AF_INET && resolution->query_type == DNS_RTYPE_A;
                        res_preferred_afinet6 = resolution->resolver_family_priority == AF_INET6 && resolution->query_type == DNS_RTYPE_AAAA;