fbf475403b
Refresh patches and backport upstream to current HEAD: a997ca0 Fix sometimes missing DNSSEC RRs when DNSSEC validation not enabled. 51e4eee Fix address-dependent domains for IPv6. 05ff659 Fix stupid infinite loop introduced by preceding commit. db0f488 Handle some corner cases in RA contructed interfaces with addresses changing interface. 7dcca6c Warn about the impact of cache-size on performance. 090856c Allow zone transfer in authoritative mode whenever auth-peer is specified. cc5cc8f Sane error message when pcap file header is wrong. c488b68 Handle standard and contructed dhcp-ranges on the same interface. Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
100 lines
3 KiB
Diff
100 lines
3 KiB
Diff
From 1f60a18ea1c64beb8b6cffa0650a2bfad95ac352 Mon Sep 17 00:00:00 2001
|
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
|
Date: Fri, 11 May 2018 16:44:16 +0100
|
|
Subject: [PATCH 07/17] Retry SERVFAIL DNSSEC queries to a different server, if
|
|
possible.
|
|
|
|
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|
---
|
|
src/forward.c | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
|
|
1 file changed, 42 insertions(+), 11 deletions(-)
|
|
|
|
--- a/src/forward.c
|
|
+++ b/src/forward.c
|
|
@@ -825,9 +825,12 @@ void reply_query(int fd, int family, tim
|
|
size_t plen;
|
|
int is_sign;
|
|
|
|
+#ifdef HAVE_DNSSEC
|
|
/* For DNSSEC originated queries, just retry the query to the same server. */
|
|
if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
|
|
{
|
|
+ struct server *start;
|
|
+
|
|
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
|
plen = forward->stash_len;
|
|
|
|
@@ -839,26 +842,54 @@ void reply_query(int fd, int family, tim
|
|
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;
|
|
+
|
|
+ start = forward->sentto;
|
|
+
|
|
+ /* for non-domain specific servers, see if we can find another to try. */
|
|
+ if ((forward->sentto->flags & SERV_TYPE) == 0)
|
|
+ while (1)
|
|
+ {
|
|
+ if (!(start = start->next))
|
|
+ start = daemon->servers;
|
|
+ if (start == forward->sentto)
|
|
+ break;
|
|
+
|
|
+ if ((start->flags & SERV_TYPE) == 0 &&
|
|
+ (start->flags & SERV_DO_DNSSEC))
|
|
+ break;
|
|
+ }
|
|
+
|
|
+
|
|
+ if (start->sfd)
|
|
+ fd = start->sfd->fd;
|
|
else
|
|
{
|
|
#ifdef HAVE_IPV6
|
|
- if (forward->sentto->addr.sa.sa_family == AF_INET6)
|
|
- fd = forward->rfd6->fd;
|
|
+ if (start->addr.sa.sa_family == AF_INET6)
|
|
+ {
|
|
+ /* may have changed family */
|
|
+ if (!forward->rfd6)
|
|
+ forward->rfd6 = allocate_rfd(AF_INET6);
|
|
+ fd = forward->rfd6->fd;
|
|
+ }
|
|
else
|
|
#endif
|
|
- fd = forward->rfd4->fd;
|
|
+ {
|
|
+ /* may have changed family */
|
|
+ if (!forward->rfd4)
|
|
+ forward->rfd4 = allocate_rfd(AF_INET);
|
|
+ fd = forward->rfd4->fd;
|
|
+ }
|
|
}
|
|
-
|
|
+
|
|
while (retry_send(sendto(fd, (char *)header, plen, 0,
|
|
- &forward->sentto->addr.sa,
|
|
- sa_len(&forward->sentto->addr))));
|
|
+ &start->addr.sa,
|
|
+ sa_len(&start->addr))));
|
|
|
|
return;
|
|
}
|
|
-
|
|
+#endif
|
|
+
|
|
/* 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
|
|
@@ -1024,7 +1055,7 @@ void reply_query(int fd, int family, tim
|
|
while (1)
|
|
{
|
|
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
|
|
- (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
|
+ ((type & SERV_TYPE) != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
|
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
|
{
|
|
new_server = start;
|