Fix rare "Internal error in cache" messages.
authorSimon Kelley <simon@thekelleys.org.uk>
Fri, 24 Dec 2021 18:58:35 +0000 (18:58 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 24 Dec 2021 18:58:35 +0000 (18:58 +0000)
Fix error created in 1ce1c6beae9f683bec54cba4c0d375f85b209b95

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.

src/cache.c

index f9a874c..246c3f2 100644 (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))
            {
              /* 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))))
                {
                  if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))