dnsmasq: backport infinite dns retries fix
[openwrt/openwrt.git] / package / network / services / dnsmasq / patches / 250-Fix-infinite-retries-in-strict-order-mode.patch
1 From ef3d137a646fa8309e1ff5184e3e145eef40cc4d Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Tue, 5 Dec 2017 22:37:29 +0000
4 Subject: [PATCH] Fix infinite retries in strict-order mode.
5
6 If all configured dns servers return refused in
7 response to a query; dnsmasq will end up in an infinite loop
8 retransmitting the dns query resulting into high CPU load.
9 Problem is caused by the dns refuse retransmission logic which does
10 not check for the end of a dns server list iteration in strict mode.
11 Having one configured dns server returning a refused reply easily
12 triggers this problem in strict order mode. This was introduced in
13 9396752c115b3ab733fa476b30da73237e12e7ba
14
15 Thanks to Hans Dedecker <dedeckeh@gmail.com> for spotting this
16 and the initial patch.
17 ---
18 src/forward.c | 14 ++++++++++++--
19 1 file changed, 12 insertions(+), 2 deletions(-)
20
21 --- a/src/forward.c
22 +++ b/src/forward.c
23 @@ -797,10 +797,20 @@ void reply_query(int fd, int family, tim
24 unsigned char *pheader;
25 size_t plen;
26 int is_sign;
27 -
28 +
29 + /* In strict order mode, there must be a server later in the chain
30 + left to send to, otherwise without the forwardall mechanism,
31 + code further on will cycle around the list forwever if they
32 + all return REFUSED. Note that server is always non-NULL before
33 + this executes. */
34 + if (option_bool(OPT_ORDER))
35 + for (server = forward->sentto->next; server; server = server->next)
36 + if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR | SERV_LOOP)))
37 + break;
38 +
39 /* recreate query from reply */
40 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
41 - if (!is_sign)
42 + if (!is_sign && server)
43 {
44 header->ancount = htons(0);
45 header->nscount = htons(0);