Handle query retry on REFUSED or SERVFAIL for DNSSEC-generated queries.

This commit is contained in:
Simon Kelley
2018-05-10 21:43:14 +01:00
parent 34e26e14c5
commit a0088e8364

View File

@@ -298,9 +298,9 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
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, &forward->sentto->addr.sa,
sa_len(&forward->sentto->addr)))); sa_len(&forward->sentto->addr))));
return 1; return 1;
} }
@@ -804,8 +804,7 @@ void reply_query(int fd, int family, time_t now)
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY, dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
(void *)header, n, &serveraddr, NULL); (void *)header, n, &serveraddr, NULL);
#endif #endif
/* log_query gets called indirectly all over the place, so /* log_query gets called indirectly all over the place, so
pass these in global variables - sorry. */ pass these in global variables - sorry. */
daemon->log_display_id = forward->log_id; daemon->log_display_id = forward->log_id;
@@ -826,6 +825,40 @@ void reply_query(int fd, int family, time_t now)
size_t plen; size_t plen;
int is_sign; 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 /* 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
@@ -1017,7 +1050,8 @@ void reply_query(int fd, int family, time_t now)
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
new->rfd6 = NULL; new->rfd6 = NULL;
#endif #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. */ new->dependent = forward; /* to find query awaiting new one. */
forward->blocking_query = new; /* for garbage cleaning */ forward->blocking_query = new; /* for garbage cleaning */