[source] dnsmasq: backport infinite dns retries fix

LEDE Commits lede-commits at lists.infradead.org
Wed Dec 6 05:57:45 PST 2017


dedeckeh pushed a commit to source.git, branch master:
https://git.lede-project.org/347d18177e30cd38e26d889471696c105772d828

commit 347d18177e30cd38e26d889471696c105772d828
Author: Hans Dedecker <dedeckeh at gmail.com>
AuthorDate: Wed Dec 6 14:22:59 2017 +0100

    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 at gmail.com>
---
 package/network/services/dnsmasq/Makefile          |  2 +-
 .../services/dnsmasq/patches/240-ubus.patch        |  4 +-
 ...Fix-infinite-retries-in-strict-order-mode.patch | 45 ++++++++++++++++++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile
index 2c1073c..480a8a9 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 0a380ca..d21ca0d 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 0000000..faff680
--- /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 at 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 at 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);



More information about the lede-commits mailing list