Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 22 Jun 2024 17:54:29 +0800
From: Lance Yang <>
Cc: Lance Yang <>
Subject: [PATCH 1/1] improve DNS resolution logic for parallel queries

From: Lance Yang <>

musl’s resolver queries some configured nameservers in parallel and accepts
the first response. However, if the first response's RCODE indicates
NXDOMAIN, the resolver terminates the resolution process too early,
potentially missing valid responses from other nameservers.

There is a DNS issue that is reproducible under specific conditions. For
instance, it occurs when one of the nameservers does not have the domain
name and responds first. Even worse, if this nameserver consistently
responds the fastest, the domain name will never be resolved successfully.

This commit introduces a 'send_tracker' counter to track the number of
queries sent. The resolver now continues waiting for responses from other
nameservers unless only one query was sent, ensuring more robust DNS

Signed-off-by: Lance Yang <>
 src/network/res_msend.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/network/res_msend.c b/src/network/res_msend.c
index 86c2fcf4..29f1ce0b 100644
--- a/src/network/res_msend.c
+++ b/src/network/res_msend.c
@@ -98,6 +98,7 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
 	unsigned char alen_buf[nqueries][2];
 	int r;
 	unsigned long t0, t1, t2;
+	int send_tracker = 0;
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
@@ -185,7 +186,7 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
 			/* Query all configured namservers in parallel */
 			for (i=0; i<nqueries; i++)
 				if (!alens[i])
-					for (j=0; j<nns; j++)
+					for (j=0; j<nns; j++, send_tracker++)
 						sendto(fd, queries[i],
 							qlens[i], MSG_NOSIGNAL,
 							(void *)&ns[j], sl);
@@ -228,14 +229,19 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
 			 * all other codes such as refusal. */
 			switch (answers[next][3] & 15) {
 			case 0:
-			case 3:
+			case 3:
+				if (send_tracker <= 1)
+					break;
 			case 2:
-				if (servfail_retry && servfail_retry--)
+				if (servfail_retry && servfail_retry--) {
 					sendto(fd, queries[i],
 						qlens[i], MSG_NOSIGNAL,
 						(void *)&ns[j], sl);
+					send_tracker++;
+				}
+				send_tracker--;

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.