88 lines
3 KiB
Diff
88 lines
3 KiB
Diff
|
From a0088e83640d7d1544127dd668660462e9f78e52 Mon Sep 17 00:00:00 2001
|
||
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
||
|
Date: Thu, 10 May 2018 21:43:14 +0100
|
||
|
Subject: [PATCH 06/10] Handle query retry on REFUSED or SERVFAIL for
|
||
|
DNSSEC-generated queries.
|
||
|
|
||
|
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||
|
---
|
||
|
src/forward.c | 46 ++++++++++++++++++++++++++++++++++++++++------
|
||
|
1 file changed, 40 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/src/forward.c
|
||
|
+++ b/src/forward.c
|
||
|
@@ -298,9 +298,9 @@ static int forward_query(int udpfd, unio
|
||
|
fd = forward->rfd4->fd;
|
||
|
}
|
||
|
|
||
|
- while (retry_send( sendto(fd, (char *)header, plen, 0,
|
||
|
- &forward->sentto->addr.sa,
|
||
|
- sa_len(&forward->sentto->addr))));
|
||
|
+ while (retry_send(sendto(fd, (char *)header, plen, 0,
|
||
|
+ &forward->sentto->addr.sa,
|
||
|
+ sa_len(&forward->sentto->addr))));
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
@@ -804,8 +804,7 @@ void reply_query(int fd, int family, tim
|
||
|
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
|
||
|
(void *)header, n, &serveraddr, NULL);
|
||
|
#endif
|
||
|
-
|
||
|
-
|
||
|
+
|
||
|
/* log_query gets called indirectly all over the place, so
|
||
|
pass these in global variables - sorry. */
|
||
|
daemon->log_display_id = forward->log_id;
|
||
|
@@ -826,6 +825,40 @@ void reply_query(int fd, int family, tim
|
||
|
size_t plen;
|
||
|
int is_sign;
|
||
|
|
||
|
+ /* For DNSSEC originated queries, just retry the query to the same server. */
|
||
|
+ if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
|
||
|
+ {
|
||
|
+ blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||
|
+ plen = forward->stash_len;
|
||
|
+
|
||
|
+ forward->forwardall = 2; /* only retry once */
|
||
|
+
|
||
|
+ if (forward->sentto->addr.sa.sa_family == AF_INET)
|
||
|
+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
|
||
|
+#ifdef HAVE_IPV6
|
||
|
+ else
|
||
|
+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
|
||
|
+#endif
|
||
|
+
|
||
|
+ if (forward->sentto->sfd)
|
||
|
+ fd = forward->sentto->sfd->fd;
|
||
|
+ else
|
||
|
+ {
|
||
|
+#ifdef HAVE_IPV6
|
||
|
+ if (forward->sentto->addr.sa.sa_family == AF_INET6)
|
||
|
+ fd = forward->rfd6->fd;
|
||
|
+ else
|
||
|
+#endif
|
||
|
+ fd = forward->rfd4->fd;
|
||
|
+ }
|
||
|
+
|
||
|
+ while (retry_send(sendto(fd, (char *)header, plen, 0,
|
||
|
+ &forward->sentto->addr.sa,
|
||
|
+ sa_len(&forward->sentto->addr))));
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
/* In strict order mode, there must be a server later in the chain
|
||
|
left to send to, otherwise without the forwardall mechanism,
|
||
|
code further on will cycle around the list forwever if they
|
||
|
@@ -1017,7 +1050,8 @@ void reply_query(int fd, int family, tim
|
||
|
#ifdef HAVE_IPV6
|
||
|
new->rfd6 = NULL;
|
||
|
#endif
|
||
|
- new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
|
||
|
+ new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_HAS_EXTRADATA);
|
||
|
+ new->forwardall = 0;
|
||
|
|
||
|
new->dependent = forward; /* to find query awaiting new one. */
|
||
|
forward->blocking_query = new; /* for garbage cleaning */
|