mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
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:
parent
65ce3f5ee4
commit
3cf7f98782
40
src/dns.c
40
src/dns.c
@ -129,6 +129,7 @@ void dns_reset_resolution(struct dns_resolution *resolution)
|
|||||||
* - check if the packet requires processing (not outdated resolution)
|
* - check if the packet requires processing (not outdated resolution)
|
||||||
* - ensure the DNS packet received is valid and call requester's callback
|
* - ensure the DNS packet received is valid and call requester's callback
|
||||||
* - call requester's error callback if invalid response
|
* - 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)
|
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,
|
* If existing IP not found, return the first IP matching family_priority,
|
||||||
* otherwise, first ip found
|
* otherwise, first ip found
|
||||||
* The following tasks are the responsibility of the caller:
|
* The following tasks are the responsibility of the caller:
|
||||||
* - resp contains an error free DNS response
|
* - <dns_p> contains an error free DNS response
|
||||||
* - the response matches the dn_name
|
|
||||||
* For both cases above, dns_validate_dns_response is required
|
* For both cases above, dns_validate_dns_response is required
|
||||||
* returns one of the DNS_UPD_* code
|
* 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;
|
struct dns_answer_item *record;
|
||||||
int family_priority;
|
int family_priority;
|
||||||
char *dn_name;
|
int i, currentip_found;
|
||||||
int dn_name_len;
|
unsigned char *newip4, *newip6;
|
||||||
int i, cnamelen, currentip_found;
|
|
||||||
unsigned char *cname, *newip4, *newip6;
|
|
||||||
struct {
|
struct {
|
||||||
void *ip;
|
void *ip;
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
@ -737,28 +735,12 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
|
|||||||
int score, max_score;
|
int score, max_score;
|
||||||
|
|
||||||
family_priority = resol->opts->family_prio;
|
family_priority = resol->opts->family_prio;
|
||||||
dn_name = resol->hostname_dn;
|
*newip = newip4 = newip6 = NULL;
|
||||||
dn_name_len = resol->hostname_dn_len;
|
currentip_found = 0;
|
||||||
cname = *newip = newip4 = newip6 = NULL;
|
|
||||||
cnamelen = currentip_found = 0;
|
|
||||||
*newip_sin_family = AF_UNSPEC;
|
*newip_sin_family = AF_UNSPEC;
|
||||||
|
|
||||||
/* now parsing response records */
|
/* now parsing response records */
|
||||||
list_for_each_entry(record, &dns_response.answer_list, list) {
|
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 */
|
/* analyzing record content */
|
||||||
switch (record->type) {
|
switch (record->type) {
|
||||||
case DNS_RTYPE_A:
|
case DNS_RTYPE_A:
|
||||||
@ -770,10 +752,9 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* we're looking for IPs only. CNAME validation is done when
|
||||||
|
* parsing the response buffer for the first time */
|
||||||
case DNS_RTYPE_CNAME:
|
case DNS_RTYPE_CNAME:
|
||||||
cname = record->target;
|
|
||||||
cnamelen = record->data_len;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DNS_RTYPE_AAAA:
|
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 */
|
/* no IP found in the response */
|
||||||
if (!newip4 && !newip6) {
|
if (!newip4 && !newip6) {
|
||||||
return DNS_UPD_NO_IP_FOUND;
|
return DNS_UPD_NO_IP_FOUND;
|
||||||
|
Loading…
Reference in New Issue
Block a user