mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Fix caching logic for validated answers.
The current logic is naive in the case that there is more than one RRset in an answer (Typically, when a non-CNAME query is answered by one or more CNAME RRs, and then then an answer RRset.) If all the RRsets validate, then they are cached and marked as validated, but if any RRset doesn't validate, then the AD flag is not set (good) and ALL the RRsets are cached marked as not validated. This breaks when, eg, the answer contains a validated CNAME, pointing to a non-validated answer. A subsequent query for the CNAME without do will get an answer with the AD flag wrongly reset, and worse, the same query with do will get a cached answer without RRSIGS, rather than being forwarded. The code now records the validation of individual RRsets and that is used to correctly set the "validated" bits in the cache entries.
This commit is contained in:
@@ -1025,6 +1025,7 @@ extern struct daemon {
|
||||
#ifdef HAVE_DNSSEC
|
||||
char *keyname; /* MAXDNAME size buffer */
|
||||
char *workspacename; /* ditto */
|
||||
char *rr_status; /* 256 bytes as flags for individual RRs */
|
||||
#endif
|
||||
unsigned int local_answer, queries_forwarded, auth_answer;
|
||||
struct frec *frec_list;
|
||||
@@ -1139,7 +1140,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
|
||||
unsigned long ttl);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
|
||||
time_t now, char **ipsets, int is_sign, int check_rebind,
|
||||
int no_cache_dnssec, int secure, int *doctored);
|
||||
int no_cache_dnssec, int secure, int *doctored, char *rr_status);
|
||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
struct in_addr local_addr, struct in_addr local_netmask,
|
||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
|
||||
@@ -1172,7 +1173,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,
|
||||
int check_unsigned, int *neganswer, int *nons);
|
||||
int check_unsigned, int *neganswer, int *nons, char *rr_status);
|
||||
int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
|
||||
size_t filter_rrsigs(struct dns_header *header, size_t plen);
|
||||
unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
|
||||
|
||||
Reference in New Issue
Block a user