mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix case of DS queries to domains marked as not doing DNSSEC.
This was causing confusion: DNSSEC queries would be sent to servers for domains that don't do DNSSEC, but because of that status the answers would be treated as answers to ordinary queries, sometimes resulting in a crash.
This commit is contained in:
@@ -120,8 +120,10 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
|
|||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
|
|
||||||
for (serv = daemon->servers; serv; serv=serv->next)
|
for (serv = daemon->servers; serv; serv=serv->next)
|
||||||
|
if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
|
||||||
|
continue;
|
||||||
/* domain matches take priority over NODOTS matches */
|
/* domain matches take priority over NODOTS matches */
|
||||||
if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
|
else if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
|
||||||
{
|
{
|
||||||
unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
|
unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
|
||||||
*type = SERV_FOR_NODOTS;
|
*type = SERV_FOR_NODOTS;
|
||||||
@@ -933,14 +935,13 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
/* Find server to forward to. This will normally be the
|
/* Find server to forward to. This will normally be the
|
||||||
same as for the original query, but may be another if
|
same as for the original query, but may be another if
|
||||||
servers for domains are involved. */
|
servers for domains are involved. */
|
||||||
if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
|
if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
|
||||||
{
|
{
|
||||||
struct server *start = server, *new_server = NULL;
|
struct server *start = server, *new_server = NULL;
|
||||||
type &= ~SERV_DO_DNSSEC;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (type == (start->flags & SERV_TYPE) &&
|
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
|
||||||
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
||||||
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
||||||
{
|
{
|
||||||
@@ -963,7 +964,6 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
new->sentto = server;
|
new->sentto = server;
|
||||||
|
|
||||||
new->rfd4 = NULL;
|
new->rfd4 = NULL;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
new->rfd6 = NULL;
|
new->rfd6 = NULL;
|
||||||
@@ -1506,14 +1506,12 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
|||||||
/* Find server to forward to. This will normally be the
|
/* Find server to forward to. This will normally be the
|
||||||
same as for the original query, but may be another if
|
same as for the original query, but may be another if
|
||||||
servers for domains are involved. */
|
servers for domains are involved. */
|
||||||
if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) != 0)
|
if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
|
||||||
{
|
{
|
||||||
new_status = STAT_ABANDONED;
|
new_status = STAT_ABANDONED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
type &= ~SERV_DO_DNSSEC;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (!firstsendto)
|
if (!firstsendto)
|
||||||
@@ -1530,7 +1528,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != (server->flags & SERV_TYPE) ||
|
if (type != (server->flags & (SERV_TYPE | SERV_DO_DNSSEC)) ||
|
||||||
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
|
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
|
||||||
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
||||||
continue;
|
continue;
|
||||||
@@ -2080,6 +2078,8 @@ static void free_frec(struct frec *f)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* if wait==NULL return a free or older than TIMEOUT record.
|
/* if wait==NULL return a free or older than TIMEOUT record.
|
||||||
else return *wait zero if one available, or *wait is delay to
|
else return *wait zero if one available, or *wait is delay to
|
||||||
when the oldest in-use record will expire. Impose an absolute
|
when the oldest in-use record will expire. Impose an absolute
|
||||||
@@ -2126,7 +2126,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
|
|||||||
|
|
||||||
/* can't find empty one, use oldest if there is one
|
/* can't find empty one, use oldest if there is one
|
||||||
and it's older than timeout */
|
and it's older than timeout */
|
||||||
if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
|
if (!force && oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
|
||||||
{
|
{
|
||||||
/* keep stuff for twice timeout if we can by allocating a new
|
/* keep stuff for twice timeout if we can by allocating a new
|
||||||
record instead */
|
record instead */
|
||||||
|
|||||||
Reference in New Issue
Block a user