update to 9.7.1-P2
[tridge/bind9.git] / lib / lwres / getipnode.c
index a6c50c28b80320c33b81d6d9044b31450ebcf430..3bd82177b1e64987973837b3d05a3fb199d5dc38 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
  * Copyright (C) 1999-2003  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */
+/* $Id: getipnode.c,v 1.47 2009/09/01 23:47:45 tbox Exp $ */
 
 /*! \file */
 
@@ -23,7 +23,7 @@
  *    These functions perform thread safe, protocol independent
  *    nodename-to-address and address-to-nodename translation as defined in
  *    RFC2553.  This use a struct hostent which is defined in namedb.h:
- * 
+ *
  * \code
  * struct  hostent {
  *         char    *h_name;        // official name of host
  * };
  * #define h_addr  h_addr_list[0]  // address, for backward compatibility
  * \endcode
- * 
+ *
  *    The members of this structure are:
- * 
+ *
  * \li   h_name:
  *           The official (canonical) name of the host.
- * 
+ *
  * \li   h_aliases:
  *           A NULL-terminated array of alternate names (nicknames) for the
  *           host.
- * 
+ *
  * \li   h_addrtype:
  *           The type of address being returned - usually PF_INET or
  *           PF_INET6.
- * 
+ *
  * \li   h_length:
  *           The length of the address in bytes.
- * 
+ *
  * \li   h_addr_list:
  *           A NULL terminated array of network addresses for the host. Host
  *           addresses are returned in network byte order.
- * 
+ *
  *    lwres_getipnodebyname() looks up addresses of protocol family af for
  *    the hostname name. The flags parameter contains ORed flag bits to
  *    specify the types of addresses that are searched for, and the types of
  *    addresses that are returned. The flag bits are:
- * 
+ *
  * \li   #AI_V4MAPPED:
  *           This is used with an af of #AF_INET6, and causes IPv4 addresses
  *           to be returned as IPv4-mapped IPv6 addresses.
- * 
+ *
  * \li   #AI_ALL:
  *           This is used with an af of #AF_INET6, and causes all known
  *           addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is
  *           also set, the IPv4 addresses are return as mapped IPv6
  *           addresses.
- * 
+ *
  * \li   #AI_ADDRCONFIG:
  *           Only return an IPv6 or IPv4 address if here is an active
  *           network interface of that type. This is not currently
  *           implemented in the BIND 9 lightweight resolver, and the flag is
  *           ignored.
- * 
+ *
  * \li   #AI_DEFAULT:
  *           This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits.
- * 
+ *
  *    lwres_getipnodebyaddr() performs a reverse lookup of address src which
  *    is len bytes long. af denotes the protocol family, typically PF_INET
  *    or PF_INET6.
- * 
+ *
  *    lwres_freehostent() releases all the memory associated with the struct
  *    hostent pointer. Any memory allocated for the h_name, h_addr_list
  *    and h_aliases is freed, as is the memory for the hostent structure
  *    itself.
- * 
+ *
  * \section getipnode_return Return Values
- * 
+ *
  *    If an error occurs, lwres_getipnodebyname() and
  *    lwres_getipnodebyaddr() set *error_num to an appropriate error code
  *    and the function returns a NULL pointer. The error codes and their
  *    meanings are defined in \link netdb.h <lwres/netdb.h>\endlink:
- * 
+ *
  * \li   #HOST_NOT_FOUND:
  *           No such host is known.
- * 
+ *
  * \li   #NO_ADDRESS:
  *           The server recognised the request and the name but no address
  *           is available. Another type of request to the name server for
  *           the domain might return an answer.
- * 
+ *
  * \li   #TRY_AGAIN:
  *           A temporary and possibly transient error occurred, such as a
  *           failure of a server to respond. The request may succeed if
  *           retried.
- * 
+ *
  * \li   #NO_RECOVERY:
  *           An unexpected failure occurred, and retrying the request is
  *           pointless.
- * 
+ *
  *    lwres_hstrerror() translates these error codes to suitable error
  *    messages.
- * 
+ *
  * \section getipnode_see See Also
- * 
- * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553  
+ *
+ * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
  */
 
 #include <config.h>
@@ -146,21 +146,21 @@ LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 
 #ifndef IN6_IS_ADDR_V4COMPAT
 static const unsigned char in6addr_compat[12] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 #define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
-                                 ((x)->s6_addr[12] != 0 || \
-                                  (x)->s6_addr[13] != 0 || \
-                                  (x)->s6_addr[14] != 0 || \
-                                   ((x)->s6_addr[15] != 0 && \
-                                    (x)->s6_addr[15] != 1)))
+                                ((x)->s6_addr[12] != 0 || \
+                                 (x)->s6_addr[13] != 0 || \
+                                 (x)->s6_addr[14] != 0 || \
+                                  ((x)->s6_addr[15] != 0 && \
+                                   (x)->s6_addr[15] != 1)))
 #endif
 #ifndef IN6_IS_ADDR_V4MAPPED
 #define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
 #endif
 
 static const unsigned char in6addr_mapped[12] = {
-        0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0xff, 0xff
+       0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0xff, 0xff
 };
 
 /***
@@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
        struct in6_addr in6;
        struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
        int v4 = 0, v6 = 0;
-       int tmp_err;
+       int tmp_err = 0;
        lwres_context_t *lwrctx = NULL;
        lwres_gabnresponse_t *by = NULL;
        int n;
@@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
        (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
        tmp_err = NO_RECOVERY;
        if (have_v6 && af == AF_INET6) {
-
                n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
                if (n == 0) {
                        he1 = hostfromname(by, AF_INET6);
@@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
                                goto cleanup;
                        }
                } else {
-                       tmp_err = HOST_NOT_FOUND;
+                       if (n == LWRES_R_NOTFOUND)
+                               tmp_err = HOST_NOT_FOUND;
+                       else {
+                               *error_num = NO_RECOVERY;
+                               goto cleanup;
+                       }
                }
        }
 
@@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
        if (n != 0) {
                lwres_conf_clear(lwrctx);
                lwres_context_destroy(&lwrctx);
-               *error_num = HOST_NOT_FOUND;
+
+               if (n == LWRES_R_NOTFOUND)
+                      *error_num = HOST_NOT_FOUND;
+               else
+                      *error_num = NO_RECOVERY;
+
                return (NULL);
        }
+
        he1 = hostfromaddr(by, AF_INET6, src);
        lwres_gnbaresponse_free(lwrctx, &by);
        if (he1 == NULL)
@@ -492,7 +502,7 @@ lwres_freehostent(struct hostent *he) {
  */
 
 #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
-    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) 
+    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
 
 #ifdef __hpux
 #define lifc_len iflc_len
@@ -504,7 +514,7 @@ lwres_freehostent(struct hostent *he) {
 #define ISC_HAVE_LIFC_FLAGS 1
 #define LIFCONF lifconf
 #endif
+
 #ifdef __hpux
 #define lifr_addr iflr_addr
 #define lifr_name iflr_name
@@ -557,7 +567,7 @@ scan_interfaces6(int *have_v4, int *have_v6) {
                        /*
                         * Some OS's just return what will fit rather
                         * than set EINVAL if the buffer is too small
-                        * to fit all the interfaces in.  If 
+                        * to fit all the interfaces in.  If
                         * lifc.lifc_len is too near to the end of the
                         * buffer we will grow it just in case and
                         * retry.
@@ -619,13 +629,13 @@ scan_interfaces6(int *have_v4, int *have_v6) {
                                if ((lifreq.lifr_flags & IFF_UP) == 0)
                                        break;
                                *have_v4 = 1;
-                       } 
+                       }
                        break;
                case AF_INET6:
                        if (*have_v6 == 0) {
                                memcpy(&in6,
                                       &((struct sockaddr_in6 *)
-                                      &lifreq.lifr_addr)->sin6_addr, 
+                                      &lifreq.lifr_addr)->sin6_addr,
                                       sizeof(in6));
                                if (memcmp(&in6, &in6addr_any,
                                           sizeof(in6)) == 0)
@@ -675,7 +685,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
        InitSockets();
 #endif
 #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
-    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) 
+    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
        /*
         * Try to scan the interfaces using IPv6 ioctls().
         */
@@ -721,7 +731,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
                        /*
                         * Some OS's just return what will fit rather
                         * than set EINVAL if the buffer is too small
-                        * to fit all the interfaces in.  If 
+                        * to fit all the interfaces in.  If
                         * ifc.ifc_len is too near to the end of the
                         * buffer we will grow it just in case and
                         * retry.
@@ -786,7 +796,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
                                if ((u.ifreq.ifr_flags & IFF_UP) == 0)
                                        break;
                                *have_v4 = 1;
-                       } 
+                       }
                        break;
                case AF_INET6:
                        if (*have_v6 == 0) {