Commit 1f60a18e authored by Simon Kelley's avatar Simon Kelley

Retry SERVFAIL DNSSEC queries to a different server, if possible.

parent a0088e83
...@@ -825,9 +825,12 @@ void reply_query(int fd, int family, time_t now) ...@@ -825,9 +825,12 @@ void reply_query(int fd, int family, time_t now)
size_t plen; size_t plen;
int is_sign; int is_sign;
#ifdef HAVE_DNSSEC
/* For DNSSEC originated queries, just retry the query to the same server. */ /* For DNSSEC originated queries, just retry the query to the same server. */
if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
{ {
struct server *start;
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header); blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
plen = forward->stash_len; plen = forward->stash_len;
...@@ -839,26 +842,54 @@ void reply_query(int fd, int family, time_t now) ...@@ -839,26 +842,54 @@ void reply_query(int fd, int family, time_t now)
else else
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec"); log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
#endif #endif
if (forward->sentto->sfd) start = forward->sentto;
fd = forward->sentto->sfd->fd;
/* 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 else
{ {
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
if (forward->sentto->addr.sa.sa_family == AF_INET6) if (start->addr.sa.sa_family == AF_INET6)
fd = forward->rfd6->fd; {
/* may have changed family */
if (!forward->rfd6)
forward->rfd6 = allocate_rfd(AF_INET6);
fd = forward->rfd6->fd;
}
else else
#endif #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, while (retry_send(sendto(fd, (char *)header, plen, 0,
&forward->sentto->addr.sa, &start->addr.sa,
sa_len(&forward->sentto->addr)))); sa_len(&start->addr))));
return; return;
} }
#endif
/* In strict order mode, there must be a server later in the chain /* In strict order mode, there must be a server later in the chain
left to send to, otherwise without the forwardall mechanism, left to send to, otherwise without the forwardall mechanism,
code further on will cycle around the list forwever if they code further on will cycle around the list forwever if they
...@@ -1024,7 +1055,7 @@ void reply_query(int fd, int family, time_t now) ...@@ -1024,7 +1055,7 @@ void reply_query(int fd, int family, time_t now)
while (1) while (1)
{ {
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) && 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))) !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
{ {
new_server = start; new_server = start;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment