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>
This commit is contained in:
parent
deaf9597c6
commit
347d18177e
3 changed files with 48 additions and 3 deletions
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=dnsmasq
|
PKG_NAME:=dnsmasq
|
||||||
PKG_VERSION:=2.78
|
PKG_VERSION:=2.78
|
||||||
PKG_RELEASE:=4
|
PKG_RELEASE:=5
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||||
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
|
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int bind_fallback = 0;
|
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();
|
set_dbus_listeners();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
if (daemon->dhcp || daemon->relay4)
|
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();
|
check_dbus_listeners();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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);
|
Loading…
Reference in a new issue