Fix long-term bug in TCP caching code which would lose NXDOMAIN.

A NXDOMAIN answer recieved over TCP by a child process would
be correctly sent back to the master process which would then
fail to insert it into the cache.
This commit is contained in:
Simon Kelley
2023-04-01 22:03:49 +01:00
parent a78487a4df
commit b14aa762ff

View File

@@ -800,6 +800,7 @@ void cache_end_insert(void)
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
{
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
if (flags & F_RR)
@@ -824,6 +825,7 @@ void cache_end_insert(void)
#endif
}
}
}
new_chain = tmp;
}
@@ -872,10 +874,32 @@ int cache_recv_insert(time_t now, int fd)
ttl = difftime(ttd, now);
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
if (flags & F_CNAME)
{
struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
/* This relies on the fact that the target of a CNAME immediately precedes
it because of the order of extraction in extract_addresses, and
the order reversal on the new_chain. */
if (newc)
{
newc->addr.cname.is_name_ptr = 0;
if (!crecp)
newc->addr.cname.target.cache = NULL;
else
{
next_uid(crecp);
newc->addr.cname.target.cache = crecp;
newc->addr.cname.uid = crecp->uid;
}
}
}
else
{
unsigned short class = C_IN;
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
{
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
return 0;
@@ -896,29 +920,10 @@ int cache_recv_insert(time_t now, int fd)
return 0;
}
#endif
}
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
}
else if (flags & F_CNAME)
{
struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
/* This relies on the fact that the target of a CNAME immediately precedes
it because of the order of extraction in extract_addresses, and
the order reversal on the new_chain. */
if (newc)
{
newc->addr.cname.is_name_ptr = 0;
if (!crecp)
newc->addr.cname.target.cache = NULL;
else
{
next_uid(crecp);
newc->addr.cname.target.cache = crecp;
newc->addr.cname.uid = crecp->uid;
}
}
}
}
}