Fix rare "Internal error in cache" messages.

Fix error created in 1ce1c6beae

Many thanks to Hartmut Birr for finding the bug and bisecting to
the guilty commit.

The breaking commit creates cache entries which have F_NXDOMAIN
set but none of F_IPV4, F_IPV6 or F_SRV. If cache_scan_free() is called
to delete such an entry it will fail to do so.

If the cache has no free slots and the least-recently-used slot is such
an entry, then a new insertion will attempt to make space by calling
cache_scan_free(), which will fail when it should be impossible and
trigger the internal error.
This commit is contained in:
Simon Kelley
2021-12-24 18:58:35 +00:00
parent 18b1d1424e
commit ea33a01303

View File

@@ -413,7 +413,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name)) if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
{ {
/* Don't delete DNSSEC in favour of a CNAME, they can co-exist */ /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) || if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV | F_NXDOMAIN)) ||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS)))) (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
{ {
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))