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