Don't return NXDOMAIN to empty non-terminals.
When a record is defined locally, eg an A record for one.two.example then
we already know that if we forward, eg an AAAA query for one.two.example,
and get back NXDOMAIN, then we need to alter that to NODATA. This is handled
by check_for_local_domain(). But, if we forward two.example, because
one.two.example exists, then the answer to two.example should also be
a NODATA.
For most local records this is easy, just to substring matching.
for A, AAAA and CNAME records that are in the cache, it's more difficult.
The cache has no efficient way to find such records. The fix is to
insert empty (none of F_IPV4, F_IPV6 F_CNAME set) records for each
non-terminal.
The same considerations apply in auth mode, and the same basic mechanism
is used there too.
diff --git a/src/util.c b/src/util.c
index 532bc16..b27d50e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -355,6 +355,44 @@
return 1;
}
+/* is b equal to or a subdomain of a return 2 for equal, 1 for subdomain */
+int hostname_issubdomain(char *a, char *b)
+{
+ char *ap, *bp;
+ unsigned int c1, c2;
+
+ /* move to the end */
+ for (ap = a; *ap; ap++);
+ for (bp = b; *bp; bp++);
+
+ /* a shorter than b or a empty. */
+ if ((bp - b) < (ap - a) || ap == a)
+ return 0;
+
+ do
+ {
+ c1 = (unsigned char) *(--ap);
+ c2 = (unsigned char) *(--bp);
+
+ if (c1 >= 'A' && c1 <= 'Z')
+ c1 += 'a' - 'A';
+ if (c2 >= 'A' && c2 <= 'Z')
+ c2 += 'a' - 'A';
+
+ if (c1 != c2)
+ return 0;
+ } while (ap != a);
+
+ if (bp == b)
+ return 2;
+
+ if (*(--bp) == '.')
+ return 1;
+
+ return 0;
+}
+
+
time_t dnsmasq_time(void)
{
#ifdef HAVE_BROKEN_RTC