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;
...@@ -840,24 +843,52 @@ void reply_query(int fd, int family, time_t now) ...@@ -840,24 +843,52 @@ void reply_query(int fd, int family, time_t now)
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)
{
/* may have changed family */
if (!forward->rfd6)
forward->rfd6 = allocate_rfd(AF_INET6);
fd = forward->rfd6->fd; fd = forward->rfd6->fd;
}
else else
#endif #endif
{
/* may have changed family */
if (!forward->rfd4)
forward->rfd4 = allocate_rfd(AF_INET);
fd = forward->rfd4->fd; 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,
...@@ -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