[Dnsmasq-discuss] [PATCH v2] Fix local host records being overridden by upstream NXDOMAIN

Dominik Derigs dl6er at dl6er.de
Sun Aug 9 07:57:05 UTC 2026


Hey Simon,

this is iteration #2 of a patch I sent on 2026-05-16, archived as

https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q2/018476.html

It has had no reply, so here it is again, rebased onto current master 
and with
one small change over v1 (see below).

A name that only exists locally - /etc/hosts, a DHCP lease, or 
--host-record -
loses to upstream when it is queried for a type it does not have. 
answer_request()
finds no matching record, gives up, and the query is forwarded. The 
upstream is
authoritative for the public parent zone, knows nothing about the name and
answers NXDOMAIN, which is factually wrong: the name does exist, it just 
has no
record of that type. This bites hard in practice because Linux resolvers 
send
AAAA and HTTPS/SVCB alongside every A query, so a plain A-only host 
record is
enough to trigger it several times per lookup.

There is already a safety net for this in process_reply(), converting an
upstream NXDOMAIN for a locally-known name into NODATA, but it sits 
behind the
!bogusanswer gate. For a local name under a signed public parent the 
upstream
denial is exactly the answer that fails validation, so the one code path 
meant
to catch this case is skipped whenever DNSSEC is on.

The patch closes both:

1. answer_request() answers NODATA itself when the name has local
    F_HOSTS/F_DHCP/F_CONFIG records but nothing for the queried type, so the
    query is never forwarded in the first place.

2. The NXDOMAIN-to-NODATA conversion in process_reply() runs before the
    bogus-answer gate. Local records are authoritative for a name's 
existence
    no matter what an upstream denial validates to.

Changed in v2: the log_query() call in answer_request() now only sets
F_IPV4/F_IPV6 for A/AAAA queries, so an MX or HTTPS query is logged as
"NODATA" instead of "NODATA-IPv6".

Reproducer, with --host-record=node-1.example.org,10.0.20.20 and any 
upstream
that is authoritative for example.org:

   dig @localhost node-1.example.org A       -> NOERROR, 10.0.20.20
   dig @localhost node-1.example.org AAAA    -> forwarded, upstream NXDOMAIN
   dig @localhost node-1.example.org HTTPS   -> forwarded, upstream NXDOMAIN

With the patch the last two are answered locally as NODATA and never 
leave the
machine. Downstream report with a user hitting this in the wild:
https://github.com/pi-hole/FTL/issues/2841

Best regards,
Dominik
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v2-0001-Fix-local-host-records-being-overridden-by-upstre.patch
Type: text/x-patch
Size: 3891 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20260809/238cd151/attachment.bin>


More information about the Dnsmasq-discuss mailing list