]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1798. [func] The server syntax has been extended to support a
authorMark Andrews <marka@isc.org>
Mon, 17 Jan 2005 00:46:05 +0000 (00:46 +0000)
committerMark Andrews <marka@isc.org>
Mon, 17 Jan 2005 00:46:05 +0000 (00:46 +0000)
                        range of servers.  [RT #11132]

12 files changed:
CHANGES
bin/named/named.conf.docbook
bin/named/server.c
doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/include/dns/peer.h
lib/dns/peer.c
lib/isc/include/isc/netaddr.h
lib/isc/netaddr.c
lib/isccfg/include/isccfg/grammar.h
lib/isccfg/namedconf.c
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index e419b2afc0285fc77c3d0ec346b627e4ea3b6098..17ec86e495d83bd229ce74a469d0b7c9775a63d5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,5 @@
-1798.  [placeholder]   rt11132
+1798.  [func]          The server syntax has been extended to support a
+                       range of servers.  [RT #11132]
 
 1797.  [func]          named-checkconf now check acls to verify that they
                        only refer to existing acls. [RT #13101]
index 58dd5889a18894cec3837bc138e1a3105333e097..f0547247001529ac256d4cfcf2a5fec163a3a21a 100644 (file)
@@ -15,7 +15,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: named.conf.docbook,v 1.7 2005/01/12 01:56:06 marka Exp $ -->
+<!-- $Id: named.conf.docbook,v 1.8 2005/01/17 00:46:01 marka Exp $ -->
 
 <refentry>
   <refentryinfo>
@@ -90,7 +90,7 @@ masters <replaceable>string</replaceable> <optional> port <replaceable>integer</
 <refsect1>
 <title>SERVER</title>
 <LITERALLAYOUT>
-server ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) {
+server ( <replaceable>ipv4_address<optional>/prefixlen</optional></replaceable> | <replaceable>ipv6_address<optional>/prefixlen</optional></replaceable> ) {
        bogus <replaceable>boolean</replaceable>;
        edns <replaceable>boolean</replaceable>;
        provide-ixfr <replaceable>boolean</replaceable>;
@@ -327,7 +327,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
                ...
        };
 
-       server ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) {
+       server ( <replaceable>ipv4_address<optional>/prefixlen</optional></replaceable> | <replaceable>ipv6_address<optional>/prefixlen</optional></replaceable> ) {
                ...
        };
 
index b2a6e4ad6b6482d56bfe93276e04b48051bc1885..62394c121b22dfb928194458492d72e8e0332e57 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.437 2005/01/14 03:28:07 marka Exp $ */
+/* $Id: server.c,v 1.438 2005/01/17 00:46:01 marka Exp $ */
 
 #include <config.h>
 
@@ -580,15 +580,14 @@ configure_order(dns_order_t *order, cfg_obj_t *ent) {
 
 static isc_result_t
 configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
-       isc_sockaddr_t *sa;
        isc_netaddr_t na;
        dns_peer_t *peer;
        cfg_obj_t *obj;
        char *str;
        isc_result_t result;
+       unsigned int prefixlen;
 
-       sa = cfg_obj_assockaddr(cfg_map_getname(cpeer));
-       isc_netaddr_fromsockaddr(&na, sa);
+       cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen);
 
        peer = NULL;
        result = dns_peer_new(mctx, &na, &peer);
@@ -643,7 +642,7 @@ configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
        }
 
        obj = NULL;
-       if (isc_sockaddr_pf(sa) == AF_INET)
+       if (na.family == AF_INET)
                (void)cfg_map_get(cpeer, "transfer-source", &obj);
        else
                (void)cfg_map_get(cpeer, "transfer-source-v6", &obj);
index 45194af34c859a333556376678103049ce8bf35e..c5825105177cacd58f53391880a98cc7a683105e 100644 (file)
@@ -2,7 +2,7 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
                "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.262 2005/01/11 03:46:09 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.263 2005/01/17 00:46:02 marka Exp $ -->
 
 <book>
 <title>BIND 9 Administrator Reference Manual</title>
@@ -4463,7 +4463,7 @@ entries are purged from acache only at the periodic cleaning time.
 <sect2 id="server_statement_grammar">
 <title><command>server</command> Statement Grammar</title>
 
-<programlisting>server <replaceable>ip_addr</replaceable> {
+<programlisting>server <replaceable>ip_addr<optional>/prefixlen</optional></replaceable> {
     <optional> bogus <replaceable>yes_or_no</replaceable> ; </optional>
     <optional> provide-ixfr <replaceable>yes_or_no</replaceable> ; </optional>
     <optional> request-ixfr <replaceable>yes_or_no</replaceable> ; </optional>
@@ -4482,7 +4482,10 @@ entries are purged from acache only at the periodic cleaning time.
 <title><command>server</command> Statement Definition and Usage</title>
 
 <para>The <command>server</command> statement defines characteristics
-to be associated with a remote name server.</para>
+to be associated with a remote name server.  If a prefix length is
+specified then a range of servers is covered.  Only the most specific
+server clause applies regardless of the order in
+<filename>named.conf</filename>.</para>
 
 <para>
 The <command>server</command> statement can occur at the top level of the
index aa2af9021e410279922b6bbe2e1af57c9cde9835..5f45ea4de48a43bff89498f280a8af158fc2cc67 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: check.c,v 1.54 2005/01/11 03:46:10 marka Exp $ */
+/* $Id: check.c,v 1.55 2005/01/17 00:46:02 marka Exp $ */
 
 #include <config.h>
 
@@ -1101,8 +1101,8 @@ check_servers(cfg_obj_t *servers, isc_log_t *logctx) {
        isc_result_t result = ISC_R_SUCCESS;
        cfg_listelt_t *e1, *e2;
        cfg_obj_t *v1, *v2;
-       isc_sockaddr_t *s1, *s2;
-       isc_netaddr_t na;
+       isc_netaddr_t n1, n2;
+       unsigned int p1, p2;
        cfg_obj_t *ts;
        char buf[128];
        const char *xfr;
@@ -1110,44 +1110,57 @@ check_servers(cfg_obj_t *servers, isc_log_t *logctx) {
 
        for (e1 = cfg_list_first(servers); e1 != NULL; e1 = cfg_list_next(e1)) {
                v1 = cfg_listelt_value(e1);
-               s1 = cfg_obj_assockaddr(cfg_map_getname(v1));
+               cfg_obj_asnetprefix(cfg_map_getname(v1), &n1, &p1);
+               /*
+                * Check that unused bits are zero.
+                */
+               result = isc_netaddr_prefixok(&n1, p1);
+               if (result != ISC_R_SUCCESS) {
+                       INSIST(result == ISC_R_FAILURE);
+                       isc_buffer_init(&target, buf, sizeof(buf) - 1);
+                       RUNTIME_CHECK(isc_netaddr_totext(&n1, &target)
+                                     == ISC_R_SUCCESS);
+                       buf[isc_buffer_usedlength(&target)] = '\0';
+                       cfg_obj_log(v1, logctx, ISC_LOG_ERROR,
+                                   "server '%s/%u': invalid prefix "
+                                   "(extra bits specified)", buf, p1);
+               }
                ts = NULL;
-               if (isc_sockaddr_pf(s1) == AF_INET)
+               if (n1.family == AF_INET)
                        xfr = "transfer-source-v6";
                else
                        xfr = "transfer-source";
                (void)cfg_map_get(v1, xfr, &ts);
                if (ts != NULL) {
-                       isc_netaddr_fromsockaddr(&na, s1);
                        isc_buffer_init(&target, buf, sizeof(buf) - 1);
-                       RUNTIME_CHECK(isc_netaddr_totext(&na, &target)
+                       RUNTIME_CHECK(isc_netaddr_totext(&n1, &target)
                                      == ISC_R_SUCCESS);
                        buf[isc_buffer_usedlength(&target)] = '\0';
                        cfg_obj_log(v1, logctx, ISC_LOG_ERROR,
-                                   "server '%s': %s not valid", buf, xfr);
+                                   "server '%s/%u': %s not valid",
+                                   buf, p1, xfr);
                        result = ISC_R_FAILURE;
                }
                e2 = e1;
                while ((e2 = cfg_list_next(e2)) != NULL) {
                        v2 = cfg_listelt_value(e2);
-                       s2 = cfg_obj_assockaddr(cfg_map_getname(v2));
-                       if (isc_sockaddr_eqaddr(s1, s2)) {
+                       cfg_obj_asnetprefix(cfg_map_getname(v2), &n2, &p2);
+                       if (p1 == p2 && isc_netaddr_equal(&n1, &n2)) {
                                const char *file = cfg_obj_file(v1);
                                unsigned int line = cfg_obj_line(v1);
 
                                if (file == NULL)
                                        file = "<unknown file>";
 
-                               isc_netaddr_fromsockaddr(&na, s2);
                                isc_buffer_init(&target, buf, sizeof(buf) - 1);
-                               RUNTIME_CHECK(isc_netaddr_totext(&na, &target)
+                               RUNTIME_CHECK(isc_netaddr_totext(&n2, &target)
                                              == ISC_R_SUCCESS);
                                buf[isc_buffer_usedlength(&target)] = '\0';
 
                                cfg_obj_log(v2, logctx, ISC_LOG_ERROR,
-                                           "server '%s': already exists "
+                                           "server '%s/%u': already exists "
                                            "previous definition: %s:%u",
-                                           buf, file, line);
+                                           buf, p2, file, line);
                                result = ISC_R_FAILURE;
                        }
                }
index 78be7a99d2fab0cce80d75e6dd956b6581a160e2..5dffcc4b30f6288b89c66e8d3b0ee937ed509e33 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: peer.h,v 1.20 2004/03/05 05:09:45 marka Exp $ */
+/* $Id: peer.h,v 1.21 2005/01/17 00:46:03 marka Exp $ */
 
 #ifndef DNS_PEER_H
 #define DNS_PEER_H 1
@@ -64,6 +64,7 @@ struct dns_peer {
        isc_mem_t              *mem;
 
        isc_netaddr_t           address;
+       unsigned int            prefixlen;
        isc_boolean_t           bogus;
        dns_transfer_format_t   transfer_format;
        isc_uint32_t            transfers;
@@ -115,6 +116,10 @@ dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval);
 isc_result_t
 dns_peer_new(isc_mem_t *mem, isc_netaddr_t *ipaddr, dns_peer_t **peer);
 
+isc_result_t
+dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *ipaddr,
+                  unsigned int prefixlen, dns_peer_t **peer);
+
 void
 dns_peer_attach(dns_peer_t *source, dns_peer_t **target);
 
index 39fdf2b3d27ba0d4fe4701e368954552719cba4f..a1204c609103c9b7197cc79cfe48dcf18b66dc5a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: peer.c,v 1.19 2004/03/05 05:09:22 marka Exp $ */
+/* $Id: peer.c,v 1.20 2005/01/17 00:46:03 marka Exp $ */
 
 #include <config.h>
 
@@ -130,7 +130,20 @@ dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) {
 
        dns_peer_attach(peer, &p);
 
-       ISC_LIST_APPEND(peers->elements, peer, next);
+       /*
+        * More specifics to front of list.
+        */
+       for (p = ISC_LIST_HEAD(peers->elements);
+            p != NULL;
+            p = ISC_LIST_NEXT(p, next))
+               if (p->prefixlen < peer->prefixlen)
+                       break;
+
+       if (p != NULL)
+               ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next);
+       else
+               ISC_LIST_APPEND(peers->elements, peer, next);
+               
 }
 
 isc_result_t
@@ -145,7 +158,8 @@ dns_peerlist_peerbyaddr(dns_peerlist_t *servers,
 
        server = ISC_LIST_HEAD(servers->elements);
        while (server != NULL) {
-               if (isc_netaddr_equal(addr, &server->address))
+               if (isc_netaddr_eqprefix(addr, &server->address,
+                                        server->prefixlen))
                        break;
 
                server = ISC_LIST_NEXT(server, next);
@@ -176,6 +190,27 @@ dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) {
 
 isc_result_t
 dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) {
+       unsigned int prefixlen = 0;
+
+       REQUIRE(peerptr != NULL);
+       switch(addr->family) {
+       case AF_INET:
+               prefixlen = 32;
+               break;
+       case AF_INET6:
+                prefixlen = 128;
+               break;
+       default:
+               INSIST(0);
+       }
+
+       return (dns_peer_newprefix(mem, addr, prefixlen, peerptr));
+}
+
+isc_result_t
+dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen,
+                  dns_peer_t **peerptr)
+{ 
        dns_peer_t *peer;
 
        REQUIRE(peerptr != NULL);
@@ -186,6 +221,7 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) {
 
        peer->magic = DNS_PEER_MAGIC;
        peer->address = *addr;
+       peer->prefixlen = prefixlen;
        peer->mem = mem;
        peer->bogus = ISC_FALSE;
        peer->transfer_format = dns_one_answer;
index 5c399bb02d203001c99b1132791112cc9ed13747..b92335505f73c4545445d1963591f03b92844ec4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: netaddr.h,v 1.25 2004/03/05 05:10:59 marka Exp $ */
+/* $Id: netaddr.h,v 1.26 2005/01/17 00:46:04 marka Exp $ */
 
 #ifndef ISC_NETADDR_H
 #define ISC_NETADDR_H 1
@@ -143,6 +143,19 @@ isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s);
  * Convert an IPv6 v4mapped address into an IPv4 address.
  */
 
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen);
+/*
+ * Test whether the netaddr 'na' and 'prefixlen' are consistant.
+ * e.g. prefixlen within range.
+ *      na does not have bits set which are not covered by the prefixlen.
+ *
+ * Returns:
+ *     ISC_R_SUCCESS
+ *     ISC_R_RANGE             prefixlen out of range
+ *     ISC_R_NOTIMPLENTED      unsupported family
+ *     ISC_R_FAILURE           extra bits.
+ */
 
 ISC_LANG_ENDDECLS
 
index 74cd159535d2dd3cdda6f646746ad23792242a60..40fece183d94024635ed80da573f290b17e69a74 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: netaddr.c,v 1.28 2004/05/15 03:37:33 jinmei Exp $ */
+/* $Id: netaddr.c,v 1.29 2005/01/17 00:46:04 marka Exp $ */
 
 #include <config.h>
 
@@ -190,6 +190,42 @@ isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) {
        }
 }
 
+
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) {
+       static const unsigned char zeros[16];
+       unsigned int nbits, nbytes, ipbytes, i;
+       const unsigned char *p;
+
+       switch (na->family) {
+       case AF_INET:
+               p = (const unsigned char *) &na->type.in;
+               ipbytes = 4;
+               if (prefixlen > 32)
+                       return (ISC_R_RANGE);
+               break;
+       case AF_INET6:
+               p = (const unsigned char *) &na->type.in6;
+               ipbytes = 16;
+               if (prefixlen > 128)
+                       return (ISC_R_RANGE);
+               break;
+       default:
+               ipbytes = 0;
+               return (ISC_R_NOTIMPLEMENTED);
+       }
+       nbytes = prefixlen / 8;
+       nbits = prefixlen % 8;
+       if (nbits != 0) {
+               if ((p[nbytes] & (0xff>>nbits)) != 0U)
+                       return (ISC_R_FAILURE);
+               nbytes++;
+       }
+       if (memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0)
+               return (ISC_R_FAILURE);
+       return (ISC_R_SUCCESS);
+}
+
 isc_result_t
 isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) {
        unsigned int nbits, nbytes, ipbytes, i;
index 230f346ac86039745e730ae39336b593c65d9ede..32bf863f400bd83f8255a623ed5aeb19cf4bd825 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: grammar.h,v 1.6 2004/11/30 01:08:52 marka Exp $ */
+/* $Id: grammar.h,v 1.7 2005/01/17 00:46:05 marka Exp $ */
 
 #ifndef ISCCFG_GRAMMAR_H
 #define ISCCFG_GRAMMAR_H 1
@@ -377,6 +377,10 @@ cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
 isc_result_t
 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
 
+isc_result_t
+cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
+ret);
+
 void
 cfg_print_map(cfg_printer_t *pctx, cfg_obj_t *obj);
 
index 4d7b88c82f502b0963ec40bb8dd60b65623bc676..52e86a2851bb9f6a6be49c2f45fd22679f9bb6a4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.45 2005/01/11 23:10:06 marka Exp $ */
+/* $Id: namedconf.c,v 1.46 2005/01/17 00:46:04 marka Exp $ */
 
 #include <config.h>
 
@@ -912,7 +912,7 @@ server_clausesets[] = {
        NULL
 };
 static cfg_type_t cfg_type_server = {
-       "server", cfg_parse_addressed_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
+       "server", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
        server_clausesets
 };
 
index 3fbda9bff4f114ec3d9a53b6bfdfc4103f8ec75e..4d22ace0a957dc2d7ecb3aacd8ce55ff2e50c3aa 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: parser.c,v 1.114 2004/07/23 04:15:26 marka Exp $ */
+/* $Id: parser.c,v 1.115 2005/01/17 00:46:04 marka Exp $ */
 
 #include <config.h>
 
@@ -1358,13 +1358,22 @@ cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
 
 /*
  * Parse a map identified by a network address.
- * Used for the "server" statement.
+ * Used to be used for the "server" statement.
  */
 isc_result_t
 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
        return (parse_any_named_map(pctx, &cfg_type_netaddr, type, ret));
 }
 
+/*
+ * Parse a map identified by a network prefix.
+ * Used for the "server" statement.
+ */
+isc_result_t
+cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+       return (parse_any_named_map(pctx, &cfg_type_netprefix, type, ret));
+}
+
 void
 cfg_print_mapbody(cfg_printer_t *pctx, cfg_obj_t *obj) {
        isc_result_t result = ISC_R_SUCCESS;
@@ -1483,6 +1492,9 @@ cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type) {
        } else if (type->parse == cfg_parse_addressed_map) {
                cfg_doc_obj(pctx, &cfg_type_netaddr);
                cfg_print_chars(pctx, " ", 1);
+       } else if (type->parse == cfg_parse_netprefix_map) {
+               cfg_doc_obj(pctx, &cfg_type_netprefix);
+               cfg_print_chars(pctx, " ", 1);
        }
        
        print_open(pctx);