Always use IPv4 sockets for IPv4 addresses.
authorUlrich Drepper <drepper@redhat.com>
Fri, 15 Jan 2010 06:34:28 +0000 (22:34 -0800)
committerUlrich Drepper <drepper@redhat.com>
Fri, 15 Jan 2010 06:34:28 +0000 (22:34 -0800)
ChangeLog
resolv/res_send.c

index f5dd3ac003ee6f6b355678cb8b124a2515f5d261..f25912ede8c77c499d4fa43c7a6d2399dae5c78e 100644 (file)
--- 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.
index e2bbfcc83f0229efb3bc7cc2027e6cb9ee7a59ed..28a47e42b8ef03726db2e087faa45e67a9ad5726 100644 (file)
@@ -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;
-}