about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-11-03 18:56:56 +0000
committerUlrich Drepper <drepper@redhat.com>2005-11-03 18:56:56 +0000
commitabab68592e2ef3fedc7328637d749ce0efe04682 (patch)
tree22596f2daf656eb1a97bc10a3b76474d548bbd7b
parent7006f757e6d6f110b88f6a5a7759d1e118870489 (diff)
downloadglibc-abab68592e2ef3fedc7328637d749ce0efe04682.tar.gz
glibc-abab68592e2ef3fedc7328637d749ce0efe04682.tar.xz
glibc-abab68592e2ef3fedc7328637d749ce0efe04682.zip
[BZ #1774]
2005-11-03  Ulrich Drepper  <drepper@redhat.com>
	[BZ #1774]
	* sysdeps/posix/getaddrinfo.c (gaih_inet): Don't use simple
	gethostbyname2 lookup if AI_V4MAPPED|AI_ALL is set.

	* sysdeps/posix/getaddrinfo.c (gaih_inet): Avoid alloca when possible
	while looking for scope delimiter.
	Some pretty printing.
-rw-r--r--ChangeLog10
-rw-r--r--sysdeps/posix/getaddrinfo.c30
2 files changed, 26 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index ea742251d3..8cdee79104 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2005-11-03  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #1774]
+	* sysdeps/posix/getaddrinfo.c (gaih_inet): Don't use simple
+	gethostbyname2 lookup if AI_V4MAPPED|AI_ALL is set.
+
+	* sysdeps/posix/getaddrinfo.c (gaih_inet): Avoid alloca when possible
+	while looking for scope delimiter.
+	Some pretty printing.
+
 2005-10-31  Steven Munroe  <sjmunroe@us.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/Makefile
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 934aae009c..81a56a0794 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -568,12 +568,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
       if (at->family == AF_UNSPEC)
 	{
-	  char *namebuf = strdupa (name);
-	  char *scope_delim;
+	  char *namebuf = (char *) name;
+	  char *scope_delim = strchr (name, SCOPE_DELIMITER);
 
-	  scope_delim = strchr (namebuf, SCOPE_DELIMITER);
-	  if (scope_delim != NULL)
-	    *scope_delim = '\0';
+	  if (__builtin_expect (scope_delim != NULL, 0))
+	    {
+	      namebuf = alloca (scope_delim - name + 1);
+	      *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
+	    }
 
 	  if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
 	    {
@@ -629,7 +631,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  /* If we do not have to look for IPv4 and IPv6 together, use
 	     the simple, old functions.  */
-	  if (req->ai_family == AF_INET || req->ai_family == AF_INET6)
+	  if (req->ai_family == AF_INET
+	      || (req->ai_family == AF_INET6
+		  && ((req->ai_flags & AI_V4MAPPED) == 0
+		      || (req->ai_flags & AI_ALL) == 0)))
 	    {
 	      int family = req->ai_family;
 	      size_t tmpbuflen = 512;
@@ -888,8 +893,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		     AF_INET6.  Try to find a useful one for both.  */
 		  if (inet6_status == NSS_STATUS_TRYAGAIN)
 		    status = NSS_STATUS_TRYAGAIN;
-		  else if (status == NSS_STATUS_UNAVAIL &&
-			   inet6_status != NSS_STATUS_UNAVAIL)
+		  else if (status == NSS_STATUS_UNAVAIL
+			   && inet6_status != NSS_STATUS_UNAVAIL)
 		    status = inet6_status;
 		}
 
@@ -1039,9 +1044,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      }
 	  }
 
-	if (at2->family == AF_INET6)
+	family = at2->family;
+	if (family == AF_INET6)
 	  {
-	    family = AF_INET6;
 	    socklen = sizeof (struct sockaddr_in6);
 
 	    /* If we looked up IPv4 mapped address discard them here if
@@ -1053,10 +1058,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      goto ignore;
 	  }
 	else
-	  {
-	    family = AF_INET;
-	    socklen = sizeof (struct sockaddr_in);
-	  }
+	  socklen = sizeof (struct sockaddr_in);
 
 	for (st2 = st; st2 != NULL; st2 = st2->next)
 	  {