066c85321e
Refresh patches and backport upstream to current HEAD: 1f1873a Log warning on very large cachesize config, instead of truncating it. 0a496f0 Do unsolicited RAs for interfaces which appear after dnsmasq startup. e27825b Fix logging in previous. 1f60a18 Retry SERVFAIL DNSSEC queries to a different server, if possible. a0088e8 Handle query retry on REFUSED or SERVFAIL for DNSSEC-generated queries. 34e26e1 Retry query to other servers on receipt of SERVFAIL rcode. 6b17335 Add packet-dump debugging facility. 07ed585 Add logging for DNS error returns from upstream and local configuration. 0669ee7 Fix DHCP broken-ness when --no-ping AND --dhcp-sequential-ip are set. f84e674 Be persistent with broken-upstream-DNSSEC warnings. Compile & run tested: ar71xx Archer C7 v2 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/10] 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;
|