mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
dnsmasq: bump to 2.77
This is a cumulative backport of multiple dnsmasq update commits in master. Drops three LEDE specific patches which are included upstream and another patch which became obsolete. Remaining LEDE specific patches are rebased. Fixes FS#766 - Intermittent SIGSEGV crash of dnsmasq-full. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
9e20cc56b9
commit
cdfc6788a9
@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dnsmasq
|
||||
PKG_VERSION:=2.76
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=2.77
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
|
||||
PKG_HASH:=4b92698dee19ca0cb2a8f2e48f1d2dffd01a21eb15d1fbed4cf085630c8c9f96
|
||||
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
|
||||
PKG_HASH:=6eac3b1c50ae25170e3ff8c96ddb55236cf45007633fdb8a35b1f3e02f5f8b8a
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
@ -1,130 +0,0 @@
|
||||
From 68f6312d4bae30b78daafcd6f51dc441b8685b1e Mon Sep 17 00:00:00 2001
|
||||
From: Baptiste Jonglez <git@bitsofnetworks.org>
|
||||
Date: Mon, 6 Feb 2017 21:09:11 +0000
|
||||
Subject: [PATCH] Stop treating SERVFAIL as a successful response from upstream
|
||||
servers.
|
||||
|
||||
This effectively reverts most of 51967f9807 ("SERVFAIL is an expected
|
||||
error return, don't try all servers.") and 4ace25c5d6 ("Treat REFUSED (not
|
||||
SERVFAIL) as an unsuccessful upstream response").
|
||||
|
||||
With the current behaviour, as soon as dnsmasq receives a SERVFAIL from an
|
||||
upstream server, it stops trying to resolve the query and simply returns
|
||||
SERVFAIL to the client. With this commit, dnsmasq will instead try to
|
||||
query other upstream servers upon receiving a SERVFAIL response.
|
||||
|
||||
According to RFC 1034 and 1035, the semantic of SERVFAIL is that of a
|
||||
temporary error condition. Recursive resolvers are expected to encounter
|
||||
network or resources issues from time to time, and will respond with
|
||||
SERVFAIL in this case. Similarly, if a validating DNSSEC resolver [RFC
|
||||
4033] encounters issues when checking signatures (unknown signing
|
||||
algorithm, missing signatures, expired signatures because of a wrong
|
||||
system clock, etc), it will respond with SERVFAIL.
|
||||
|
||||
Note that all those behaviours are entirely different from a negative
|
||||
response, which would provide a definite indication that the requested
|
||||
name does not exist. In our case, if an upstream server responds with
|
||||
SERVFAIL, another upstream server may well provide a positive answer for
|
||||
the same query.
|
||||
|
||||
Thus, this commit will increase robustness whenever some upstream servers
|
||||
encounter temporary issues or are misconfigured.
|
||||
|
||||
Quoting RFC 1034, Section 4.3.1. "Queries and responses":
|
||||
|
||||
If recursive service is requested and available, the recursive response
|
||||
to a query will be one of the following:
|
||||
|
||||
- The answer to the query, possibly preface by one or more CNAME
|
||||
RRs that specify aliases encountered on the way to an answer.
|
||||
|
||||
- A name error indicating that the name does not exist. This
|
||||
may include CNAME RRs that indicate that the original query
|
||||
name was an alias for a name which does not exist.
|
||||
|
||||
- A temporary error indication.
|
||||
|
||||
Here is Section 5.2.3. of RFC 1034, "Temporary failures":
|
||||
|
||||
In a less than perfect world, all resolvers will occasionally be unable
|
||||
to resolve a particular request. This condition can be caused by a
|
||||
resolver which becomes separated from the rest of the network due to a
|
||||
link failure or gateway problem, or less often by coincident failure or
|
||||
unavailability of all servers for a particular domain.
|
||||
|
||||
And finally, RFC 1035 specifies RRCODE 2 for this usage, which is now more
|
||||
widely known as SERVFAIL (RFC 1035, Section 4.1.1. "Header section format"):
|
||||
|
||||
RCODE Response code - this 4 bit field is set as part of
|
||||
responses. The values have the following
|
||||
interpretation:
|
||||
(...)
|
||||
|
||||
2 Server failure - The name server was
|
||||
unable to process this query due to a
|
||||
problem with the name server.
|
||||
|
||||
For the DNSSEC-related usage of SERVFAIL, here is RFC 4033
|
||||
Section 5. "Scope of the DNSSEC Document Set and Last Hop Issues":
|
||||
|
||||
A validating resolver can determine the following 4 states:
|
||||
(...)
|
||||
|
||||
Insecure: The validating resolver has a trust anchor, a chain of
|
||||
trust, and, at some delegation point, signed proof of the
|
||||
non-existence of a DS record. This indicates that subsequent
|
||||
branches in the tree are provably insecure. A validating resolver
|
||||
may have a local policy to mark parts of the domain space as
|
||||
insecure.
|
||||
|
||||
Bogus: The validating resolver has a trust anchor and a secure
|
||||
delegation indicating that subsidiary data is signed, but the
|
||||
response fails to validate for some reason: missing signatures,
|
||||
expired signatures, signatures with unsupported algorithms, data
|
||||
missing that the relevant NSEC RR says should be present, and so
|
||||
forth.
|
||||
(...)
|
||||
|
||||
This specification only defines how security-aware name servers can
|
||||
signal non-validating stub resolvers that data was found to be bogus
|
||||
(using RCODE=2, "Server Failure"; see [RFC4035]).
|
||||
|
||||
Notice the difference between a definite negative answer ("Insecure"
|
||||
state), and an indefinite error condition ("Bogus" state). The second
|
||||
type of error may be specific to a recursive resolver, for instance
|
||||
because its system clock has been incorrectly set, or because it does not
|
||||
implement newer cryptographic primitives. Another recursive resolver may
|
||||
succeed for the same query.
|
||||
|
||||
There are other similar situations in which the specified behaviour is
|
||||
similar to the one implemented by this commit.
|
||||
|
||||
For instance, RFC 2136 specifies the behaviour of a "requestor" that wants
|
||||
to update a zone using the DNS UPDATE mechanism. The requestor tries to
|
||||
contact all authoritative name servers for the zone, with the following
|
||||
behaviour specified in RFC 2136, Section 4:
|
||||
|
||||
4.6. If a response is received whose RCODE is SERVFAIL or NOTIMP, or
|
||||
if no response is received within an implementation dependent timeout
|
||||
period, or if an ICMP error is received indicating that the server's
|
||||
port is unreachable, then the requestor will delete the unusable
|
||||
server from its internal name server list and try the next one,
|
||||
repeating until the name server list is empty. If the requestor runs
|
||||
out of servers to try, an appropriate error will be returned to the
|
||||
requestor's caller.
|
||||
---
|
||||
src/forward.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -853,7 +853,8 @@ void reply_query(int fd, int family, tim
|
||||
we get a good reply from another server. Kill it when we've
|
||||
had replies from all to avoid filling the forwarding table when
|
||||
everything is broken */
|
||||
- if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != REFUSED)
|
||||
+ if (forward->forwardall == 0 || --forward->forwardall == 1 ||
|
||||
+ (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
|
||||
{
|
||||
int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
|
||||
|
@ -1,47 +0,0 @@
|
||||
--- a/src/dhcp.c
|
||||
+++ b/src/dhcp.c
|
||||
@@ -147,7 +147,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
ssize_t sz;
|
||||
int iface_index = 0, unicast_dest = 0, is_inform = 0;
|
||||
int rcvd_iface_index;
|
||||
- struct in_addr iface_addr;
|
||||
+ struct in_addr iface_addr, *addrp = NULL;
|
||||
struct iface_param parm;
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
struct arpreq arp_req;
|
||||
@@ -277,11 +277,9 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
{
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
|
||||
- iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
- else
|
||||
{
|
||||
- my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
- return;
|
||||
+ addrp = &iface_addr;
|
||||
+ iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
}
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
@@ -300,7 +298,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
parm.relay_local.s_addr = 0;
|
||||
parm.ind = iface_index;
|
||||
|
||||
- if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
|
||||
+ if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, NULL))
|
||||
{
|
||||
/* If we failed to match the primary address of the interface, see if we've got a --listen-address
|
||||
for a secondary */
|
||||
@@ -320,6 +318,12 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
|
||||
}
|
||||
|
||||
+ if (!addrp)
|
||||
+ {
|
||||
+ my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!iface_enumerate(AF_INET, &parm, complete_context))
|
||||
return;
|
||||
|
@ -44,67 +44,22 @@
|
||||
(buffer = safe_malloc(BUFF_SZ)) &&
|
||||
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
|
||||
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
|
||||
@@ -168,62 +149,16 @@ static int new_add_to_ipset(const char *
|
||||
}
|
||||
|
||||
|
||||
-static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
|
||||
-{
|
||||
- socklen_t size;
|
||||
- struct ip_set_req_adt_get {
|
||||
- unsigned op;
|
||||
- unsigned version;
|
||||
- union {
|
||||
- char name[IPSET_MAXNAMELEN];
|
||||
- uint16_t index;
|
||||
- } set;
|
||||
- char typename[IPSET_MAXNAMELEN];
|
||||
- } req_adt_get;
|
||||
- struct ip_set_req_adt {
|
||||
- unsigned op;
|
||||
- uint16_t index;
|
||||
- uint32_t ip;
|
||||
- } req_adt;
|
||||
-
|
||||
- if (strlen(setname) >= sizeof(req_adt_get.set.name))
|
||||
- {
|
||||
- errno = ENAMETOOLONG;
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- req_adt_get.op = 0x10;
|
||||
- req_adt_get.version = 3;
|
||||
- strcpy(req_adt_get.set.name, setname);
|
||||
- size = sizeof(req_adt_get);
|
||||
- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
|
||||
- return -1;
|
||||
- req_adt.op = remove ? 0x102 : 0x101;
|
||||
- req_adt.index = req_adt_get.set.index;
|
||||
- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
|
||||
- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-
|
||||
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
|
||||
{
|
||||
int af = AF_INET;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -217,17 +198,10 @@ int add_to_ipset(const char *setname, co
|
||||
if (flags & F_IPV6)
|
||||
- {
|
||||
{
|
||||
af = AF_INET6;
|
||||
- /* old method only supports IPv4 */
|
||||
- if (old_kernel)
|
||||
- return -1;
|
||||
- }
|
||||
- {
|
||||
- errno = EAFNOSUPPORT ;
|
||||
- ret = -1;
|
||||
- }
|
||||
}
|
||||
#endif
|
||||
|
||||
- return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
+ return new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
}
|
||||
- if (ret != -1)
|
||||
- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
+ ret = new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
|
||||
#endif
|
||||
if (ret == -1)
|
||||
my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
|
||||
|
@ -1,149 +0,0 @@
|
||||
From f6bea86c78ba9efbd01da3dd2fb18764ec806290 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 7 Sep 2016 09:35:07 +0100
|
||||
Subject: [PATCH] dnsmasq: compile time option NO_ID
|
||||
|
||||
Some consider it good practice to obscure software version numbers to
|
||||
clients. Compiling with -DNO_ID removes the *.bind info structure.
|
||||
This includes: version, author, copyright, cachesize, cache insertions,
|
||||
evictions, misses & hits, auth & servers.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 2 ++
|
||||
src/config.h | 5 +++++
|
||||
src/dnsmasq.h | 4 ++++
|
||||
src/option.c | 8 ++++++--
|
||||
src/rfc1035.c | 3 ++-
|
||||
5 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -1290,6 +1290,7 @@ void cache_add_dhcp_entry(char *host_nam
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifndef NO_ID
|
||||
int cache_make_stat(struct txt_record *t)
|
||||
{
|
||||
static char *buff = NULL;
|
||||
@@ -1385,6 +1386,7 @@ int cache_make_stat(struct txt_record *t
|
||||
*buff = len;
|
||||
return 1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* There can be names in the cache containing control chars, don't
|
||||
mess up logging or open security holes. */
|
||||
--- a/src/config.h
|
||||
+++ b/src/config.h
|
||||
@@ -120,6 +120,8 @@ HAVE_LOOP
|
||||
HAVE_INOTIFY
|
||||
use the Linux inotify facility to efficiently re-read configuration files.
|
||||
|
||||
+NO_ID
|
||||
+ Don't report *.bind CHAOS info to clients.
|
||||
NO_IPV6
|
||||
NO_TFTP
|
||||
NO_DHCP
|
||||
@@ -434,6 +436,9 @@ static char *compile_opts =
|
||||
"no-"
|
||||
#endif
|
||||
"DNSSEC "
|
||||
+#ifdef NO_ID
|
||||
+"no-ID "
|
||||
+#endif
|
||||
#ifndef HAVE_LOOP
|
||||
"no-"
|
||||
#endif
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -286,6 +286,7 @@ struct naptr {
|
||||
struct naptr *next;
|
||||
};
|
||||
|
||||
+#ifndef NO_ID
|
||||
#define TXT_STAT_CACHESIZE 1
|
||||
#define TXT_STAT_INSERTS 2
|
||||
#define TXT_STAT_EVICTIONS 3
|
||||
@@ -293,6 +294,7 @@ struct naptr {
|
||||
#define TXT_STAT_HITS 5
|
||||
#define TXT_STAT_AUTH 6
|
||||
#define TXT_STAT_SERVERS 7
|
||||
+#endif
|
||||
|
||||
struct txt_record {
|
||||
char *name;
|
||||
@@ -1078,7 +1080,9 @@ void cache_add_dhcp_entry(char *host_nam
|
||||
struct in_addr a_record_from_hosts(char *name, time_t now);
|
||||
void cache_unhash_dhcp(void);
|
||||
void dump_cache(time_t now);
|
||||
+#ifndef NO_ID
|
||||
int cache_make_stat(struct txt_record *t);
|
||||
+#endif
|
||||
char *cache_get_name(struct crec *crecp);
|
||||
char *cache_get_cname_target(struct crec *crecp);
|
||||
struct crec *cache_enumerate(int init);
|
||||
--- a/src/option.c
|
||||
+++ b/src/option.c
|
||||
@@ -657,7 +657,8 @@ static int atoi_check8(char *a, int *res
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
-
|
||||
+
|
||||
+#ifndef NO_ID
|
||||
static void add_txt(char *name, char *txt, int stat)
|
||||
{
|
||||
struct txt_record *r = opt_malloc(sizeof(struct txt_record));
|
||||
@@ -670,13 +671,14 @@ static void add_txt(char *name, char *tx
|
||||
*(r->txt) = len;
|
||||
memcpy((r->txt)+1, txt, len);
|
||||
}
|
||||
-
|
||||
+
|
||||
r->stat = stat;
|
||||
r->name = opt_string_alloc(name);
|
||||
r->next = daemon->txt;
|
||||
daemon->txt = r;
|
||||
r->class = C_CHAOS;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static void do_usage(void)
|
||||
{
|
||||
@@ -4515,6 +4517,7 @@ void read_opts(int argc, char **argv, ch
|
||||
daemon->soa_expiry = SOA_EXPIRY;
|
||||
daemon->max_port = MAX_PORT;
|
||||
|
||||
+#ifndef NO_ID
|
||||
add_txt("version.bind", "dnsmasq-" VERSION, 0 );
|
||||
add_txt("authors.bind", "Simon Kelley", 0);
|
||||
add_txt("copyright.bind", COPYRIGHT, 0);
|
||||
@@ -4527,6 +4530,7 @@ void read_opts(int argc, char **argv, ch
|
||||
add_txt("auth.bind", NULL, TXT_STAT_AUTH);
|
||||
#endif
|
||||
add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
|
||||
+#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -1264,6 +1264,7 @@ size_t answer_request(struct dns_header
|
||||
unsigned long ttl = daemon->local_ttl;
|
||||
int ok = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
|
||||
+#ifndef NO_ID
|
||||
/* Dynamically generate stat record */
|
||||
if (t->stat != 0)
|
||||
{
|
||||
@@ -1271,7 +1272,7 @@ size_t answer_request(struct dns_header
|
||||
if (!cache_make_stat(t))
|
||||
ok = 0;
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
ttl, NULL,
|
||||
T_TXT, t->class, "t", t->len, t->txt))
|
@ -35,13 +35,13 @@ Signed-off-by: Steven Barth <steven@midlink.org>
|
||||
+ if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0)
|
||||
{
|
||||
/* time already OK, update timestamp, and do key checking from the start. */
|
||||
if (utime(daemon->timestamp_file, NULL) == -1)
|
||||
if (utimes(daemon->timestamp_file, NULL) == -1)
|
||||
@@ -493,7 +500,7 @@ int setup_timestamp(void)
|
||||
|
||||
close(fd);
|
||||
|
||||
- timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
|
||||
+ timestamp_time = timbuf.actime = timbuf.modtime = base;
|
||||
if (utime(daemon->timestamp_file, &timbuf) == 0)
|
||||
goto check_and_exit;
|
||||
}
|
||||
- timestamp_time = 1420070400; /* 1-1-2015 */
|
||||
+ timestamp_time = base; /* 1-1-2015 */
|
||||
tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
|
||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||
if (utimes(daemon->timestamp_file, tv) == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user