about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2010-01-14 22:34:28 -0800
committerUlrich Drepper <drepper@redhat.com>2010-01-14 22:34:28 -0800
commitace4e23f8c495927d3f24554b41560858ee50d4f (patch)
treece29d872625874e14a00a578d70df34be404bbc3
parent21f5de55ec4fa5eba06060c40fed87aad2aecdee (diff)
downloadglibc-ace4e23f8c495927d3f24554b41560858ee50d4f.tar.gz
glibc-ace4e23f8c495927d3f24554b41560858ee50d4f.tar.xz
glibc-ace4e23f8c495927d3f24554b41560858ee50d4f.zip
Always use IPv4 sockets for IPv4 addresses.
-rw-r--r--ChangeLog4
-rw-r--r--resolv/res_send.c44
2 files changed, 13 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index f5dd3ac003..f25912ede8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2010-01-14  Ulrich Drepper  <drepper@redhat.com>
 
+	[BZ #11141]
+	* resolv/res_send.c (reopen): Don't use IPv6 sockets for IPv4
+	addresses.
+
 	[BZ #11127]
 	* posix/regcomp.c (alc_eclosure_iter): Do not ignore
 	re_node_set_insert failure; return REG_ESPACE.
diff --git a/resolv/res_send.c b/resolv/res_send.c
index e2bbfcc83f..28a47e42b8 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -199,10 +199,6 @@ static void		Perror(const res_state, FILE *, const char *, int);
 #endif
 static int		sock_eq(struct sockaddr_in6 *, struct sockaddr_in6 *);
 
-/* Reachover. */
-
-static void convaddr4to6(struct sockaddr_in6 *sa);
-
 /* Public. */
 
 /* int
@@ -911,10 +907,12 @@ static int
 reopen (res_state statp, int *terrno, int ns)
 {
 	if (EXT(statp).nssocks[ns] == -1) {
-		struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+		struct sockaddr *nsap
+		  = (struct sockaddr *) EXT(statp).nsaddrs[ns];
+		socklen_t slen;
 
 		/* only try IPv6 if IPv6 NS and if not failed before */
-		if ((EXT(statp).nscount6 > 0) && !statp->ipv6_unavail) {
+		if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
 			if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
 				EXT(statp).nssocks[ns] =
 				  socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
@@ -931,12 +929,8 @@ reopen (res_state statp, int *terrno, int ns)
 				  socket(PF_INET6, SOCK_DGRAM, 0);
 			if (EXT(statp).nssocks[ns] < 0)
 			    statp->ipv6_unavail = errno == EAFNOSUPPORT;
-			/* If IPv6 socket and nsap is IPv4, make it
-			   IPv4-mapped */
-			else if (nsap->sin6_family == AF_INET)
-			    convaddr4to6(nsap);
-		}
-		if (EXT(statp).nssocks[ns] < 0) {
+			slen = sizeof (struct sockaddr_in6);
+		} else if (nsap->sa_family == AF_INET) {
 			if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
 				EXT(statp).nssocks[ns]
 				  = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
@@ -951,6 +945,7 @@ reopen (res_state statp, int *terrno, int ns)
 			if (__builtin_expect (__have_o_nonblock < 0, 0))
 				EXT(statp).nssocks[ns]
 				  = socket(PF_INET, SOCK_DGRAM, 0);
+			slen = sizeof (struct sockaddr_in);
 		}
 		if (EXT(statp).nssocks[ns] < 0) {
 			*terrno = errno;
@@ -969,10 +964,8 @@ reopen (res_state statp, int *terrno, int ns)
 		 * error message is received.  We can thus detect
 		 * the absence of a nameserver without timing out.
 		 */
-		if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap,
-			    sizeof *nsap) < 0) {
-			Aerror(statp, stderr, "connect(dg)", errno,
-			       (struct sockaddr *) nsap);
+		if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
+			Aerror(statp, stderr, "connect(dg)", errno, nsap);
 			__res_iclose(statp, false);
 			return (0);
 		}
@@ -1415,22 +1408,3 @@ sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
 		(a1->sin6_addr.s6_addr32[3] ==
 		 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
 }
-
-/*
- * Converts IPv4 family, address and port to
- * IPv6 family, IPv4-mapped IPv6 address and port.
- */
-static void
-convaddr4to6(struct sockaddr_in6 *sa)
-{
-    struct sockaddr_in *sa4p = (struct sockaddr_in *) sa;
-    in_port_t port = sa4p->sin_port;
-    in_addr_t addr = sa4p->sin_addr.s_addr;
-
-    sa->sin6_family = AF_INET6;
-    sa->sin6_port = port;
-    sa->sin6_addr.s6_addr32[0] = 0;
-    sa->sin6_addr.s6_addr32[1] = 0;
-    sa->sin6_addr.s6_addr32[2] = htonl(0xFFFF);
-    sa->sin6_addr.s6_addr32[3] = addr;
-}