Hi Simon,
I would like to propose an optional --no-auto-edns setting for compatibility 
with upstream DNS servers or intervening network devices which fail to handle 
queries carrying EDNS0.
Since dnsmasq 2.91, a plain upstream UDP query is automatically given an OPT 
record. Reducing --edns-packet-max still leaves that record present; this 
proposal allows administrators to suppress its automatic creation.
The attached patch changes only that default insertion step when the option is 
enabled. Existing OPT records are retained, including those supplied by clients 
or created by configured EDNS features or DNSSEC. The usual UDP-size adjustment 
still applies to an existing record. Default behaviour and TCP forwarding are 
unchanged. The patch includes help text and a manual entry.
Base: upstream master a9880c595f052d63859d6ed8aa86a3a6b007bf20.
The patch applies independently, without OpenWrt patches.
After rebasing, the default build, option/configuration checks and manual 
formatting were checked. Live upstream-query and DNSSEC protocol testing were 
not performed in this environment, so I am submitting this as an RFC.
I used AI assistance in preparing the change and its review. Would an opt-in 
compatibility setting with this scope be acceptable?
Best regards,
Dmitry
Subject: [RFC PATCH] Add a no-auto-edns compatibility option

Since 2.91, dnsmasq automatically adds EDNS0 to an upstream UDP query
which does not already contain an OPT record. Add an opt-in compatibility
setting for upstream servers or intervening devices which do not handle
these queries correctly.

With --no-auto-edns, skip only this automatic creation of an OPT record.
Existing EDNS0 is retained, including client-supplied records and records
created for explicitly configured EDNS features or DNSSEC. Continue to
apply the existing UDP-size adjustment when an OPT record is present.
Default behaviour and TCP query forwarding are unchanged.

Document the option in the manual and command-line help. Based on the
locally maintained dnsmasq 2.93 no-auto-edns v2 patch; rebased onto current
upstream without OpenWrt packaging changes.

Base-commit: a9880c595f052d63859d6ed8aa86a3a6b007bf20

---
 man/dnsmasq.8 | 11 +++++++++++
 src/dnsmasq.h |  3 ++-
 src/forward.c | 10 ++++++++--
 src/option.c  |  4 ++++
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 89233257ef5a6d9e3e8163aaffd2e342dfae54ed..12da8a02bb0e6b25e1fbc98ce33138781079cdf9 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -199,6 +199,17 @@ Specify the largest EDNS.0 UDP packet which is supported by the DNS
 forwarder. Defaults to 1232, which is the recommended size following the
 DNS flag day in 2020. Only increase if you know what you are doing.
 .TP
+.B --no-auto-edns
+Do not automatically add an EDNS0 OPT pseudo-record when forwarding a
+UDP DNS query which does not already contain one. This is a compatibility
+option for upstream DNS servers or network devices which fail to handle
+EDNS0 queries. The default is to add EDNS0 and advertise the size set by
+.B --edns-packet-max.
+An existing OPT record, whether supplied by the client or added by an
+explicitly enabled feature such as DNSSEC validation, is retained and its
+advertised UDP size is still adjusted in the usual way. This option does
+not disable EDNS0 or DNSSEC, and does not change TCP query forwarding.
+.TP
 .B \-Q, --query-port=<query_port>
 Send outbound DNS queries from, and listen for their replies on, the
 specific UDP port <query_port> instead of using random ports. NOTE
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index ecff18d652573749cda46a90486300b0d8d83bbf..059b967709b0fbf9fda2b84a0ea9a925be091fe8 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -296,7 +296,8 @@ struct event_desc {
 #define OPT_LEASEQUERY     77
 #define OPT_LOG_ONLY_FAILED  78
 #define OPT_LOG_MALLOC     79
-#define OPT_LAST           80
+#define OPT_NO_AUTO_EDNS   80
+#define OPT_LAST           81
 
 #define OPTION_BITS (sizeof(unsigned int)*8)
 #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
diff --git a/src/forward.c b/src/forward.c
index f736c302f10caa82b76b8b047aaf3fef2f64e230..0517ebe5af6d48f9b475ccb9831dc5cc5d6d112d 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -513,8 +513,14 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
 
   forwarded = 0;
 
-  /* Advertise the size of UDP reply we can accept. */
-  plen = add_pseudoheader(header, plen, daemon->edns_pktsz, 0, NULL, 0, 0, 0);
+  /* Since 2.91 dnsmasq normally adds EDNS0 to every upstream query.
+     In compatibility mode, retain EDNS0 only when the query already has
+     a pseudo-header, for example because the client supplied it or an
+     enabled feature such as DNSSEC created it. */
+  if (!option_bool(OPT_NO_AUTO_EDNS) ||
+      find_pseudoheader(header, plen, NULL, NULL, NULL, NULL))
+    plen = add_pseudoheader(header, plen, daemon->edns_pktsz,
+                            0, NULL, 0, 0, 0);
 
   /* check for send errors here (no route to host) 
      if we fail to send to all nameservers, send back an error
diff --git a/src/option.c b/src/option.c
index 44bd52274397e70275c1507becb09eb97ba4f934..75f61917152d1eb714d2852349d9f275814a6768 100644
--- a/src/option.c
+++ b/src/option.c
@@ -201,6 +201,7 @@ struct myoption {
 #define LOPT_LEASEQUERY    389
 #define LOPT_SPLIT_RELAY   390
 #define LOPT_LOG_MALLOC    391
+#define LOPT_NO_AUTO_EDNS  392
 
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -257,6 +258,7 @@ static const struct myoption opts[] =
     { "no-round-robin", 0, 0, LOPT_NORR },
     { "no-0x20-encode", 0, 0, LOPT_NO_ENCODE },
     { "do-0x20-encode", 0, 0, LOPT_DO_ENCODE },
+    { "no-auto-edns", 0, 0, LOPT_NO_AUTO_EDNS },
     { "cache-rr", 1, 0, LOPT_CACHE_RR },
     { "addn-hosts", 1, 0, 'H' },
     { "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
@@ -608,6 +610,8 @@ static struct {
   { LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
   { LOPT_NO_ENCODE, OPT_NO_0x20, NULL, gettext_noop("Suppress DNS bit 0x20 encoding."), NULL },
   { LOPT_DO_ENCODE, OPT_DO_0x20, NULL, gettext_noop("Enable DNS bit 0x20 encoding."), NULL },
+  { LOPT_NO_AUTO_EDNS, OPT_NO_AUTO_EDNS, NULL,
+    gettext_noop("Do not add EDNS0 to plain upstream DNS queries."), NULL },
   { LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
   { LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
   { LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to