summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2023-03-20 17:14:17 +0000
committerSimon Kelley <simon@thekelleys.org.uk>2023-03-20 17:14:17 +0000
commit28429720355c21739c851c28b003b6d0b4aee549 (patch)
treec5b1bd6a080ee6ea5e0f9fd00347465b5cfdb7dc
parent5a9eae429a7d0680d606f03f2759d7dde0bbe3f0 (diff)
downloaddnsmasq-28429720355c21739c851c28b003b6d0b4aee549.tar.gz
More --filter-AAAA caching improvements.
Cache answers before filtering and filter coming out of the cache.
-rw-r--r--src/forward.c19
-rw-r--r--src/rfc1035.c38
2 files changed, 38 insertions, 19 deletions
diff --git a/src/forward.c b/src/forward.c
index 0f03818..3f3954d 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -811,16 +811,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
}
- /* Before extract_addresses() */
- if (rcode == NOERROR)
- {
- if (option_bool(OPT_FILTER_A))
- n = rrfilter(header, n, RRFILTER_A);
-
- if (option_bool(OPT_FILTER_AAAA))
- n = rrfilter(header, n, RRFILTER_AAAA);
- }
-
switch (extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
{
case 1:
@@ -839,6 +829,15 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
break;
}
+ if (rcode == NOERROR)
+ {
+ if (option_bool(OPT_FILTER_A))
+ n = rrfilter(header, n, RRFILTER_A);
+
+ if (option_bool(OPT_FILTER_AAAA))
+ n = rrfilter(header, n, RRFILTER_AAAA);
+ }
+
if (doctored)
cache_secure = 0;
}
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 5abacbd..75481d3 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -880,7 +880,18 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
return 2;
}
else
- log_query(flags | F_FORWARD | secflag | F_UPSTREAM, name, &addr, NULL, aqtype);
+ {
+ int negflag = F_UPSTREAM;
+
+ /* We're filtering this RRtype. It will be removed from the
+ returned packet in process_reply() but gets cached here anyway
+ and will be filtered again on the way out of the cache. Here,
+ we just need to alter the logging. */
+ if (((flags & F_IPV4) && option_bool(OPT_FILTER_A)) || ((flags & F_IPV6) && option_bool(OPT_FILTER_AAAA)))
+ negflag = F_NEG | F_CONFIG;
+
+ log_query(negflag | flags | F_FORWARD | secflag, name, &addr, NULL, aqtype);
+ }
}
p1 = endrr;
@@ -1863,8 +1874,21 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (!(crecp->flags & F_DNSSECOK))
sec_data = 0;
-
- if (crecp->flags & F_NEG)
+
+ if (!(crecp->flags & (F_HOSTS | F_DHCP)))
+ auth = 0;
+
+ if ((((flag & F_IPV4) && option_bool(OPT_FILTER_A)) || ((flag & F_IPV6) && option_bool(OPT_FILTER_AAAA))) &&
+ !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | F_NEG)))
+ {
+ /* We have a cached answer but we're filtering it. */
+ ans = 1;
+ sec_data = 0;
+
+ if (!dryrun)
+ log_query(F_NEG | F_CONFIG | flag, name, NULL, NULL, 0);
+ }
+ else if (crecp->flags & F_NEG)
{
ans = 1;
auth = 0;
@@ -1882,9 +1906,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
!is_same_net(crecp->addr.addr4, local_addr, local_netmask))
continue;
- if (!(crecp->flags & (F_HOSTS | F_DHCP)))
- auth = 0;
-
ans = 1;
if (!dryrun)
{
@@ -1917,13 +1938,12 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
that may be enough to tell us if the answer should be NODATA and save the round trip.
Cached NXDOMAIN has already been handled, so here we look for any record for the domain,
since its existence allows us to return a NODATA answer. Note that we never set the AD flag,
- since we didn't authentucate the record. We do set the AA flag since this answer comes from
- local config. */
+ since we didn't authentucate the record. */
if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_SRV))
{
ans = 1;
- sec_data = 0;
+ sec_data = auth = 0;
if (!dryrun)
log_query(F_NEG | F_CONFIG | flag, name, NULL, NULL, 0);