]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1629. [func] dig now supports IPv6 scoped addresses with the
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Sat, 15 May 2004 03:37:34 +0000 (03:37 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Sat, 15 May 2004 03:37:34 +0000 (03:37 +0000)
extended format in the local-server part. [RT #8753]

CHANGES
lib/bind9/getaddresses.c
lib/isc/include/isc/result.h
lib/isc/netaddr.c
lib/isc/result.c
lib/isc/sockaddr.c
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index 6a99be22d80f43adb58667be88c34f557285432e..b29cc971a5f8475c1792135b4107a004606d6797 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -25,7 +25,8 @@
 
 1630.  [contrib]       queryperf: add support for IPv6 transport.
 
-1629.  [placeholder]   rt8753
+1629.  [func]          dig now supports IPv6 scoped addresses with the
+                       extended format in the local-server part. [RT #8753]
 
 1628.  [bug]           Typo in Compaq Trucluster support. [RT# 11264]
 
index b4c9158b44625a53a8c0be212dd13ed4f17d190b..d407f64066850239648139135c8b9313333b23cf 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: getaddresses.c,v 1.15 2004/03/05 05:09:04 marka Exp $ */
+/* $Id: getaddresses.c,v 1.16 2004/05/15 03:37:33 jinmei Exp $ */
 
 #include <config.h>
 #include <string.h>
@@ -23,6 +23,7 @@
 #include <isc/net.h>
 #include <isc/netaddr.h>
 #include <isc/netdb.h>
+#include <isc/netscope.h>
 #include <isc/result.h>
 #include <isc/sockaddr.h>
 #include <isc/util.h>
@@ -67,19 +68,67 @@ bind9_getaddresses(const char *hostname, in_port_t port,
        have_ipv4 = (isc_net_probeipv4() == ISC_R_SUCCESS);
        have_ipv6 = (isc_net_probeipv6() == ISC_R_SUCCESS);
 
-       if (inet_pton(AF_INET6, hostname, &in6) == 1) {
-               if (!have_ipv6)
-                       return (ISC_R_FAMILYNOSUPPORT);
-               isc_sockaddr_fromin6(&addrs[0], &in6, port);
-               *addrcount = 1;
-               return (ISC_R_SUCCESS);
-       } else if (inet_pton(AF_INET, hostname, &in4) == 1) {
+       /*
+        * Try IPv4, then IPv6.  In order to handle the extended format
+        * for IPv6 scoped addresses (address%scope_ID), we'll use a local
+        * working buffer of 128 bytes.  The length is an ad-hoc value, but
+        * should be enough for this purpose; the buffer can contain a string
+        * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
+        * addresses (up to 46 bytes), the delimiter character and the
+        * terminating NULL character.
+        */
+       if (inet_pton(AF_INET, hostname, &in4) == 1) {
                if (have_ipv4)
                        isc_sockaddr_fromin(&addrs[0], &in4, port);
                else
                        isc_sockaddr_v6fromin(&addrs[0], &in4, port);
                *addrcount = 1;
                return (ISC_R_SUCCESS);
+       } else if (strlen(hostname) <= 127) {
+               char tmpbuf[128], *d;
+               isc_uint32_t zone = 0;
+
+               strcpy(tmpbuf, hostname);
+               d = strchr(tmpbuf, '%');
+               if (d != NULL)
+                       *d = '\0';
+
+               if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
+                       isc_netaddr_t na;
+
+                       if (!have_ipv6)
+                               return (ISC_R_FAMILYNOSUPPORT);
+
+                       if (d != NULL) {
+#ifdef ISC_PLATFORM_HAVESCOPEID
+                               isc_result_t result;
+
+                               result = isc_netscope_pton(AF_INET6, d + 1,
+                                                          &in6, &zone);
+                                   
+                               if (result != ISC_R_SUCCESS)
+                                       return (result);
+#else
+                               /*
+                                * The extended format is specified while the
+                                * system does not provide the ability to use
+                                * it.  Throw an explicit error instead of
+                                * ignoring the specified value.
+                                */
+                               return (ISC_R_BADADDRESSFORM);
+#endif
+                       }
+
+                       isc_netaddr_fromin6(&na, &in6);
+                       isc_netaddr_setzone(&na, zone);
+                       isc_sockaddr_fromnetaddr(&addrs[0],
+                                                (const isc_netaddr_t *)&na,
+                                                port);
+
+                       *addrcount = 1;
+                       return (ISC_R_SUCCESS);
+                       
+               }
        }
 #ifdef USE_GETADDRINFO
        memset(&hints, 0, sizeof(hints));
index d1ae566f0abc2063190bbf44976cd9a8d6a5d28e..d3bfb49a74a670efad104f478d20758dcbd8ad03 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: result.h,v 1.62 2004/03/05 05:11:00 marka Exp $ */
+/* $Id: result.h,v 1.63 2004/05/15 03:37:34 jinmei Exp $ */
 
 #ifndef ISC_RESULT_H
 #define ISC_RESULT_H 1
 #define ISC_R_BADNUMBER                        56      /* not a valid number */
 #define ISC_R_DISABLED                 57      /* disabled */
 #define ISC_R_MAXSIZE                  58      /* max size */
+#define ISC_R_BADADDRESSFORM           59      /* invalid address format */
 
 /*
  * Not a result code: the number of results.
  */
-#define ISC_R_NRESULTS                         59
+#define ISC_R_NRESULTS                         60
 
 ISC_LANG_BEGINDECLS
 
index a2081afacb34c929295a6a189c115e781584cb8c..74cd159535d2dd3cdda6f646746ad23792242a60 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: netaddr.c,v 1.27 2004/03/05 05:10:47 marka Exp $ */
+/* $Id: netaddr.c,v 1.28 2004/05/15 03:37:33 jinmei Exp $ */
 
 #include <config.h>
 
@@ -47,7 +47,8 @@ isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
                break;
        case AF_INET6:
                if (memcmp(&a->type.in6, &b->type.in6,
-                          sizeof(a->type.in6)) != 0)
+                          sizeof(a->type.in6)) != 0 ||
+                   a->zone != b->zone)
                        return (ISC_FALSE);
                break;
        default:
index 68acf9f2d2983a08a89853ee3a5bf62c6068516e..7eb3a4332c9bc08578b8083dadfa159ac738c08a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: result.c,v 1.62 2004/03/05 05:10:48 marka Exp $ */
+/* $Id: result.c,v 1.63 2004/05/15 03:37:33 jinmei Exp $ */
 
 #include <config.h>
 
@@ -96,7 +96,8 @@ static const char *text[ISC_R_NRESULTS] = {
        "soft quota reached",                   /* 55 */
        "not a valid number",                   /* 56 */
        "disabled",                             /* 57 */
-       "max size"                              /* 58 */
+       "max size",                             /* 58 */
+       "invalid address format"                /* 59 */
 };
 
 #define ISC_RESULT_RESULTSET                   2
index 27b9309f95607e8e428177f9fd8c63e25bc33964..edaaf5b06df820c9c59d6583238809fd1b6ef829 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sockaddr.c,v 1.59 2004/03/05 05:10:49 marka Exp $ */
+/* $Id: sockaddr.c,v 1.60 2004/05/15 03:37:33 jinmei Exp $ */
 
 #include <config.h>
 
@@ -57,6 +57,10 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
                if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
                           sizeof(a->type.sin6.sin6_addr)) != 0)
                        return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+               if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+                       return (ISC_FALSE);
+#endif
                if (a->type.sin6.sin6_port != b->type.sin6.sin6_port)
                        return (ISC_FALSE);
                break;
@@ -86,6 +90,10 @@ isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
                if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
                           sizeof(a->type.sin6.sin6_addr)) != 0)
                        return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+               if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+                       return (ISC_FALSE);
+#endif
                break;
        default:
                if (memcmp(&a->type, &b->type, a->length) != 0)
index 8a4affd493b56de1e9607c0ac8401a52fd3a6e2e..14223142ba4b837d6dab07cb287e13fce6b1e774 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: parser.c,v 1.112 2004/03/18 02:58:07 marka Exp $ */
+/* $Id: parser.c,v 1.113 2004/05/15 03:37:34 jinmei Exp $ */
 
 #include <config.h>
 
@@ -1671,7 +1671,7 @@ token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {
                }
                if ((flags & CFG_ADDR_V6OK) != 0 &&
                    strlen(s) <= 127U) {
-                       char buf[128];
+                       char buf[128]; /* see lib/bind9/getaddresses.c */
                        char *d; /* zone delimiter */
                        isc_uint32_t zone = 0; /* scope zone ID */
 
@@ -1682,6 +1682,7 @@ token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {
 
                        if (inet_pton(AF_INET6, buf, &in6a) == 1) {
                                if (d != NULL) {
+#ifdef ISC_PLATFORM_HAVESCOPEID
                                        isc_result_t result;
 
                                        result = isc_netscope_pton(AF_INET6,
@@ -1690,6 +1691,9 @@ token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {
                                                                   &zone);
                                        if (result != ISC_R_SUCCESS)
                                                return (result);
+#else
+                               return (ISC_R_BADADDRESSFORM);
+#endif
                                }
 
                                isc_netaddr_fromin6(na, &in6a);