Compare commits

...

12 Commits

Author SHA1 Message Date
Simon Kelley
8c8e5385fd Close debian bug. 2024-02-12 23:11:03 +00:00
Simon Kelley
3de7289bd6 Make --filter-rr=ANY filter the answer to ANY queries.
Thanks to Dominik Derigs for an earlier patch which inspired this.
2024-02-12 20:45:20 +00:00
Simon Kelley
febeea9d01 Tweak logging and special handling of T_ANY in rr-filter code. 2024-02-12 13:42:07 +00:00
Heikki Linnakangas
762a3f2430 Don't create a useless inotify file desrcriptor when --port=0
If there are no dynamic configuration directories configured with
dhcp-hostsdir, dhcp-optsdir and hostsdir then we need to use inotify
only to track changes to resolv-files, but we don't need to do
that when DNS is disabled (port=0) or no resolv-files are configured.

It turns out that inotify slots can be a scarce resource, so not
using one when it's not needed is a Goood Thing.

Patch by HL, description above from SRK.
2024-02-07 14:44:49 +00:00
Simon Kelley
6d35601da4 Refactor the accumulated crud of years in process_reply(). 2024-02-05 22:33:09 +00:00
Simon Kelley
a827127c77 Handle caching SOA for negative PTR queries.
Also deal with the fact that a root SOA is a thing.
2024-02-03 20:46:23 +00:00
Simon Kelley
d4a6f3a93e Fix logic error in signed RR handling.
In extract_addresses() the "secure" argument is only set if the
whole reply is validated (ie the AD bit can be set). Even without
that, some records may be validated, and should be marked
as such in the cache.

Related, the DNS doctor code has to update the flags for individual
RRs as it works, not the global "secure" flag.
2024-02-02 21:36:56 +00:00
Simon Kelley
86c15032ba Fix compiler warning. 2024-02-02 00:26:44 +00:00
Simon Kelley
12ddb2a4b9 Cache SOAs and return them with cached NXDOMAIN/NODATA replies.
Now we can cache arbirary RRs, give more correct answers when
replying negative answers from cache.

To implement this needed the DNS-doctor code to be untangled from
find_soa(), so it should be under suspicion for any regresssions
in that department.
2024-02-01 23:37:11 +00:00
Simon Kelley
db07664f2a Hardcode Lua library version in debian/rules, rather than the Makefile. 2024-01-26 23:03:34 +00:00
Simon Kelley
1205fc3541 Let pkg-config select the newest installed Lua version, don't hardcode it.
The version can be overridden with the LUA envvar

Make LUA=lua5.4

Thanks to Petr Menšík for the patch which inspired this one.
2024-01-26 22:44:06 +00:00
Simon Kelley
3a8ebcac77 Debian changelog tweaking: LUA -> Lua and use upstream test version
for experimental release.
2024-01-26 22:23:12 +00:00
15 changed files with 1010 additions and 872 deletions

View File

@@ -25,6 +25,12 @@ version 2.90
end up in the query also. This bug only seems to cause problems
when the usptream server is a DOH/DOT proxy. Thanks to Justin He
for the bug report.
Add configurable caching for arbitrary RR-types.
Add --filter-rr option, to filter arbitrary RR-types.
--filter-rr=ANY has a special meaning: it filters the
answers to queries for the ANY RR-type.
version 2.89

View File

@@ -29,6 +29,7 @@ LDFLAGS =
COPTS =
RPM_OPT_FLAGS =
LIBS =
LUA = lua
#################################################################
@@ -60,8 +61,8 @@ idn2_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFI
idn2_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --libs libidn2`
ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.4`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.4`
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags $(LUA)`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs $(LUA)`
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags 'nettle hogweed' \
HAVE_CRYPTOHASH $(PKG_CONFIG) --cflags nettle \
HAVE_NETTLEHASH $(PKG_CONFIG) --cflags nettle`

8
debian/changelog vendored
View File

@@ -1,7 +1,9 @@
dnsmasq (2.90-1) experimental; urgency=medium
dnsmasq (2.90~test4-1) experimental; urgency=medium
[ Simon Kelley ]
* New upstream. (closes: #1033165)
* Move hard-coding of Lua version from the upstream Makefile
to d/rules.
[ Sven Geuer ]
* Introduce autokpgtests per d/tests/* (closes: #1034135).
* Switch to dpkg-source 3.0 (quilt) format (closes: #1007041).
@@ -11,7 +13,7 @@ dnsmasq (2.90-1) experimental; urgency=medium
* Rename d/systemd.service to d/dnsmasq.service.
* Rename d/systemd@.service to d/dnsmasq@.service.
* Refactor d/rules to use the DH sequencer and fix major lintian issues
(closes: #844989, #1040923).
(closes: #844989, #1040923, #1063551).
Modified files:
- d/rules
Complete rewrite making use of debhelper and its tools, fixes lintian
@@ -78,7 +80,7 @@ dnsmasq (2.90-1) experimental; urgency=medium
* Introduce d/u/metadata.
* Fix lintian issue duplicate-short-description.
* Fix lintian issue capitalization-error-in-description.
* Bump LUA version to 5.4 (closes: #1050750).
* Bump Lua version to 5.4 (closes: #1050750).
Modified files:
- d/control
- d/t/functions.d/log.patterns

2
debian/rules vendored
View File

@@ -87,7 +87,7 @@ override_dh_auto_install:
BUILDDIR=debian/auto-build/dnsmasq-base-lua \
DESTDIR=$(CURDIR)/debian/dnsmasq-base-lua \
PREFIX=$(PREFIX) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
COPTS="$(COPTS) -DHAVE_LUASCRIPT"
LUA=lua5.4 COPTS="$(COPTS) -DHAVE_LUASCRIPT"
dh_auto_build -p dnsmasq-utils -D contrib/lease-tools
override_dh_auto_clean:

View File

@@ -386,7 +386,11 @@ Remove A records from answers. No IPv4 addresses will be returned.
Remove AAAA records from answers. No IPv6 addresses will be returned.
.TP
.B --filter-rr=<rrtype>[,<rrtype>...]
Remove records of the specified type(s) from answers.
Remove records of the specified type(s) from answers. The otherwise-nonsensical --filter-rr=ANY has
a special meaning: it filters replies to queries for type ANY. Everything other than A, AAAA, MX and CNAME
records are removed. Since ANY queries with forged source addresses can be used in DNS amplification attacks
(replies to ANY queries can be large) this defangs such attacks, whilst still supporting the
one remaining possible use of ANY queries. See RFC 8482 para 4.3 for details.
.TP
.B --cache-rr=<rrtype>[,<rrtype>...]
By default, dnsmasq caches A, AAAA, CNAME and SRV DNS record types.

View File

@@ -802,32 +802,28 @@ void cache_end_insert(void)
read_write(daemon->pipe_to_parent, (unsigned char *)name, m, 0);
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
if (flags & F_RR)
{
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
if (flags & F_RR)
{
/* A negative RR entry is possible and has no data, obviously. */
if (!(flags & F_NEG) && (flags & F_KEYTAG))
blockdata_write(new_chain->addr.rrblock.rrdata, new_chain->addr.rrblock.datalen, daemon->pipe_to_parent);
}
#ifdef HAVE_DNSSEC
if (flags & F_DNSKEY)
{
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
}
else if (flags & F_DS)
{
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
/* A negative DS entry is possible and has no data, obviously. */
if (!(flags & F_NEG))
blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
}
#endif
/* A negative RR entry is possible and has no data, obviously. */
if (!(flags & F_NEG) && (flags & F_KEYTAG))
blockdata_write(new_chain->addr.rrblock.rrdata, new_chain->addr.rrblock.datalen, daemon->pipe_to_parent);
}
#ifdef HAVE_DNSSEC
if (flags & F_DNSKEY)
{
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
}
else if (flags & F_DS)
{
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
/* A negative DS entry is possible and has no data, obviously. */
if (!(flags & F_NEG))
blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
}
#endif
}
}
@@ -871,7 +867,8 @@ int cache_recv_insert(time_t now, int fd)
if (!read_write(fd, (unsigned char *)daemon->namebuff, m, 1) ||
!read_write(fd, (unsigned char *)&ttd, sizeof(ttd), 1) ||
!read_write(fd, (unsigned char *)&flags, sizeof(flags), 1))
!read_write(fd, (unsigned char *)&flags, sizeof(flags), 1) ||
!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
return 0;
daemon->namebuff[m] = 0;
@@ -902,30 +899,23 @@ int cache_recv_insert(time_t now, int fd)
{
unsigned short class = C_IN;
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
{
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
return 0;
if ((flags & F_RR) && !(flags & F_NEG) && (flags & F_KEYTAG)
&& !(addr.rrblock.rrdata = blockdata_read(fd, addr.rrblock.datalen)))
return 0;
if ((flags & F_RR) && !(flags & F_NEG) && (flags & F_KEYTAG)
&& !(addr.rrblock.rrdata = blockdata_read(fd, addr.rrblock.datalen)))
return 0;
#ifdef HAVE_DNSSEC
if (flags & F_DNSKEY)
{
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
!(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
return 0;
}
else if (flags & F_DS)
{
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
(!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
return 0;
}
#endif
if (flags & F_DNSKEY)
{
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
!(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
return 0;
}
else if (flags & F_DS)
{
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
(!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
return 0;
}
#endif
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
}
}
@@ -1809,8 +1799,18 @@ static void dump_cache_entry(struct crec *cache, time_t now)
p = buff;
*a = 0;
if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
n = "<Root>";
if (cache->flags & F_REVERSE)
{
if ((cache->flags & F_NEG))
n = "";
}
else
{
if (strlen(n) == 0)
n = "<Root>";
}
p += sprintf(p, "%-30.30s ", sanitise(n));
if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
a = sanitise(cache_get_cname_target(cache));

View File

@@ -131,19 +131,11 @@ int main (int argc, char **argv)
'.' or NAME_ESCAPE then all would have to be escaped, so the
presentation format would be twice as long as the spec. */
daemon->keyname = safe_malloc((MAXDNAME * 2) + 1);
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
/* one char flag per possible RR in answer section (may get extended). */
daemon->rr_status_sz = 64;
daemon->rr_status = safe_malloc(sizeof(*daemon->rr_status) * daemon->rr_status_sz);
}
#endif
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
/* CONNTRACK UBUS code uses this buffer, so if not allocated above,
we need to allocate it here. */
if (option_bool(OPT_CMARK_ALST_EN) && !daemon->workspacename)
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
#endif
#ifdef HAVE_DHCP
if (!daemon->lease_file)
@@ -429,8 +421,8 @@ int main (int argc, char **argv)
}
#ifdef HAVE_INOTIFY
if ((daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6)
&& (!option_bool(OPT_NO_RESOLV) || daemon->dynamic_dirs))
if ((daemon->port != 0 && !option_bool(OPT_NO_RESOLV)) ||
daemon->dynamic_dirs)
inotify_dnsmasq_init();
else
daemon->inotifyfd = -1;

View File

@@ -341,7 +341,7 @@ union all_addr {
in the cache flags. */
struct datablock {
unsigned short rrtype;
unsigned char datalen;
unsigned char datalen; /* also length of SOA in negative records. */
char data[];
} rrdata;
};
@@ -1233,10 +1233,7 @@ extern struct daemon {
char *packet; /* packet buffer */
int packet_buff_sz; /* size of above */
char *namebuff; /* MAXDNAME size buffer */
#if (defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)) || defined(HAVE_DNSSEC)
/* CONNTRACK UBUS code uses this buffer, as well as DNSSEC code. */
char *workspacename;
#endif
#ifdef HAVE_DNSSEC
char *keyname; /* MAXDNAME size buffer */
unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */
@@ -1376,6 +1373,7 @@ int is_name_synthetic(int flags, char *name, union all_addr *addr);
int is_rev_synth(int flag, union all_addr *addr, char *name);
/* rfc1035.c */
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff);
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes);
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
@@ -1386,7 +1384,7 @@ unsigned int extract_request(struct dns_header *header, size_t qlen,
void setup_reply(struct dns_header *header, unsigned int flags, int ede);
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
time_t now, struct ipsets *ipsets, struct ipsets *nftsets, int is_sign,
int check_rebind, int no_cache_dnssec, int secure, int *doctored);
int check_rebind, int no_cache_dnssec, int secure);
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
void report_addresses(struct dns_header *header, size_t len, u32 mark);
#endif

View File

@@ -1804,7 +1804,7 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
When validating replies to DS records, we're only interested in the NSEC{3} RRs in the auth section.
Other RRs in that section missing sigs will not cause am INSECURE reply. We determine this mode
is the nons argument is non-NULL.
if the nons argument is non-NULL.
*/
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 *nsec_ttl)

View File

@@ -687,14 +687,13 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
{
unsigned char *pheader, *sizep;
struct ipsets *ipsets = NULL, *nftsets = NULL;
int munged = 0, is_sign;
int is_sign;
unsigned int rcode = RCODE(header);
size_t plen;
(void)ad_reqd;
(void)do_bit;
(void)bogusanswer;
#ifdef HAVE_IPSET
if (daemon->ipsets && extract_request(header, n, daemon->namebuff, NULL))
ipsets = domain_find_sets(daemon->ipsets, daemon->namebuff);
@@ -782,73 +781,89 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
server->flags |= SERV_WARNED_RECURSIVE;
}
if (daemon->bogus_addr && rcode != NXDOMAIN &&
check_for_bogus_wildcard(header, n, daemon->namebuff, now))
if (header->hb3 & HB3_TC)
{
munged = 1;
SET_RCODE(header, NXDOMAIN);
header->hb3 &= ~HB3_AA;
cache_secure = 0;
ede = EDE_BLOCKED;
log_query(F_UPSTREAM, NULL, NULL, "truncated", 0);
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
}
else
{
int doctored = 0;
if (rcode == NXDOMAIN &&
extract_request(header, n, daemon->namebuff, NULL))
{
if (check_for_local_domain(daemon->namebuff, now) ||
lookup_domain(daemon->namebuff, F_CONFIG, NULL, NULL))
{
/* if we forwarded a query for a locally known name (because it was for
an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
since we know that the domain exists, even if upstream doesn't */
munged = 1;
header->hb3 |= HB3_AA;
SET_RCODE(header, NOERROR);
cache_secure = 0;
}
}
switch (extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
if (!(header->hb3 & HB3_TC) && (!bogusanswer || (header->hb4 & HB4_CD)))
{
if (rcode == NXDOMAIN && extract_request(header, n, daemon->namebuff, NULL) &&
(check_for_local_domain(daemon->namebuff, now) || lookup_domain(daemon->namebuff, F_CONFIG, NULL, NULL)))
{
case 1:
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
munged = 1;
/* if we forwarded a query for a locally known name (because it was for
an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
since we know that the domain exists, even if upstream doesn't */
header->hb3 |= HB3_AA;
SET_RCODE(header, NOERROR);
cache_secure = 0;
}
if (daemon->doctors && do_doctor(header, n, daemon->namebuff))
cache_secure = 0;
/* check_for_bogus_wildcard() does it's own caching, so
don't call extract_addresses() if it triggers. */
if (daemon->bogus_addr && rcode != NXDOMAIN &&
check_for_bogus_wildcard(header, n, daemon->namebuff, now))
{
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
SET_RCODE(header, NXDOMAIN);
header->hb3 &= ~HB3_AA;
cache_secure = 0;
ede = EDE_BLOCKED;
break;
/* extract_addresses() found a malformed answer. */
case 2:
munged = 1;
SET_RCODE(header, SERVFAIL);
cache_secure = 0;
ede = EDE_OTHER;
break;
}
else
{
int rc = extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure);
if (rcode == NOERROR && rrfilter(header, &n, RRFILTER_CONF) > 0)
ede = EDE_FILTERED;
if (rc != 0)
{
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
cache_secure = 0;
}
if (rc == 1)
{
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
ede = EDE_BLOCKED;
}
if (rc == 2)
{
/* extract_addresses() found a malformed answer. */
SET_RCODE(header, SERVFAIL);
ede = EDE_OTHER;
}
}
if (doctored)
cache_secure = 0;
if (RCODE(header) == NOERROR && rrfilter(header, &n, RRFILTER_CONF) > 0)
ede = EDE_FILTERED;
}
#ifdef HAVE_DNSSEC
if (bogusanswer && !(header->hb4 & HB4_CD) && !option_bool(OPT_DNSSEC_DEBUG))
{
/* Bogus reply, turn into SERVFAIL */
SET_RCODE(header, SERVFAIL);
munged = 1;
}
if (option_bool(OPT_DNSSEC_VALID))
{
header->hb4 &= ~HB4_AD;
if (!(header->hb4 & HB4_CD) && ad_reqd && cache_secure)
if (bogusanswer)
{
if (!(header->hb4 & HB4_CD) && !option_bool(OPT_DNSSEC_DEBUG))
{
/* Bogus reply, turn into SERVFAIL */
SET_RCODE(header, SERVFAIL);
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
ede = EDE_DNSSEC_BOGUS;
}
}
else if (!(header->hb4 & HB4_CD) && ad_reqd && cache_secure)
header->hb4 |= HB4_AD;
/* If the requestor didn't set the DO bit, don't return DNSSEC info. */
@@ -856,20 +871,9 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
rrfilter(header, &n, RRFILTER_DNSSEC);
}
#endif
/* do this after extract_addresses. Ensure NODATA reply and remove
nameserver info. */
if (munged)
{
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
header->hb3 &= ~HB3_TC;
}
/* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
sections of the packet. Find the new length here and put back pseudoheader
if it was removed. */
/* the code above can elide sections of the packet. Find the new length here
and put back pseudoheader if it was removed. */
n = resize_packet(header, n, pheader, plen);
if (pheader && ede != EDE_UNSET)

View File

@@ -94,7 +94,7 @@ void inotify_dnsmasq_init()
if (daemon->inotifyfd == -1)
die(_("failed to create inotify: %s"), NULL, EC_MISC);
if (option_bool(OPT_NO_RESOLV))
if (daemon->port == 0 || option_bool(OPT_NO_RESOLV))
return;
for (res = daemon->resolv_files; res; res = res->next)

View File

@@ -5844,6 +5844,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon = opt_malloc(sizeof(struct daemon));
memset(daemon, 0, sizeof(struct daemon));
daemon->namebuff = buff;
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
daemon->addrbuff = safe_malloc(ADDRSTRLEN);
/* Set defaults - everything else is zero or NULL */

File diff suppressed because it is too large Load Diff

View File

@@ -213,6 +213,14 @@ size_t rrfilter(struct dns_header *header, size_t *plen, int mode)
if (i < ntohs(header->ancount) && type == qtype && class == qclass)
continue;
}
else if (qtype == T_ANY && rr_on_list(daemon->filter_rr, T_ANY))
{
/* Filter replies to ANY queries in the spirit of
RFC RFC 8482 para 4.3 */
if (class != C_IN ||
type == T_A || type == T_AAAA || type == T_MX || type == T_CNAME)
continue;
}
else
{
/* Only looking at answer section now. */

View File

@@ -119,7 +119,7 @@ int rr_on_list(struct rrlist *list, unsigned short rr)
{
while (list)
{
if (list->rr == rr || list->rr == T_ANY)
if (list->rr == rr)
return 1;
list = list->next;