mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
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:
47
src/cache.c
47
src/cache.c
@@ -800,6 +800,7 @@ void cache_end_insert(void)
|
|||||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
|
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
|
||||||
|
|
||||||
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_RR))
|
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);
|
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
|
||||||
|
|
||||||
if (flags & F_RR)
|
if (flags & F_RR)
|
||||||
@@ -824,6 +825,7 @@ void cache_end_insert(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_chain = tmp;
|
new_chain = tmp;
|
||||||
}
|
}
|
||||||
@@ -872,10 +874,32 @@ int cache_recv_insert(time_t now, int fd)
|
|||||||
|
|
||||||
ttl = difftime(ttd, now);
|
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;
|
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))
|
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -896,29 +920,10 @@ int cache_recv_insert(time_t now, int fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user