1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- From 8ce27433f8b2e17c557cb55e4f16941d309deeac Mon Sep 17 00:00:00 2001
- From: Simon Kelley <[email protected]>
- Date: Fri, 17 Jan 2025 17:49:29 +0000
- Subject: [PATCH] Handle DS queries to auth zones.
- Origin: upstream, v2.91test8
- When dnsmasq is configured to act as an authoritative server and has
- an authoritative zone configured, and recieves a query for
- that zone _as_forwarder_ it answers the query directly rather
- than forwarding it. This doesn't affect the answer, but it
- saves dnsmasq forwarding the query to the recusor upstream,
- whch then bounces it back to dnsmasq in auth mode. The
- exception should be when the query is for the root of zone, for a DS
- RR. The answer to that has to come from the parent, via the
- recursor, and will typically be a proof-of-nonexistence since
- dnsmasq doesn't support signed zones. This patch suppresses
- local answers and forces forwarding to the upstream recursor
- for such queries. It stops breakage when a DNSSEC validating
- client makes queries to dnsmasq acting as forwarder for a zone
- for which it is authoritative.
- [ukleinek: drop changes to CHANGELOG to prevent conflicts]
- ---
- src/forward.c | 52 +++++++++++++++++++++++++++++++++++++--------------
- 1 file changed, 38 insertions(+), 14 deletions(-)
- --- a/src/forward.c
- +++ b/src/forward.c
- @@ -1744,15 +1744,27 @@ void receive_query(struct listener *list
- #endif
-
- #ifdef HAVE_AUTH
- - /* find queries for zones we're authoritative for, and answer them directly */
- + /* Find queries for zones we're authoritative for, and answer them directly.
- + The exception to this is DS queries for the zone route. They
- + have to come from the parent zone. Since dnsmasq's auth server
- + can't do DNSSEC, the zone will be unsigned, and anything using
- + dnsmasq as a forwarder and doing validation will be expecting to
- + see the proof of non-existence from the parent. */
- if (!auth_dns && !option_bool(OPT_LOCALISE))
- for (zone = daemon->auth_zones; zone; zone = zone->next)
- - if (in_zone(zone, daemon->namebuff, NULL))
- - {
- - auth_dns = 1;
- - local_auth = 1;
- - break;
- - }
- + {
- + char *cut;
- +
- + if (in_zone(zone, daemon->namebuff, &cut))
- + {
- + if (type != T_DS || cut)
- + {
- + auth_dns = 1;
- + local_auth = 1;
- + }
- + break;
- + }
- + }
- #endif
-
- #ifdef HAVE_LOOP
- @@ -2268,15 +2280,27 @@ unsigned char *tcp_request(int confd, ti
- &peer_addr, auth_dns ? "auth" : "query", qtype);
-
- #ifdef HAVE_AUTH
- - /* find queries for zones we're authoritative for, and answer them directly */
- + /* Find queries for zones we're authoritative for, and answer them directly.
- + The exception to this is DS queries for the zone route. They
- + have to come from the parent zone. Since dnsmasq's auth server
- + can't do DNSSEC, the zone will be unsigned, and anything using
- + dnsmasq as a forwarder and doing validation will be expecting to
- + see the proof of non-existence from the parent. */
- if (!auth_dns && !option_bool(OPT_LOCALISE))
- for (zone = daemon->auth_zones; zone; zone = zone->next)
- - if (in_zone(zone, daemon->namebuff, NULL))
- - {
- - auth_dns = 1;
- - local_auth = 1;
- - break;
- - }
- + {
- + char *cut;
- +
- + if (in_zone(zone, daemon->namebuff, &cut))
- + {
- + if (qtype != T_DS || cut)
- + {
- + auth_dns = 1;
- + local_auth = 1;
- + }
- + break;
- + }
- + }
- #endif
- }
- }
|