Hello everyone!

I have created a patch that adds an option to dnsmasq to filter out A record 
requests. This is particularly suitable for IPv6-only environments. Some 
software (especially NodeJS) will reorder DNS requests giving priority to A 
records, irrespective of IPv4 connectivity of the host. My patch filters A 
records, while AAAA records are returned.

In theory, the OS shouldn't send A records requests in the first place, if no 
IPv4 connectivity exists. Otherwise, most OS don't send AAAA record requests if 
no IPv6 connectivity exists. So my patch mitigates some of the problems in 
IPv6-only environments.

Is there any chance for such a patch to make it into official dnsmasq? Are 
pull-requests on github acted on? That would be my preferred method, otherwise 
I will post the patch here.

Cheers,
Treysis

Patch:

>From bd22a36f76e35a0dc6c8be8996056318fec96e5e Mon Sep 17 00:00:00 2001
From: treysis <trey...@gmx.net>
Date: Sat, 5 Jun 2021 15:27:26 +0200
Subject: [PATCH] Add option to filter A record requests

---
 src/dnsmasq.h |  3 ++-
 src/option.c  |  3 +++
 src/rfc1035.c | 11 +++++++++++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 95dc8ae..7eae110 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -272,7 +272,8 @@ struct event_desc {
 #define OPT_LOG_DEBUG      62
 #define OPT_UMBRELLA       63
 #define OPT_UMBRELLA_DEVID 64
-#define OPT_LAST           65
+#define OPT_FILTER_A       65
+#define OPT_LAST           66

 #define OPTION_BITS (sizeof(unsigned int)*8)
 #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
diff --git a/src/option.c b/src/option.c
index 23cf058..a81aa1f 100644
--- a/src/option.c
+++ b/src/option.c
@@ -171,6 +171,7 @@ struct myoption {
 #define LOPT_DYNHOST       362
 #define LOPT_LOG_DEBUG     363
 #define LOPT_UMBRELLA     364
+#define LOPT_FILTER_A      365

 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =
@@ -347,6 +348,7 @@ static const struct myoption opts[] =
     { "dynamic-host", 1, 0, LOPT_DYNHOST },
     { "log-debug", 0, 0, LOPT_LOG_DEBUG },
        { "umbrella", 2, 0, LOPT_UMBRELLA },
+    { "filter-a", 0, 0, LOPT_FILTER_A },
     { NULL, 0, 0, 0 }
   };

@@ -530,6 +532,7 @@ static struct {
   { LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to 
dump"), NULL },
   { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script 
when lease expiry changes."), NULL },
   { LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella 
identifiers including remote IP."), NULL },
+  { LOPT_FILTER_A, OPT_FILTER_A, NULL, gettext_noop("Filter all A requests."), 
NULL },
   { 0, 0, NULL, NULL, NULL }
 };

diff --git a/src/rfc1035.c b/src/rfc1035.c
index 5a961b8..d859b48 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1895,6 +1895,17 @@ size_t answer_request(struct dns_header *header, char 
*limit, size_t qlen,
            }
        }

+       /* filter a forwards */
+       if (qtype == T_A && option_bool(OPT_FILTER_A))
+         {
+           /* return a null reply */
+               ans = 1;
+               if (!dryrun)
+                 log_query(F_CONFIG | F_IPV6 | F_NEG, name, &addr, NULL);
+               break;
+         }
+       /* end of filtering a */
+
       if (!ans)
        return 0; /* failed to answer a question */
     }

_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to