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 */
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;
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;
/* ipv4 is stored on 4 bytes */
if (len != 4)
return DNS_RESP_INVALID;
+ expected_record = 1;
break;
case DNS_RTYPE_CNAME:
/* ipv6 is stored on 16 bytes */
if (len != 16)
return DNS_RESP_INVALID;
+ expected_record = 1;
break;
} /* switch (record type) */
reader += len;
} /* for i 0 to ancount */
+ if (expected_record == 0)
+ return DNS_RESP_NO_EXPECTED_RECORD;
+
return DNS_RESP_VALID;
}
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;