From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14840 invoked by alias); 28 Aug 2006 10:09:10 -0000 Received: (qmail 14814 invoked by uid 22791); 28 Aug 2006 10:09:08 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 28 Aug 2006 10:09:03 +0000 Received: from sunsite.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id k7SA8pjL015542; Mon, 28 Aug 2006 12:08:51 +0200 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.1/8.13.1/Submit) id k7SA8puI015541; Mon, 28 Aug 2006 12:08:51 +0200 Date: Mon, 28 Aug 2006 10:09:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] getnameinfo fixes Message-ID: <20060828100850.GL4556@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-08/txt/msg00029.txt.bz2 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 * 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