NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/44915: getaddrinfo() error code usage



>Number:         44915
>Category:       lib
>Synopsis:       getaddrinfo() error code usage
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 28 12:05:01 +0000 2011
>Originator:     Havard Eidnes
>Release:        NetBSD 5.1
>Organization:
        I Try, Inc.
>Environment:
System: NetBSD smistad.uninett.no 5.1 NetBSD 5.1 (MAANEN) #12: Wed Dec 22 
11:42:27 CET 2010 
he%smistad.uninett.no@localhost:/usr/obj/sys/arch/i386/compile/MAANEN i386
Architecture: i386
Machine: i386
>Description:
        There are a few issues with getaddrinfo() this particular PR
        addresses:

         - getaddrinfo() when looking for AAAA info for a name which
           has a CNAME but where the target doesn't have AAAA returns
           EAI_FAIL ("Non-recoverable failure in name resolution").

           I think RFC 3493 prescribes that EAI_NONAME should be
           returned instead.

         - getaddrinfo() makes use of the EAI_NODATA error code.
           Between RFC 2553 and RFC 3493, that error code has
           apparently been deprecated.  I have searched but not found
           the reason for this particular change; it may have come
           from the POSIX side.

         - The error text for EAI_NONAME is perhaps a bit confusing
           and also slightly misleading ("hostname nor servname
           provided, or not known"); I have tried to think of a better
           short message which is more fitting, but the best I've come
           up with so far is "Hostname/servname/address-type not found
           or not provided", which is longer and which I'm not
           entirely happy with, but it also covers the case where
           "name exists, but not the data you were looking for".

           No diff is provided for this particular issue.

>How-To-Repeat:
        % ping6 www.apple.com
        ping6: Non-recoverable failure in name resolution
        % dig www.apple.com. aaaa
        ...
        ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 0
        ...
        ;; ANSWER SECTION:
        www.apple.com.              1262 IN CNAME www.isg-apple.com.akadns.net.
        www.isg-apple.com.akadns.net. 60 IN CNAME www.apple.com.edgekey.net.
        www.apple.com.edgekey.net.  6583 IN CNAME e3191.c.akamaiedge.net.
        ...     
        

        The deprecation of EAI_NODATA can be seen by inspection in RFC
        3493.

>Fix:
        The first hunk below removes an instance where EAI_NODATA is
        being returned, bringing us one small step closer to complying
        with RFC 3493.  EAI_NONAME is returned instead.

        The rest is so that we distinguish between "no data of
        requested type" and "(severe) lookup failure" which otherwise
        appears as the default error code.


Index: net/getaddrinfo.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getaddrinfo.c,v
retrieving revision 1.91.6.1
diff -u -u -p -r1.91.6.1 getaddrinfo.c
--- net/getaddrinfo.c   26 Jan 2009 00:27:34 -0000      1.91.6.1
+++ net/getaddrinfo.c   28 Apr 2011 11:19:28 -0000
@@ -581,7 +581,7 @@ explore_fqdn(const struct addrinfo *pai,
                error = EAI_FAIL;
                goto free;
        case NS_NOTFOUND:
-               error = EAI_NODATA;
+               error = EAI_NONAME;
                goto free;
        case NS_SUCCESS:
                error = 0;
@@ -1235,7 +1235,12 @@ getanswer(const querybuf *answer, int an
                return sentinel.ai_next;
        }
 
-       h_errno = NO_RECOVERY;
+       /* We could have walked a CNAME chain, */
+       /* but the ultimate target may not have what we looked for */
+       if (ntohs(hp->ancount) > 0)
+               h_errno = NO_DATA;
+       else
+               h_errno = NO_RECOVERY;
        return NULL;
 }
 
@@ -1367,6 +1372,7 @@ _dns_getaddrinfo(void *rv, void   *cb_data
                __res_put_state(res);
                switch (h_errno) {
                case HOST_NOT_FOUND:
+               case NO_DATA:
                        return NS_NOTFOUND;
                case TRY_AGAIN:
                        return NS_TRYAGAIN;
        



Home | Main Index | Thread Index | Old Index