"nxdomain-redirect" may not be triggered for redirect responses with TTL=0
Without nxdomain-redirect
, if:
- a client sends a query at Unix timestamp X,
- then, an upstream response with TTL=0 is received at Unix timestamp A,
- then,
query_resume()
happens to be executed at Unix timestamp B which is different than Unix timestamp A,
things still work fine because query_resume()
takes care of storing the response in qctx->rdataset
, which means that another database lookup is not needed to return the response to the client and thus updating client->now
in fetch_callback()
(from timestamp A to timestamp B) does not affect the contents of the response.
With nxdomain-redirect
, if:
- a client sends a query at Unix timestamp X,
- then, an upstream response is received at Unix timestamp A,
- then, an upstream response for the redirect lookup with TTL=0 is received at Unix timestamp R,
- then,
query_resume()
for the redirect lookup happens to be executed at Unix timestamp S which is different than Unix timestamp R,
the nxdomain-redirect
feature breaks: in redirect2()
, a database lookup is performed with now
set to the moment the response to the redirect query was received (i.e. timestamp R) instead of the moment the client's query was received (i.e. timestamp X). In other words, nxdomain-redirect
's behavior is affected by the TTL of the response received to the redirect lookup while the rewrite should arguably be considered a discrete event from the client's perspective.
An example occurrence of this issue may be found here: https://gitlab.isc.org/isc-projects/bind9/-/jobs/186097.
Here is a crude patch against current master that triggers this issue in the redirect
system test:
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 03b8248fdd..044471d445 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -16,6 +16,7 @@
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
+#include <unistd.h>
#include <isc/counter.h>
#include <isc/log.h>
@@ -6607,6 +6608,14 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
if (result != ISC_R_SUCCESS)
goto unlock;
+ {
+ static bool slept = false;
+ if (!slept && strcmp(fctx->info, "nonexist.redirect/TXT") == 0) {
+ sleep(1);
+ slept = true;
+ }
+ }
+
if (!HAVE_ANSWER(fctx)) {
fctx->attributes |= FCTX_ATTR_HAVEANSWER;
if (event != NULL) {