MINOR: dns: proper domain name validation when receiving DNS response

The analyse of CNAME resolution and request's domain name was performed
twice:
- when validating the response buffer
- when loading the right IP address from the response

Now DNS response are properly loaded into a DNS response structure, we
do the domain name validation when loading/validating the response in
the DNS strcucture and later processing of this task is now useless.

backport: no
This commit is contained in:
Baptiste Assmann 2016-04-17 22:43:26 +02:00 committed by Willy Tarreau
parent 65ce3f5ee4
commit 3cf7f98782

View File

@ -129,6 +129,7 @@ void dns_reset_resolution(struct dns_resolution *resolution)
* - check if the packet requires processing (not outdated resolution)
* - ensure the DNS packet received is valid and call requester's callback
* - call requester's error callback if invalid response
* - check the dn_name in the packet against the one sent
*/
void dns_resolve_recv(struct dgram_conn *dgram)
{
@ -710,8 +711,7 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct
* If existing IP not found, return the first IP matching family_priority,
* otherwise, first ip found
* The following tasks are the responsibility of the caller:
* - resp contains an error free DNS response
* - the response matches the dn_name
* - <dns_p> contains an error free DNS response
* For both cases above, dns_validate_dns_response is required
* returns one of the DNS_UPD_* code
*/
@ -723,10 +723,8 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
{
struct dns_answer_item *record;
int family_priority;
char *dn_name;
int dn_name_len;
int i, cnamelen, currentip_found;
unsigned char *cname, *newip4, *newip6;
int i, currentip_found;
unsigned char *newip4, *newip6;
struct {
void *ip;
unsigned char type;
@ -737,28 +735,12 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
int score, max_score;
family_priority = resol->opts->family_prio;
dn_name = resol->hostname_dn;
dn_name_len = resol->hostname_dn_len;
cname = *newip = newip4 = newip6 = NULL;
cnamelen = currentip_found = 0;
*newip = newip4 = newip6 = NULL;
currentip_found = 0;
*newip_sin_family = AF_UNSPEC;
/* now parsing response records */
list_for_each_entry(record, &dns_response.answer_list, list) {
if (cname) {
if (memcmp(record->name, cname, cnamelen) != 0) {
return DNS_UPD_NAME_ERROR;
}
}
else if (memcmp(record->name, dn_name, dn_name_len) != 0) {
return DNS_UPD_NAME_ERROR;
}
/*
* we know the record is either for our server hostname
* or a valid CNAME in a crecursion
*/
/* analyzing record content */
switch (record->type) {
case DNS_RTYPE_A:
@ -770,10 +752,9 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
}
break;
/* we're looking for IPs only. CNAME validation is done when
* parsing the response buffer for the first time */
case DNS_RTYPE_CNAME:
cname = record->target;
cnamelen = record->data_len;
break;
case DNS_RTYPE_AAAA:
@ -857,11 +838,6 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
}
}
/* only CNAMEs in the response, no IP found */
if (cname && !newip4 && !newip6) {
return DNS_UPD_CNAME;
}
/* no IP found in the response */
if (!newip4 && !newip6) {
return DNS_UPD_NO_IP_FOUND;