Discussion:
[Dnsmasq-discuss] [PATCH] Fix dns query retransmission when --strict-order active
Hans Dedecker
2017-12-04 09:15:27 UTC
Permalink
Commit 9396752c115b3ab733fa476b30da73237e12e7ba added support for dns query
retransmission in case a server returns refused in strict-order mode.
The patch did not cover the case when all servers return refused triggering
a dns query retransmission storm resulting into a high cpu load by dnsmasq.
Fix the problem by checking in strict-order mode if a next dns server is
available in the dns server list before forwarding the query again.

Signed-off-by: Hans Dedecker <***@gmail.com>
---
src/forward.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/forward.c b/src/forward.c
index 4824759..3d58571 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -799,11 +799,23 @@ void reply_query(int fd, int family, time_t now)
{
unsigned char *pheader;
size_t plen;
- int is_sign;
-
+ int is_sign, fwd_query = 0;
+
+ if (option_bool(OPT_ORDER))
+ {
+ /* try to find a good server to which the query can be forwarded */
+ 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)))
+ {
+ fwd_query = 1;
+ break;
+ }
+ } else
+ fwd_query = 1;
+
/* recreate query from reply */
pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
- if (!is_sign)
+ if (!is_sign && fwd_query)
{
header->ancount = htons(0);
header->nscount = htons(0);
--
1.9.1
Simon Kelley
2017-12-05 22:41:48 UTC
Permalink
OK, I re-worked this and committed it as

http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=ef3d137a646fa8309e1ff5184e3e145eef40cc4d

Please could you check I didn't break anything?


Cheers,

Simon.
Post by Hans Dedecker
Commit 9396752c115b3ab733fa476b30da73237e12e7ba added support for dns query
retransmission in case a server returns refused in strict-order mode.
The patch did not cover the case when all servers return refused triggering
a dns query retransmission storm resulting into a high cpu load by dnsmasq.
Fix the problem by checking in strict-order mode if a next dns server is
available in the dns server list before forwarding the query again.
---
src/forward.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/forward.c b/src/forward.c
index 4824759..3d58571 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -799,11 +799,23 @@ void reply_query(int fd, int family, time_t now)
{
unsigned char *pheader;
size_t plen;
- int is_sign;
-
+ int is_sign, fwd_query = 0;
+
+ if (option_bool(OPT_ORDER))
+ {
+ /* try to find a good server to which the query can be forwarded */
+ 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)))
+ {
+ fwd_query = 1;
+ break;
+ }
+ } else
+ fwd_query = 1;
+
/* recreate query from reply */
pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
- if (!is_sign)
+ if (!is_sign && fwd_query)
{
header->ancount = htons(0);
header->nscount = htons(0);
Hans Dedecker
2017-12-06 14:02:38 UTC
Permalink
Post by Simon Kelley
OK, I re-worked this and committed it as
http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=ef3d137a646fa8309e1ff5184e3e145eef40cc4d
Please could you check I didn't break anything?
Testing with the patch did not show any regression; looks fine for me

Hans
Post by Simon Kelley
Cheers,
Simon.
Post by Hans Dedecker
Commit 9396752c115b3ab733fa476b30da73237e12e7ba added support for dns query
retransmission in case a server returns refused in strict-order mode.
The patch did not cover the case when all servers return refused triggering
a dns query retransmission storm resulting into a high cpu load by dnsmasq.
Fix the problem by checking in strict-order mode if a next dns server is
available in the dns server list before forwarding the query again.
---
src/forward.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/forward.c b/src/forward.c
index 4824759..3d58571 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -799,11 +799,23 @@ void reply_query(int fd, int family, time_t now)
{
unsigned char *pheader;
size_t plen;
- int is_sign;
-
+ int is_sign, fwd_query = 0;
+
+ if (option_bool(OPT_ORDER))
+ {
+ /* try to find a good server to which the query can be forwarded */
+ 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)))
+ {
+ fwd_query = 1;
+ break;
+ }
+ } else
+ fwd_query = 1;
+
/* recreate query from reply */
pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
- if (!is_sign)
+ if (!is_sign && fwd_query)
{
header->ancount = htons(0);
header->nscount = htons(0);
Loading...