This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] getnameinfo fixes


Hi!

http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=204122
complains that getnameinfo suffers similar problem like getaddrinfo used to
6 years ago, namely that EAI_AGAIN is not returned when it should.
While looking at it, I noticed e.g. struct hostent *h = NULL; if (h == NULL)
{ ... } bogosity, AF_INET loop not checking herrno == NETDB_INTERNAL and
when returning EAI_SYSTEM setting errno to the saved errno value from when
getnameinfo was entered (but the standard says that for EAI_SYSTEM errno
should contain the error code).  I have also moved the error checking code
out of the loops, removing the need to duplicate the checks, all that
is needed to check in the loops is the NETDB_INTERNAL/ERANGE condition,
so that we can grow the buffer.

What I'm not 100% sure is what should we do in the herrno == TRY_AGAIN
case, when NI_NAMEREQD is not set in flags.  The patch below will return
EAI_AGAIN for that, while previously it would return inet_ntop result.

2006-08-28  Jakub Jelinek  <jakub@redhat.com>

	* inet/getnameinfo.c (getnameinfo): For AF_INET, check errno
	only if herrno is NETDB_INTERNAL.  Handle errors other than
	ERANGE outside of the loops, handle TRY_AGAIN.

--- libc/inet/getnameinfo.c.jj	2006-06-21 17:36:38.000000000 +0200
+++ libc/inet/getnameinfo.c	2006-08-28 11:47:44.000000000 +0200
@@ -203,48 +203,40 @@ getnameinfo (const struct sockaddr *sa, 
 	if (!(flags & NI_NUMERICHOST))
 	  {
 	    struct hostent *h = NULL;
+	    if (sa->sa_family == AF_INET6)
+	      {
+		while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
+					  sizeof(struct in6_addr),
+					  AF_INET6, &th, tmpbuf, tmpbuflen,
+					  &h, &herrno))
+		  if (herrno == NETDB_INTERNAL && errno == ERANGE)
+		    tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		  else
+		    break;
+	      }
+	    else
+	      {
+		while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
+					  sizeof(struct in_addr), AF_INET,
+					  &th, tmpbuf, tmpbuflen,
+					  &h, &herrno))
+		  if (herrno == NETDB_INTERNAL && errno == ERANGE)
+		    tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		  else
+		    break;
+	      }
+
 	    if (h == NULL)
 	      {
-		if (sa->sa_family == AF_INET6)
+		if (herrno == NETDB_INTERNAL)
 		  {
-		    while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
-					      sizeof(struct in6_addr),
-					      AF_INET6, &th, tmpbuf, tmpbuflen,
-					      &h, &herrno))
-		      {
-			if (herrno == NETDB_INTERNAL)
-			  {
-			    if (errno == ERANGE)
-			      tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
-						      2 * tmpbuflen);
-			    else
-			      {
-				__set_h_errno (herrno);
-				__set_errno (serrno);
-				return EAI_SYSTEM;
-			      }
-			  }
-			else
-			  {
-			    break;
-			  }
-		      }
+		    __set_h_errno (herrno);
+		    return EAI_SYSTEM;
 		  }
-		else
+		if (herrno == TRY_AGAIN)
 		  {
-		    while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
-					      sizeof(struct in_addr), AF_INET,
-					      &th, tmpbuf, tmpbuflen,
-					      &h, &herrno))
-		      {
-			if (errno == ERANGE)
-			  tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
-						  2 * tmpbuflen);
-			else
-			  {
-			    break;
-			  }
-		      }
+		    __set_h_errno (herrno);
+		    return EAI_AGAIN;
 		  }
 	      }
 
@@ -361,10 +353,7 @@ getnameinfo (const struct sockaddr *sa, 
 				 (const void *) &(((const struct sockaddr_in *) sa)->sin_addr),
 				 host, hostlen);
 		if (c == NULL)
-		  {
-		    __set_errno (serrno);
-		    return EAI_SYSTEM;
-		  }
+		  return EAI_SYSTEM;
 	      }
 	    ok = 1;
 	  }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]