1798. [func] The server syntax has been extended to support a

range of servers.  [RT #11132]
This commit is contained in:
Mark Andrews 2005-01-17 00:46:05 +00:00
parent 5752b9e296
commit 4844ed026a
12 changed files with 159 additions and 37 deletions

View file

@ -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]

View 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> ) {
...
};

View 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);

View 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

View 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;
}
}

View 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);

View 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;

View 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

View 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;

View 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);

View 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
};

View 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);