about summary refs log tree commit diff
path: root/src/network
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-06-03 01:46:40 -0400
committerRich Felker <dalias@aerifal.cx>2014-06-03 01:46:40 -0400
commitd85d261ee601f7ccf0bb19c38c69e406a664fe8e (patch)
tree84050e89d696caeb81cca49c11a00e8590b8d3c6 /src/network
parentac2a7893427b6c94f05609d214178f8d5a18b333 (diff)
downloadmusl-d85d261ee601f7ccf0bb19c38c69e406a664fe8e.tar.gz
musl-d85d261ee601f7ccf0bb19c38c69e406a664fe8e.tar.xz
musl-d85d261ee601f7ccf0bb19c38c69e406a664fe8e.zip
fix negative response and non-response handling for dns queries
previously, all failures to obtain at least one address were treated
as nonexistant names (EAI_NONAME). this failed to account for the
possibility of transient failures (no response at all, or a response
with rcode of 2, server failure) or permanent failures that do not
indicate the nonexistence of the requested name. only an rcode of 3
should be treated as an indication of nonexistence.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/lookup_name.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index 8d41627a..02920930 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -151,7 +151,10 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static
 	for (i=0; i<nq; i++)
 		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
 
-	return ctx.cnt;
+	if (ctx.cnt) return ctx.cnt;
+	if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
+	if ((abuf[0][3] & 15) == 3) return EAI_NONAME;
+	return EAI_FAIL;
 }
 
 int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)