diff options
author | Hans Dedecker <dedeckeh@gmail.com> | 2017-12-06 14:22:59 +0100 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2017-12-06 14:55:12 +0100 |
commit | 347d18177e30cd38e26d889471696c105772d828 (patch) | |
tree | d2e4a77d60cbffcecbdda4b0f2ba7c76ba604c5f /package | |
parent | deaf9597c67aa970c27c333d9c69e3c3ad046248 (diff) | |
download | upstream-347d18177e30cd38e26d889471696c105772d828.tar.gz upstream-347d18177e30cd38e26d889471696c105772d828.tar.bz2 upstream-347d18177e30cd38e26d889471696c105772d828.zip |
dnsmasq: backport infinite dns retries fix
If all configured dns servers return refused in response to a query in
strict mode; dnsmasq will end up in an infinite loop retransmitting the
dns query resulting into high CPU load.
Problem is fixed by checking for the end of a dns server list iteration
in strict mode.
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'package')
3 files changed, 48 insertions, 3 deletions
diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile index 2c1073c148..480a8a9f48 100644 --- a/package/network/services/dnsmasq/Makefile +++ b/package/network/services/dnsmasq/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsmasq PKG_VERSION:=2.78 -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/ diff --git a/package/network/services/dnsmasq/patches/240-ubus.patch b/package/network/services/dnsmasq/patches/240-ubus.patch index 0a380ca824..d21ca0dbaa 100644 --- a/package/network/services/dnsmasq/patches/240-ubus.patch +++ b/package/network/services/dnsmasq/patches/240-ubus.patch @@ -74,7 +74,7 @@ int main (int argc, char **argv) { int bind_fallback = 0; -@@ -911,6 +969,7 @@ int main (int argc, char **argv) +@@ -911,6 +971,7 @@ int main (int argc, char **argv) set_dbus_listeners(); #endif @@ -82,7 +82,7 @@ #ifdef HAVE_DHCP if (daemon->dhcp || daemon->relay4) { -@@ -1041,6 +1100,8 @@ int main (int argc, char **argv) +@@ -1041,6 +1102,8 @@ int main (int argc, char **argv) check_dbus_listeners(); #endif diff --git a/package/network/services/dnsmasq/patches/250-Fix-infinite-retries-in-strict-order-mode.patch b/package/network/services/dnsmasq/patches/250-Fix-infinite-retries-in-strict-order-mode.patch new file mode 100644 index 0000000000..faff680e03 --- /dev/null +++ b/package/network/services/dnsmasq/patches/250-Fix-infinite-retries-in-strict-order-mode.patch @@ -0,0 +1,45 @@ +From ef3d137a646fa8309e1ff5184e3e145eef40cc4d Mon Sep 17 00:00:00 2001 +From: Simon Kelley <simon@thekelleys.org.uk> +Date: Tue, 5 Dec 2017 22:37:29 +0000 +Subject: [PATCH] Fix infinite retries in strict-order mode. + + If all configured dns servers return refused in + response to a query; dnsmasq will end up in an infinite loop + retransmitting the dns query resulting into high CPU load. + Problem is caused by the dns refuse retransmission logic which does + not check for the end of a dns server list iteration in strict mode. + Having one configured dns server returning a refused reply easily + triggers this problem in strict order mode. This was introduced in + 9396752c115b3ab733fa476b30da73237e12e7ba + + Thanks to Hans Dedecker <dedeckeh@gmail.com> for spotting this + and the initial patch. +--- + src/forward.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/src/forward.c ++++ b/src/forward.c +@@ -797,10 +797,20 @@ void reply_query(int fd, int family, tim + unsigned char *pheader; + size_t plen; + int is_sign; +- ++ ++ /* In strict order mode, there must be a server later in the chain ++ left to send to, otherwise without the forwardall mechanism, ++ code further on will cycle around the list forwever if they ++ all return REFUSED. Note that server is always non-NULL before ++ this executes. */ ++ if (option_bool(OPT_ORDER)) ++ for (server = forward->sentto->next; server; server = server->next) ++ if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR | SERV_LOOP))) ++ break; ++ + /* recreate query from reply */ + pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL); +- if (!is_sign) ++ if (!is_sign && server) + { + header->ancount = htons(0); + header->nscount = htons(0); |