about summary refs log tree commit diff
path: root/resolv/res_send.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-07-28 22:55:10 +0000
committerUlrich Drepper <drepper@redhat.com>2008-07-28 22:55:10 +0000
commitb7da31a1647e378258174d1d69097a594e31f89b (patch)
treea38031232a20545f6c044a94f6823ecfb6090ead /resolv/res_send.c
parent372aece0e4b7497f894f21b36bcc32ec52344ad5 (diff)
downloadglibc-b7da31a1647e378258174d1d69097a594e31f89b.tar.gz
glibc-b7da31a1647e378258174d1d69097a594e31f89b.tar.xz
glibc-b7da31a1647e378258174d1d69097a594e31f89b.zip
* resolv/res_send.c (__libc_res_nsend): Take additional parameter. cvs/fedora-glibc-20080728T2320
	Use it instead of locally defined resplen2 variable.
	(res_nsend): Adjust for __libc_res_nsend interface change.
	(send_vc): Initialize *resplen2 if necessary.  Read length of
	package into an appropriately aligned variable.  Store converted length
	in new variable and use it appropriately.
	Add branch prediction help.
	* resolv/res_query.c (__libc_res_nquery): Take additional parameter
	and pass it on to __libc_res_nsend.  Adjust all callers.
	(__libc_res_nsearch): Likewise.
	(__libc_res_nqeurydomain): Likewise.
	* resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
	change.
	(_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
	Define resplen2 variable and pass it to __libc_res_nsearch and then
	to gaih_getanswer.
	(getanswer_r): In case of incorrect DNS data don't overread buffer.
	Add branch prediction.
	(gaih_getanswer_slice): Likewise.  Check for invalid data types.
	(gaih_getanswer): Don't decode second slice if first one failed due
	to a too small buffer.  Don't let not found status of second
	decoder shadow results of the first.
	* resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
	and __libc_res_nquery interface changes
	(gethostbyaddr): Adjust for __libc_res_nquery interface change.
	* include/resolv.h: Adjust prototypes for __libc_res_nquery,
	__libc_res_nsearch, and __libc_res_nsend.
	* resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
	change.
	* resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
	__libc_res_nsearch interface changes.
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r--resolv/res_send.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c
index dec3ac7a3f..3130f64281 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -339,9 +339,9 @@ int
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 		 const u_char *buf2, int buflen2,
 		 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
-		 int *nansp2)
+		 int *nansp2, int *resplen2)
 {
-  int gotsomewhere, terrno, try, v_circuit, resplen, resplen2, ns, n;
+  int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
 	if (statp->nscount == 0) {
 		__set_errno (ESRCH);
@@ -539,7 +539,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			try = statp->retry;
 			n = send_vc(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
-				    ns, ansp, ansp2, nansp2, &resplen2);
+				    ns, ansp, ansp2, nansp2, resplen2);
 			if (n < 0)
 				return (-1);
 			if (n == 0)
@@ -549,14 +549,14 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			n = send_dg(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
 				    ns, &v_circuit, &gotsomewhere, ansp,
-				    ansp2, nansp2, &resplen2);
+				    ansp2, nansp2, resplen2);
 			if (n < 0)
 				return (-1);
 			if (n == 0)
 				goto next_ns;
 			if (v_circuit)
 			  // XXX Check whether both requests failed or
-			  // XXX whether one have been answered successfully
+			  // XXX whether one has been answered successfully
 				goto same_ns;
 		}
 
@@ -575,7 +575,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 		  DprintQ((statp->options & RES_DEBUG) ||
 			  (statp->pfcode & RES_PRF_REPLY),
 			  (stdout, "%s", ""),
-			  *ansp2, (resplen2 > *nansp2) ? *nansp2 : resplen2);
+			  *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
 
 		/*
 		 * If we have temporarily opened a virtual circuit,
@@ -638,7 +638,7 @@ res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
   return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
-			  NULL, NULL, NULL);
+			  NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsend)
 
@@ -665,6 +665,8 @@ send_vc(res_state statp,
 	u_short len2;
 	u_char *cp;
 
+	if (resplen2 != NULL)
+	  *resplen2 = 0;
 	connreset = 0;
  same_ns:
 	truncating = 0;
@@ -734,8 +736,9 @@ send_vc(res_state statp,
 	int recvresp2 = buf2 == NULL;
  read_len:
 	cp = ans;
-	len = INT16SZ;
-	while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, (char *)cp,
+	uint16_t rlen16;
+	len = sizeof(rlen16);
+	while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, &rlen16,
 					     (int)len))) > 0) {
 		cp += n;
 		if ((len -= n) <= 0)
@@ -760,11 +763,7 @@ send_vc(res_state statp,
 		}
 		return (0);
 	}
-#ifdef _STRING_ARCH_unaligned
-	resplen = ntohs (*(uint16_t *) ans);
-#else
-	resplen = ns_get16(ans);
-#endif
+	int rlen = ntohs (rlen16);
 
 	int *thisanssizp;
 	u_char **thisansp;
@@ -795,11 +794,11 @@ send_vc(res_state statp,
 	}
 	anhp = (HEADER *) *thisansp;
 
-	*thisresplenp = resplen;
-	if (resplen > *thisanssizp) {
+	*thisresplenp = rlen;
+	if (rlen > *thisanssizp) {
 		/* Yes, we test ANSCP here.  If we have two buffers
 		   both will be allocatable.  */
-		if (anscp) {
+		if (__builtin_expect (anscp != NULL, 1)) {
 			u_char *newp = malloc (MAXPACKET);
 			if (newp == NULL) {
 				*terrno = ENOMEM;
@@ -809,7 +808,7 @@ send_vc(res_state statp,
 			*thisanssizp = MAXPACKET;
 			*thisansp = newp;
 			anhp = (HEADER *) newp;
-			len = resplen;
+			len = rlen;
 		} else {
 			Dprint(statp->options & RES_DEBUG,
 				(stdout, ";; response truncated\n")
@@ -818,9 +817,9 @@ send_vc(res_state statp,
 			len = *thisanssizp;
 		}
 	} else
-		len = resplen;
+		len = rlen;
 
-	if (len < HFIXEDSZ) {
+	if (__builtin_expect (len < HFIXEDSZ, 0)) {
 		/*
 		 * Undersized message.
 		 */
@@ -836,18 +835,18 @@ send_vc(res_state statp,
 		cp += n;
 		len -= n;
 	}
-	if (n <= 0) {
+	if (__builtin_expect (n <= 0, 0)) {
 		*terrno = errno;
 		Perror(statp, stderr, "read(vc)", errno);
 		__res_iclose(statp, false);
 		return (0);
 	}
-	if (truncating) {
+	if (__builtin_expect (truncating, 0)) {
 		/*
 		 * Flush rest of answer so connection stays in synch.
 		 */
 		anhp->tc = 1;
-		len = resplen - *thisanssizp;
+		len = rlen - *thisanssizp;
 		while (len != 0) {
 			char junk[PACKETSZ];
 
@@ -872,7 +871,7 @@ send_vc(res_state statp,
 			(statp->pfcode & RES_PRF_REPLY),
 			(stdout, ";; old answer (unexpected):\n"),
 			*thisansp,
-			(resplen > *thisanssiz) ? *thisanssiz: resplen);
+			(rlen > *thisanssiz) ? *thisanssiz: rlen);
 		goto read_len;
 	}
 
@@ -889,7 +888,7 @@ send_vc(res_state statp,
 	 * All is well, or the error is fatal.  Signal that the
 	 * next nameserver ought not be tried.
 	 */
-	return (resplen);
+	return resplen;
 }
 
 static int
@@ -1084,7 +1083,7 @@ send_dg(res_state statp,
 		*thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
 					 *thisanssizp, 0,
 					(struct sockaddr *)&from, &fromlen);
-		if (*thisresplenp <= 0) {
+		if (__builtin_expect (*thisresplenp <= 0, 0)) {
 			if (errno == EINTR || errno == EAGAIN) {
 				need_recompute = 1;
 				goto wait;
@@ -1093,7 +1092,7 @@ send_dg(res_state statp,
 			goto err_out;
 		}
 		*gotsomewhere = 1;
-		if (*thisresplenp < HFIXEDSZ) {
+		if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
 			/*
 			 * Undersized message.
 			 */