bind9/lib/ns
Matthijs Mekking b9e2f3333d Only refresh RRset once
Don't attempt to resolve DNS responses for intermediate results. This
may create multiple refreshes and can cause a crash.

One scenario is where for the query there is a CNAME and canonical
answer in cache that are both stale. This will trigger a refresh of
the RRsets because we encountered stale data and we prioritized it over
the lookup. It will trigger a refresh of both RRsets. When we start
recursing, it will detect a recursion loop because the recursion
parameters will eventually be the same. In 'dns_resolver_destroyfetch'
the sanity check fails, one of the callers did not get its event back
before trying to destroy the fetch.

Move the call to 'query_refresh_rrset' to 'ns_query_done', so that it
is only called once per client request.

Another scenario is where for the query there is a stale CNAME in the
cache that points to a record that is also in cache but not stale. This
will trigger a refresh of the RRset (because we encountered stale data
and we prioritized it over the lookup).

We mark RRsets that we add to the message with
DNS_RDATASETATTR_STALE_ADDED to prevent adding a duplicate RRset when
a stale lookup and a normal lookup conflict with each other. However,
the other non-stale RRset when following a CNAME chain will be added to
the message without setting that attribute, because it is not stale.

This is a variant of the bug in #2594. The fix covered the same crash
but for stale-answer-client-timeout > 0.

Fix this by clearing all RRsets from the message before refreshing.
This requires the refresh to happen after the query is send back to
the client.

(cherry picked from commit d939d2ecde)
2022-09-08 11:50:44 +02:00
..
include Only refresh RRset once 2022-09-08 11:50:44 +02:00
client.c Fix RRL responses-per-second bypass using wildcard names 2022-09-08 09:36:50 +02:00
hooks.c Update the copyright information in all files in the repository 2022-01-11 09:05:02 +01:00
interfacemgr.c when creating an interface, set magic before linking 2022-09-06 21:48:28 -07:00
listenlist.c Store HTTP quota size inside a listenlist instead of the quota 2022-06-28 16:37:31 +03:00
log.c Update the copyright information in all files in the repository 2022-01-11 09:05:02 +01:00
Makefile.am Move all the unit tests to /tests/<libname>/ 2022-05-31 12:06:00 +02:00
notify.c Update the copyright information in all files in the repository 2022-01-11 09:05:02 +01:00
query.c Only refresh RRset once 2022-09-08 11:50:44 +02:00
server.c Store HTTP quota size inside a listenlist instead of the quota 2022-06-28 16:37:31 +03:00
sortlist.c Add isc_rwlock around dns_aclenv .localhost and .localnets member 2022-04-26 14:21:57 +02:00
stats.c Update the copyright information in all files in the repository 2022-01-11 09:05:02 +01:00
tests Move all the unit tests to /tests/<libname>/ 2022-05-31 12:06:00 +02:00
update.c Wait with NSEC3 during a DNSSEC policy change 2022-08-22 19:21:39 +02:00
xfrout.c log the reason for falling back to AXFR from IXFR at level info 2022-07-12 16:26:13 -07:00