mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
UDP retries for DNSSEC
This commit is contained in:
@@ -868,7 +868,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
{
|
{
|
||||||
unsigned char *psave, *p = (unsigned char *)(header+1);
|
unsigned char *psave, *p = (unsigned char *)(header+1);
|
||||||
struct crec *crecp;
|
struct crec *crecp;
|
||||||
int qtype, qclass, val, j, gotone;
|
int qtype, qclass, val, j;
|
||||||
struct blockdata *key;
|
struct blockdata *key;
|
||||||
|
|
||||||
if (ntohs(header->qdcount) != 1 ||
|
if (ntohs(header->qdcount) != 1 ||
|
||||||
@@ -895,7 +895,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
|
|
||||||
cache_start_insert();
|
cache_start_insert();
|
||||||
|
|
||||||
for (gotone = 0, j = ntohs(header->ancount); j != 0; j--)
|
for (j = ntohs(header->ancount); j != 0; j--)
|
||||||
{
|
{
|
||||||
int ttl, rdlen, rc, algo, digest, keytag;
|
int ttl, rdlen, rc, algo, digest, keytag;
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,46 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
forward = NULL;
|
forward = NULL;
|
||||||
else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
|
else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
/* If we've already got an answer to this query, but we're awaiting keys for vaildation,
|
||||||
|
there's no point retrying the query, retry the key query instead...... */
|
||||||
|
if (forward->blocking_query)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
while (forward->blocking_query)
|
||||||
|
forward = forward->blocking_query;
|
||||||
|
|
||||||
|
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||||||
|
plen = forward->stash_len;
|
||||||
|
|
||||||
|
if (forward->sentto->addr.sa.sa_family)
|
||||||
|
log_query(F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
else
|
||||||
|
log_query(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 (sendto(fd, (char *)header, plen, 0,
|
||||||
|
&forward->sentto->addr.sa,
|
||||||
|
sa_len(&forward->sentto->addr)) == -1 && retry_send());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* retry on existing query, send to all available servers */
|
/* retry on existing query, send to all available servers */
|
||||||
domain = forward->sentto->domain;
|
domain = forward->sentto->domain;
|
||||||
forward->sentto->failed_queries++;
|
forward->sentto->failed_queries++;
|
||||||
@@ -704,7 +744,7 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
/* We've had a reply already, which we're validating. Ignore this duplicate */
|
/* We've had a reply already, which we're validating. Ignore this duplicate */
|
||||||
if (forward->stash)
|
if (forward->blocking_query)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (header->hb3 & HB3_TC)
|
if (header->hb3 & HB3_TC)
|
||||||
@@ -737,7 +777,6 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
struct frec *next = new->next;
|
struct frec *next = new->next;
|
||||||
*new = *forward; /* copy everything, then overwrite */
|
*new = *forward; /* copy everything, then overwrite */
|
||||||
new->next = next;
|
new->next = next;
|
||||||
new->stash = NULL;
|
|
||||||
new->blocking_query = NULL;
|
new->blocking_query = NULL;
|
||||||
new->rfd4 = NULL;
|
new->rfd4 = NULL;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@@ -745,7 +784,14 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
#endif
|
#endif
|
||||||
new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
|
new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
|
||||||
|
|
||||||
if ((forward->stash = blockdata_alloc((char *)header, n)))
|
/* Free any saved query */
|
||||||
|
if (forward->stash)
|
||||||
|
blockdata_free(forward->stash);
|
||||||
|
|
||||||
|
/* Now save reply pending receipt of key data */
|
||||||
|
if (!(forward->stash = blockdata_alloc((char *)header, n)))
|
||||||
|
free_frec(new); /* malloc failure, unwind */
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@@ -760,7 +806,7 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
nn = dnssec_generate_query(header, ((char *) header) + daemon->packet_buff_sz,
|
nn = dnssec_generate_query(header, ((char *) header) + daemon->packet_buff_sz,
|
||||||
daemon->keyname, forward->class, T_DNSKEY, &server->addr);
|
daemon->keyname, forward->class, T_DNSKEY, &server->addr);
|
||||||
}
|
}
|
||||||
else if (status == STAT_NEED_DS)
|
else
|
||||||
{
|
{
|
||||||
new->flags |= FREC_DS_QUERY;
|
new->flags |= FREC_DS_QUERY;
|
||||||
nn = dnssec_generate_query(header,((char *) header) + daemon->packet_buff_sz,
|
nn = dnssec_generate_query(header,((char *) header) + daemon->packet_buff_sz,
|
||||||
@@ -769,6 +815,9 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
new->crc = questions_crc(header, nn, daemon->namebuff);
|
new->crc = questions_crc(header, nn, daemon->namebuff);
|
||||||
new->new_id = get_id(new->crc);
|
new->new_id = get_id(new->crc);
|
||||||
header->id = htons(new->new_id);
|
header->id = htons(new->new_id);
|
||||||
|
/* Save query for retransmission */
|
||||||
|
new->stash = blockdata_alloc((char *)header, nn);
|
||||||
|
new->stash_len = nn;
|
||||||
|
|
||||||
/* Don't resend this. */
|
/* Don't resend this. */
|
||||||
daemon->srv_save = NULL;
|
daemon->srv_save = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user