MINOR: dns: Update analysis of TRUNCATED response for SRV records

First implementation of the DNS parser used to consider TRUNCATED
responses as errors and triggered a failover to an other query type
(usually A to AAAA or vice-versa).

When we query for SRV records, a TRUNCATED response still contains valid
records we can exploit, so we shouldn't trigger a failover in such case.

Note that we had to move the maching against the flag later in the
response parsing (actually, until we can read the query type....)
This commit is contained in:
Baptiste Assmann 2017-08-11 09:58:27 +02:00 committed by Willy Tarreau
parent 97148f60b8
commit 251abb9cbe

View File

@ -1037,6 +1037,7 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct
reader = resp; reader = resp;
len = 0; len = 0;
previous_dname = NULL; previous_dname = NULL;
dns_query = NULL;
/* initialization of response buffer and structure */ /* initialization of response buffer and structure */
dns_p = &resolution->response; dns_p = &resolution->response;
@ -1061,9 +1062,6 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct
flags = reader[0] * 256 + reader[1]; flags = reader[0] * 256 + reader[1];
if (flags & DNS_FLAG_TRUNCATED)
return DNS_RESP_TRUNCATED;
if ((flags & DNS_FLAG_REPLYCODE) != DNS_RCODE_NO_ERROR) { if ((flags & DNS_FLAG_REPLYCODE) != DNS_RCODE_NO_ERROR) {
if ((flags & DNS_FLAG_REPLYCODE) == DNS_RCODE_NX_DOMAIN) if ((flags & DNS_FLAG_REPLYCODE) == DNS_RCODE_NX_DOMAIN)
return DNS_RESP_NX_DOMAIN; return DNS_RESP_NX_DOMAIN;
@ -1148,6 +1146,12 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct
reader += 2; reader += 2;
} }
/* TRUNCATED flag must be checked after we could read the query type
* because a TRUNCATED SRV query type response can still be exploited
*/
if (dns_query->type != DNS_RTYPE_SRV && flags & DNS_FLAG_TRUNCATED)
return DNS_RESP_TRUNCATED;
/* now parsing response records */ /* now parsing response records */
nb_saved_records = 0; nb_saved_records = 0;
for (i = 0; i < dns_p->header.ancount; i++) { for (i = 0; i < dns_p->header.ancount; i++) {