openwrt/package/network/services/dnsmasq/patches/010-localise-queries-apply-to-interface-names.patch
Kevin Darbyshire-Bryant 3bef96ef18 dnsmasq: update to dnsmasq 2.77test1
Bump to dnsmasq 2.77test1 - this includes a number of fixes since 2.76
and allows dropping of 2 LEDE carried patches.

Notable fix in rrfilter code when talking to Nominum's DNS servers
especially with DNSSEC.

A patch to switch dnsmasq back to 'soft fail' for SERVFAIL responses
from dns servers is also included.  This mean dnsmasq tries all
configured servers before giving up.

A 'localise queries' enhancement has also been backported (it will
appear in test2/rc'n') this is especially important if using the
recently imported to LEDE 'use dnsmasq standalone' feature 9525743c

I have been following dnsmasq HEAD ever since 2.76 release.
Compile & Run tested: ar71xx, Archer C7 v2

Tested-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>

Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
2017-02-05 22:26:23 +01:00

100 lines
4.0 KiB
Diff

From d42d4706bbcce3b5a40ad778a5a356a997db6b34 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Thu, 2 Feb 2017 16:52:06 +0000
Subject: [PATCH] Make --localise-queries apply to names from
--interface-name.
---
CHANGELOG | 7 +++++++
man/dnsmasq.8 | 9 +++++----
src/rfc1035.c | 21 ++++++++++++++++++++-
3 files changed, 32 insertions(+), 5 deletions(-)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -58,6 +58,13 @@ version 2.77
this is Nominum's. Thanks to Dave Täht for spotting the
bug and assisting in the fix.
+ Fix the manpage which lied that only the primary address
+ of an interface is used by --interface-name.
+
+ Make --localise-queries apply to names from --interface-name.
+ Thanks to Kevin Darbyshire-Bryant and Eric Luehrsen
+ for pushing this.
+
version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -289,8 +289,8 @@ option requires non-standard networking
under Linux. On other platforms it falls-back to --bind-interfaces mode.
.TP
.B \-y, --localise-queries
-Return answers to DNS queries from /etc/hosts which depend on the interface over which the query was
-received. If a name in /etc/hosts has more than one address associated with
+Return answers to DNS queries from /etc/hosts and --interface-name which depend on the interface over which the query was
+received. If a name has more than one address associated with
it, and at least one of those addresses is on the same subnet as the
interface to which the query was sent, then return only the
address(es) on that subnet. This allows for a server to have multiple
@@ -604,7 +604,7 @@ given by the hex data, which may be of t
012345 or any mixture of these.
.TP
.B --interface-name=<name>,<interface>[/4|/6]
-Return a DNS record associating the name with the primary address on
+Return DNS records associating the name with the address(es) of
the given interface. This flag specifies an A or AAAA record for the given
name in the same way as an /etc/hosts line, except that the address is
not constant, but taken from the given interface. The interface may be
@@ -614,7 +614,8 @@ down, not configured or non-existent, an
matching PTR record is also created, mapping the interface address to
the name. More than one name may be associated with an interface
address by repeating the flag; in that case the first instance is used
-for the reverse address-to-name mapping.
+for the reverse address-to-name mapping. Note that a name used in
+--interface-name may not appear in /etc/hosts.
.TP
.B --synth-domain=<domain>,<address range>[,<prefix>]
Create artificial A/AAAA and PTR records for an address range. The
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1516,9 +1516,24 @@ size_t answer_request(struct dns_header
if (intr)
{
struct addrlist *addrlist;
- int gotit = 0;
+ int gotit = 0, localise = 0;
enumerate_interfaces(0);
+
+ /* See if a putative address is on the network from which we recieved
+ the query, is so we'll filter other answers. */
+ if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && type == T_A)
+ for (intr = daemon->int_names; intr; intr = intr->next)
+ if (hostname_isequal(name, intr->name))
+ for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
+#ifdef HAVE_IPV6
+ if (!(addrlist->flags & ADDRLIST_IPV6))
+#endif
+ if (is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask))
+ {
+ localise = 1;
+ break;
+ }
for (intr = daemon->int_names; intr; intr = intr->next)
if (hostname_isequal(name, intr->name))
@@ -1528,6 +1543,10 @@ size_t answer_request(struct dns_header
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
#endif
{
+ if (localise &&
+ !is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask))
+ continue;
+
#ifdef HAVE_IPV6
if (addrlist->flags & ADDRLIST_REVONLY)
continue;