250-Fix-infinite-retries-in-strict-order-mode.patch 1.8 KB

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