2010-01-14 Ulrich Drepper [BZ #11141] * resolv/res_send.c (reopen): Don't use IPv6 sockets for IPv4 addresses. diff --git a/resolv/res_send.c b/resolv/res_send.c index e2bbfcc..28a47e4 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; -}