+2039. [func] Redirect on NXDOMAIN support. [RT #23146]
+
2038. [bug] Install <dns/rpz.h>. [RT #23342]
2037. [doc] Update COPYRIGHT to contain all the individual
/*
- * Generated by bindkeys.pl 1.7 2011/01/04 23:47:13 tbox Exp
- * From bind.keys 1.7 2011/01/03 23:45:07 each Exp
+ * Generated by bindkeys.pl 1.7 2011-01-04 23:47:13 tbox Exp
+ * From bind.keys 1.7 2011-01-03 23:45:07 each Exp
*/
#define TRUSTED_KEYS "\
# The bind.keys file is used to override the built-in DNSSEC trust anchors\n\
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.c,v 1.115 2011/02/03 12:18:10 tbox Exp $ */
+/* $Id: config.c,v 1.116 2011/02/23 03:08:08 marka Exp $ */
/*! \file */
ztype = dns_zone_stub;
else if (strcasecmp(str, "static-stub") == 0)
ztype = dns_zone_staticstub;
+ else if (strcasecmp(str, "redirect") == 0)
+ ztype = dns_zone_redirect;
else
INSIST(0);
return (ztype);
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.conf.docbook,v 1.50 2011/02/03 05:41:52 marka Exp $ -->
+<!-- $Id: named.conf.docbook,v 1.51 2011/02/23 03:08:08 marka Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
<title>ZONE</title>
<literallayout>
zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable> {
- type ( master | slave | stub | hint |
+ type ( master | slave | stub | hint | redirect |
forward | delegation-only );
file <replaceable>quoted_string</replaceable>;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.355 2011/02/18 15:18:30 smann Exp $ */
+/* $Id: query.c,v 1.356 2011/02/23 03:08:08 marka Exp $ */
/*! \file */
return (ISC_FALSE);
}
+/*
+ * Look for the name and type in the redirection zone. If found update
+ * the arguments as appropriate. Return ISC_TRUE if a update was
+ * performed.
+ *
+ * Only perform the update if the client is in the allow query acl and
+ * returning the update would not cause a DNSSEC validation failure.
+ */
+static isc_boolean_t
+redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
+ dns_dbnode_t **nodep, dns_db_t **dbp, dns_rdatatype_t qtype)
+{
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ dns_rdataset_t trdataset;
+ isc_result_t result;
+ dns_rdatatype_t type;
+
+ CTRACE("redirect");
+
+ if (client->view->redirect == NULL)
+ return (ISC_FALSE);
+
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ dns_rdataset_init(&trdataset);
+
+ if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
+ return (ISC_FALSE);
+
+ if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
+ if (rdataset->trust == dns_trust_secure)
+ return (ISC_FALSE);
+ if (rdataset->trust == dns_trust_ultimate &&
+ (rdataset->type == dns_rdatatype_nsec ||
+ rdataset->type == dns_rdatatype_nsec3))
+ return (ISC_FALSE);
+ if (rdataset->type == 0) {
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_ncache_current(rdataset, found, &trdataset);
+ type = trdataset.type;
+ dns_rdataset_disassociate(&trdataset);
+ if (type == dns_rdatatype_nsec ||
+ type == dns_rdatatype_nsec3 ||
+ type == dns_rdatatype_rrsig)
+ return (ISC_FALSE);
+ }
+ }
+ }
+
+ result = ns_client_checkaclsilent(client, NULL,
+ dns_zone_getqueryacl(client->view->redirect),
+ ISC_TRUE);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+
+ result = dns_zone_getdb(client->view->redirect, &db);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+
+ /*
+ * Lookup the requested data in the redirect zone.
+ */
+ result = dns_db_find(db, client->query.qname, NULL, qtype, 0,
+ client->now, &node, found, &trdataset, NULL);
+ if (result != ISC_R_SUCCESS) {
+ if (dns_rdataset_isassociated(&trdataset))
+ dns_rdataset_disassociate(&trdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+ return (ISC_FALSE);
+ }
+ CTRACE("redirect: found data: done");
+
+ dns_name_copy(found, name, NULL);
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ if (dns_rdataset_isassociated(&trdataset)) {
+ dns_rdataset_clone(&trdataset, rdataset);
+ dns_rdataset_disassociate(&trdataset);
+ }
+ if (*nodep != NULL)
+ dns_db_detachnode(*dbp, nodep);
+ dns_db_detach(dbp);
+ dns_db_attachnode(db, node, nodep);
+ dns_db_attach(db, dbp);
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+
+ client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
+ NS_QUERYATTR_NOADDITIONAL);
+
+ return (ISC_TRUE);
+}
+
/*
* Do the bulk of query processing for the current query of 'client'.
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
case DNS_R_NXDOMAIN:
INSIST(is_zone);
+ if (!empty_wild &&
+ redirect(client, fname, rdataset, &node, &db, type)) {
+ result = ISC_R_SUCCESS;
+ break;
+ }
if (dns_rdataset_isassociated(rdataset)) {
/*
* If we've got a NSEC record, we need to save the
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
+ if (redirect(client, fname, rdataset, &node, &db, type)) {
+ result = ISC_R_SUCCESS;
+ break;
+ }
case DNS_R_NCACHENXRRSET:
ncache_nxrrset:
INSIST(!is_zone);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.603 2011/02/16 19:48:12 each Exp $ */
+/* $Id: server.c,v 1.604 2011/02/23 03:08:09 marka Exp $ */
/*! \file */
goto cleanup;
}
+ /*
+ * Redirect zones only require minimal configuration.
+ */
+ if (strcasecmp(ztypestr, "redirect") == 0) {
+ if (view->redirect != NULL) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "redirect zone already exists");
+ result = ISC_R_EXISTS;
+ goto cleanup;
+ }
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL && pview->redirect != NULL) {
+ dns_zone_attach(pview->redirect, &zone);
+ dns_zone_setview(zone, view);
+ } else {
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, origin));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
+ zone));
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ }
+ CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf,
+ zone));
+ dns_zone_attach(zone, &view->redirect);
+ goto cleanup;
+ }
+
/*
* Check for duplicates in the new zone table.
*/
* options (e.g., an existing master zone cannot
* be reused if the options specify a slave zone)
*/
- result = dns_viewlist_find(&ns_g_server->viewlist,
- view->name, view->rdclass,
- &pview);
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
goto cleanup;
if (pview != NULL)
case dns_zone_stub:
type = "stub";
break;
+ case dns_zone_redirect:
+ type = "redirect";
+ break;
default:
type = "other";
break;
CHECK(dns_view_load(view, stop));
if (view->managed_keys != NULL)
CHECK(dns_zone_load(view->managed_keys));
+ if (view->redirect != NULL)
+ CHECK(dns_zone_load(view->redirect));
}
/*
/* Load managed-keys data */
if (view->managed_keys != NULL)
CHECK(dns_zone_loadnew(view->managed_keys));
+ if (view->redirect != NULL)
+ CHECK(dns_zone_loadnew(view->redirect));
}
/*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.170 2011/01/06 23:47:00 tbox Exp $ */
+/* $Id: zoneconf.c,v 1.171 2011/02/23 03:08:09 marka Exp $ */
/*% */
* to primary masters (type "master") and slaves
* acting as masters (type "slave"), but not to stubs.
*/
- if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) {
+ if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
+ ztype != dns_zone_redirect) {
obj = NULL;
result = ns_config_get(maps, "notify", &obj);
INSIST(result == ISC_R_SUCCESS);
dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60);
obj = NULL;
- result = ns_config_get(maps, "max-journal-size", &obj);
+ result = ns_config_get(maps, "max-journal-size", &obj);
INSIST(result == ISC_R_SUCCESS);
dns_zone_setjournalsize(zone, -1);
if (cfg_obj_isstring(obj)) {
INSIST(result == ISC_R_SUCCESS);
dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
cfg_obj_asboolean(obj));
+ } else if (ztype == dns_zone_redirect) {
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+
+ obj = NULL;
+ result = ns_config_get(maps, "max-journal-size", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_zone_setjournalsize(zone, -1);
+ if (cfg_obj_isstring(obj)) {
+ const char *str = cfg_obj_asstring(obj);
+ INSIST(strcasecmp(str, "unlimited") == 0);
+ journal_size = ISC_UINT32_MAX / 2;
+ } else {
+ isc_resourcevalue_t value;
+ value = cfg_obj_asuint64(obj);
+ if (value > ISC_UINT32_MAX / 2) {
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_ERROR,
+ "'max-journal-size "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too large",
+ value);
+ RETERR(ISC_R_RANGE);
+ }
+ journal_size = (isc_uint32_t)value;
+ }
+ dns_zone_setjournalsize(zone, journal_size);
}
/*
switch (ztype) {
case dns_zone_slave:
case dns_zone_stub:
+ case dns_zone_redirect:
count = 0;
obj = NULL;
result = cfg_map_get(zoptions, "masters", &obj);
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: conf.sh.in,v 1.60 2011/02/22 04:14:29 marka Exp $
+# $Id: conf.sh.in,v 1.61 2011/02/23 03:08:09 marka Exp $
#
# Common configuration data for system tests, to be sourced into
SUBDIRS="acl allow_query addzone autosign cacheclean checkconf checknames
database dlv @DLZ_SYSTEM_TEST@ dlzexternal dns64 dnssec forward
glue gost ixfr limits lwresd masterfile masterformat metadata
- notify nsupdate pending pkcs11 resolver rpz rrsetorder
+ notify nsupdate pending pkcs11 redirect resolver rpz rrsetorder
sortlist smartsign staticstub stub tkey tsig tsiggss
unknown upforwd views xfer xferquota zonechecks"
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: clean.sh,v 1.2 2011/02/23 03:08:09 marka Exp $
+
+
+rm -f ns1/K*
+rm -f ns1/signed.db*
+rm -f ns1/nsec3.db*
+rm -f ns1/dsset-signed.
+rm -f ns1/dsset-nsec3.
+rm -f */named.memstats
+rm -f */named.run
+rm -f dig.out.* random.data
--- /dev/null
+zone "." {
+ type hint;
+ file "hint.db";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+ allow-query { 10.0.1.0; };
+ forwarders { 1.2.3.4; };
+};
--- /dev/null
+zone "." {
+ type hint;
+ file "hint.db";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+ allow-query { 10.0.1.0; };
+ also-notify { 1.2.3.4; };
+};
--- /dev/null
+zone "." {
+ type hint;
+ file "hint.db";
+};
+
+zone "x" {
+ type redirect;
+ file "redirect.db";
+ allow-query { 10.0.1.0; };
+};
--- /dev/null
+zone "." {
+ type hint;
+ file "hint.db";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+};
--- /dev/null
+zone "." {
+ type master;
+ file "master.db";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+};
--- /dev/null
+zone "." {
+ type slave;
+ file "slave.db";
+ masters { 1.2.3.4; };
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+};
--- /dev/null
+zone "." {
+ type hint;
+ file "hint.db";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+ allow-query { 10.0.1.0; };
+};
--- /dev/null
+; Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: example.db,v 1.2 2011/02/23 03:08:10 marka Exp $
+
+$TTL 3600
+@ SOA ns1 marka.isc.org. 0 0 0 0 1200
+@ NS ns1
+ns1 A 10.53.0.1
+excluded-good-a AAAA 2001:eeee::1
+ A 1.2.3.4
+excluded-bad-a AAAA 2001:eeee::2
+ A 10.0.0.1
+excluded-only AAAA 2001:eeee::3
+partially-excluded-good-a AAAA 2001:eeee::1
+ AAAA 2001::1
+ A 1.2.3.4
+partially-excluded-bad-a AAAA 2001:eeee::2
+ AAAA 2001::2
+ A 10.0.0.1
+partially-excluded-only AAAA 2001:eeee::3
+ AAAA 2001::3
+a-only A 1.2.3.5
+a-and-aaaa AAAA 2001::1
+ A 1.2.3.6
+aaaa-only AAAA 2001::2
+a-not-mapped A 10.0.0.2
+mx-only MX 10 ns.example.
+cname-excluded-good-a CNAME excluded-good-a
+cname-excluded-bad-a CNAME excluded-bad-a
+cname-excluded-only CNAME excluded-only
+cname-partial-excluded-good-a CNAME partial-excluded-good-a
+cname-partial-excluded-bad-a CNAME partial-excluded-bad-a
+cname-partial-excluded-only CNAME partial-excluded-only
+cname-a-only CNAME a-only
+cname-a-and-aaaa CNAME a-and-aaaa
+cname-aaaa-only CNAME aaaa-only
+cname-a-not-mapped CNAME a-not-mapped
+cname-mx-only CNAME mx-only
+cname-non-existent CNAME non-existent
+ttl-less-than-600 500 A 5.6.7.8
+ttl-more-than-600 700 A 5.6.7.8
+ttl-less-than-minimum 1100 A 5.6.7.8
+ttl-more-than-minimum 1300 A 5.6.7.8
--- /dev/null
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: named.conf,v 1.2 2011/02/23 03:08:10 marka Exp $ */
+
+// NS1
+
+controls { /* empty */ };
+
+acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+options {
+ query-source address 10.53.0.1;
+ notify-source 10.53.0.1;
+ transfer-source 10.53.0.1;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ allow-recursion { 10.53.0.1; };
+ notify yes;
+ dnssec-enable yes;
+ dnssec-validation yes;
+};
+
+zone "." {
+ type master;
+ file "root.db";
+};
+
+zone "example" {
+ type master;
+ file "example.db";
+};
+
+zone "signed" {
+ type master;
+ file "signed.db.signed";
+};
+
+zone "nsec3" {
+ type master;
+ file "nsec3.db.signed";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+ allow-query { !10.53.0.2; !10.53.0.4; any; };
+};
+
+// include "trusted.conf";
--- /dev/null
+; Copyright
+;
+
+$TTL 300
+@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0
+@ IN NS ns.example.net
+;
+; NS records do not need address records in this zone as it is not in the
+; normal namespace.
+;
+*. IN A 100.100.100.2
+*. IN AAAA 2001:ffff:ffff::100.100.100.2
--- /dev/null
+; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: root.db,v 1.2 2011/02/23 03:08:10 marka Exp $
+
+$TTL 3600
+@ SOA a.root-servers.nil. marka.isc.org. 0 0 0 0 0
+@ NS a.root-servers.nil.
+a.root-servers.nil. A 10.53.0.1
+example NS ns1.example.
+ns1.example. A 10.53.0.1
+signed NS ns1.example.
+ns1.signed. A 10.53.0.1
--- /dev/null
+#!/bin/sh -e
+#
+# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: sign.sh,v 1.2 2011/02/23 03:08:10 marka Exp $
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+RANDFILE=../random.data
+
+zone=signed
+infile=example.db
+zonefile=signed.db
+
+key1=`$KEYGEN -q -r $RANDFILE $zone`
+key2=`$KEYGEN -q -r $RANDFILE -fk $zone`
+
+cat $infile $key1.key $key2.key > $zonefile
+
+$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null
+
+zone=nsec3
+infile=example.db
+zonefile=nsec3.db
+
+key1=`$KEYGEN -q -r $RANDFILE -3 $zone`
+key2=`$KEYGEN -q -r $RANDFILE -3 -fk $zone`
+
+cat $infile $key1.key $key2.key > $zonefile
+
+$SIGNER -P -3 - -g -r $RANDFILE -o $zone $zonefile > /dev/null
--- /dev/null
+/*
+ * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: named.conf,v 1.2 2011/02/23 03:08:10 marka Exp $ */
+
+// NS2
+
+controls { /* empty */ };
+
+acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+options {
+ query-source address 10.53.0.2;
+ notify-source 10.53.0.2;
+ transfer-source 10.53.0.2;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion yes;
+ notify yes;
+ dnssec-enable yes;
+ dnssec-validation yes;
+
+};
+
+zone "." {
+ type hint;
+ file "../../common/root.hint";
+};
+
+zone "." {
+ type redirect;
+ file "redirect.db";
+ allow-query { !10.53.0.4; any; };
+};
--- /dev/null
+; Copyright
+;
+
+$TTL 300
+@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0
+@ IN NS ns.example.net
+;
+; NS records do not need address records in this zone as it is not in the
+; normal namespace.
+;
+*. IN A 100.100.100.1
+*. IN AAAA 2001:ffff:ffff::100.100.100.1
--- /dev/null
+#!/bin/sh -e
+#
+# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: setup.sh,v 1.2 2011/02/23 03:08:09 marka Exp $
+
+sh clean.sh
+
+../../../tools/genrandom 400 random.data
+
+cd ns1 && sh sign.sh
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: tests.sh,v 1.2 2011/02/23 03:08:09 marka Exp $
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+status=0
+n=1
+
+rm -f dig.out.*
+
+DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p 5300"
+
+for conf in conf/good*.conf
+do
+ echo "I:checking that $conf is accepted ($n)"
+ ret=0
+ $CHECKCONF "$conf" || ret=1
+ n=`expr $n + 1`
+ if [ $ret != 0 ]; then echo "I:failed"; fi
+ status=`expr $status + $ret`
+done
+
+for conf in conf/bad*.conf
+do
+ echo "I:checking that $conf is rejected ($n)"
+ ret=0
+ $CHECKCONF "$conf" >/dev/null && ret=1
+ n=`expr $n + 1`
+ if [ $ret != 0 ]; then echo "I:failed"; fi
+ status=`expr $status + $ret`
+done
+
+echo "I:checking A redirect works for nonexist ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect works for nonexist ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect works for nonexist ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect doesn't work for acl miss ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 a > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect doesn't work for acl miss ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 aaaa > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect doesn't work for acl miss ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 any > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect works for signed nonexist, DO=0 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect works for signed nonexist, DO=0 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect works for signed nonexist, DO=0 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1
+grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect fails for signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect fails for signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect fails for signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect works for nonexist authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect works for nonexist authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect works for nonexist authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect doesn't work for acl miss authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 a > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect doesn't work for acl miss authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 aaaa > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect doesn't work for acl miss authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 any > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect works for signed nonexist, DO=0 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect works for signed nonexist, DO=0 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect works for signed nonexist, DO=0 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1
+grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect fails for signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect fails for signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect fails for signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)"
+ret=0
+$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1
+grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1
+grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:exit status: $status"
+exit $status
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.480 2011/02/03 07:35:55 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.481 2011/02/23 03:08:10 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
<optional> delegation-only <replaceable>yes_or_no</replaceable> ; </optional>
};
+zone <replaceable>"."</replaceable> <optional><replaceable>class</replaceable></optional> {
+ type redirect;
+ file <replaceable>string</replaceable> ;
+ <optional> masterfile-format (<constant>text</constant>|<constant>raw</constant>) ; </optional>
+ <optional> allow-query { <replaceable>address_match_list</replaceable> }; </optional>
+};
+
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
type delegation-only;
};
</para>
</entry>
</row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para>
+ <varname>redirect</varname>
+ </para>
+ </entry>
+ <entry colname="2">
+ <para>
+ Provides a source of answers when the normal resolution
+ returns NXDOMAIN. Only one redirect zone is supported
+ per view. <command>allow-query</command> can be used
+ to restrict which clients see these answers.
+ </para>
+ <para>
+ If the client has requested DNSSEC records (DO=1) and
+ the NXDOMAIN response is signed then no substitution
+ will occur.
+ </para>
+ </entry>
+ </row>
<row rowsep="0">
<entry colname="1">
<para>
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.125 2011/01/07 23:47:07 tbox Exp $ */
+/* $Id: check.c,v 1.126 2011/02/23 03:08:10 marka Exp $ */
/*! \file */
#define FORWARDZONE 16
#define DELEGATIONZONE 32
#define STATICSTUBZONE 64
-#define CHECKACL 128
+#define REDIRECTZONE 128
+#define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */
+#define CHECKACL 256
typedef struct {
const char *name;
const cfg_listelt_t *element;
static optionstable options[] = {
- { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL |
- STATICSTUBZONE },
+ { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE |
+ CHECKACL | STATICSTUBZONE },
{ "allow-notify", SLAVEZONE | CHECKACL },
{ "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL },
{ "notify", MASTERZONE | SLAVEZONE },
{ "also-notify", MASTERZONE | SLAVEZONE },
- { "dialup", MASTERZONE | SLAVEZONE | STUBZONE },
+ { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE },
{ "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE },
{ "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
{ "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
- { "maintain-ixfr-base", MASTERZONE | SLAVEZONE },
- { "max-ixfr-log-size", MASTERZONE | SLAVEZONE },
+ { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
+ { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
{ "notify-source", MASTERZONE | SLAVEZONE },
{ "notify-source-v6", MASTERZONE | SLAVEZONE },
- { "transfer-source", SLAVEZONE | STUBZONE },
- { "transfer-source-v6", SLAVEZONE | STUBZONE },
- { "max-transfer-time-in", SLAVEZONE | STUBZONE },
+ { "transfer-source", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "transfer-source-v6", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "max-transfer-time-in", SLAVEZONE | STUBZONE | STREDIRECTZONE },
{ "max-transfer-time-out", MASTERZONE | SLAVEZONE },
- { "max-transfer-idle-in", SLAVEZONE | STUBZONE },
+ { "max-transfer-idle-in", SLAVEZONE | STUBZONE | STREDIRECTZONE },
{ "max-transfer-idle-out", MASTERZONE | SLAVEZONE },
- { "max-retry-time", SLAVEZONE | STUBZONE },
- { "min-retry-time", SLAVEZONE | STUBZONE },
- { "max-refresh-time", SLAVEZONE | STUBZONE },
- { "min-refresh-time", SLAVEZONE | STUBZONE },
+ { "max-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
{ "dnssec-secure-to-insecure", MASTERZONE },
{ "sig-validity-interval", MASTERZONE },
{ "sig-re-signing-interval", MASTERZONE },
{ "sig-signing-type", MASTERZONE },
{ "sig-signing-signatures", MASTERZONE },
{ "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE |
- STATICSTUBZONE},
+ STATICSTUBZONE| REDIRECTZONE },
{ "allow-update", MASTERZONE | CHECKACL },
{ "allow-update-forwarding", SLAVEZONE | CHECKACL },
- { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE },
- { "journal", MASTERZONE | SLAVEZONE },
+ { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | REDIRECTZONE },
+ { "journal", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
{ "ixfr-base", MASTERZONE | SLAVEZONE },
{ "ixfr-tmp-file", MASTERZONE | SLAVEZONE },
- { "masters", SLAVEZONE | STUBZONE },
+ { "masters", SLAVEZONE | STUBZONE | REDIRECTZONE },
{ "pubkey", MASTERZONE | SLAVEZONE | STUBZONE },
{ "update-policy", MASTERZONE },
- { "database", MASTERZONE | SLAVEZONE | STUBZONE },
+ { "database", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE },
{ "key-directory", MASTERZONE },
{ "check-wildcard", MASTERZONE },
{ "check-mx", MASTERZONE },
{ "integrity-check", MASTERZONE },
{ "check-mx-cname", MASTERZONE },
{ "check-srv-cname", MASTERZONE },
- { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE },
+ { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE |
+ REDIRECTZONE },
{ "update-check-ksk", MASTERZONE },
{ "dnssec-dnskey-kskonly", MASTERZONE },
{ "auto-dnssec", MASTERZONE },
- { "try-tcp-refresh", SLAVEZONE },
+ { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE },
{ "server-addresses", STATICSTUBZONE },
{ "server-names", STATICSTUBZONE },
};
static optionstable dialups[] = {
- { "notify", MASTERZONE | SLAVEZONE },
- { "notify-passive", SLAVEZONE },
- { "refresh", SLAVEZONE | STUBZONE },
- { "passive", SLAVEZONE | STUBZONE },
+ { "notify", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
+ { "notify-passive", SLAVEZONE | STREDIRECTZONE },
+ { "refresh", SLAVEZONE | STUBZONE | STREDIRECTZONE },
+ { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE },
};
znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
ztype = HINTZONE;
else if (strcasecmp(typestr, "delegation-only") == 0)
ztype = DELEGATIONZONE;
+ else if (strcasecmp(typestr, "redirect") == 0)
+ ztype = REDIRECTZONE;
else {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"zone '%s': invalid type %s",
return (ISC_R_FAILURE);
}
+ if (ztype == REDIRECTZONE && strcmp(znamestr, ".") != 0) {
+ cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
+ "redirect zones must be called \".\"");
+ return (ISC_R_FAILURE);
+ }
obj = cfg_tuple_get(zconfig, "class");
if (cfg_obj_isstring(obj)) {
isc_textregion_t r;
zname = dns_fixedname_name(&fixedname);
dns_name_format(zname, namebuf, sizeof(namebuf));
- tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2,
+ tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 :
+ ztype == REDIRECTZONE ? 2 : 3,
symtab, "zone '%s': already exists "
"previous definition: %s:%u", logctx, mctx);
if (tresult != ISC_R_SUCCESS)
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.h,v 1.132 2011/01/13 01:59:28 marka Exp $ */
+/* $Id: view.h,v 1.133 2011/02/23 03:08:11 marka Exp $ */
#ifndef DNS_VIEW_H
#define DNS_VIEW_H 1
dns_viewlist_t * viewlist;
dns_zone_t * managed_keys;
+ dns_zone_t * redirect;
#ifdef BIND9
/* File in which to store configuration for newly added zones */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.182 2010/12/18 01:56:22 each Exp $ */
+/* $Id: zone.h,v 1.183 2011/02/23 03:08:11 marka Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
dns_zone_stub,
dns_zone_staticstub,
dns_zone_key,
- dns_zone_dlz
+ dns_zone_dlz,
+ dns_zone_redirect,
} dns_zonetype_t;
#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.178 2011/01/13 09:53:04 marka Exp $ */
+/* $Id: view.c,v 1.179 2011/02/23 03:08:11 marka Exp $ */
/*! \file */
ISC_LIST_INIT(view->rpz_zones);
dns_fixedname_init(&view->dlv_fixed);
view->managed_keys = NULL;
+ view->redirect = NULL;
#ifdef BIND9
view->new_zone_file = NULL;
view->new_zone_config = NULL;
}
if (view->managed_keys != NULL)
dns_zone_detach(&view->managed_keys);
+ if (view->redirect != NULL)
+ dns_zone_detach(&view->redirect);
dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
#endif
dns_fwdtable_destroy(&view->fwdtable);
dns_zone_flush(view->managed_keys);
dns_zone_detach(&view->managed_keys);
}
+ if (view->redirect != NULL) {
+ if (view->flush)
+ dns_zone_flush(view->redirect);
+ dns_zone_detach(&view->redirect);
+ }
#endif
done = all_done(view);
UNLOCK(&view->lock);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.590 2011/02/22 04:14:30 marka Exp $ */
+/* $Id: zone.c,v 1.591 2011/02/23 03:08:11 marka Exp $ */
/*! \file */
*/
void
dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
+ char namebuf[1024];
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(type != dns_zone_none);
LOCK_ZONE(zone);
REQUIRE(zone->type == dns_zone_none || zone->type == type);
zone->type = type;
+
+ if (zone->strnamerd != NULL)
+ isc_mem_free(zone->mctx, zone->strnamerd);
+
+ zone_namerd_tostr(zone, namebuf, sizeof namebuf);
+ zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
UNLOCK_ZONE(zone);
}
return (ISC_TF(zone->type == dns_zone_slave ||
zone->type == dns_zone_stub ||
zone->type == dns_zone_key ||
+ (zone->type == dns_zone_redirect &&
+ zone->masters != NULL) ||
(!zone->update_disabled && zone->ssutable != NULL) ||
(!zone->update_disabled && zone->update_acl != NULL &&
!dns_acl_isnone(zone->update_acl))));
goto cleanup;
}
- if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
+ if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
+ (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
rbt) {
if (zone->masterfile == NULL ||
!isc_file_exists(zone->masterfile)) {
result = zone_startload(db, zone, loadtime);
} else {
result = DNS_R_NOMASTERFILE;
- if (zone->type == dns_zone_master) {
+ if (zone->type == dns_zone_master ||
+ (zone->type == dns_zone_redirect &&
+ zone->masters == NULL)) {
dns_zone_log(zone, ISC_LOG_ERROR,
"loading zone: "
"no master file configured");
unsigned int options;
options = DNS_MASTER_ZONE;
- if (zone->type == dns_zone_slave)
+ if (zone->type == dns_zone_slave ||
+ (zone->type == dns_zone_redirect && zone->masters == NULL))
options |= DNS_MASTER_SLAVE;
if (zone->type == dns_zone_key)
options |= DNS_MASTER_KEY;
*/
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub) {
+ zone->type == dns_zone_stub ||
+ (zone->type == dns_zone_redirect &&
+ zone->masters == NULL)) {
if (result == ISC_R_FILENOTFOUND)
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"no master file");
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
+ case dns_zone_redirect:
if (soacount != 1) {
dns_zone_log(zone, ISC_LOG_ERROR,
"has %d SOA records", soacount);
result = DNS_R_BADZONE;
goto cleanup;
}
- if (zone->type != dns_zone_stub) {
+ if (zone->type != dns_zone_stub &&
+ zone->type != dns_zone_redirect) {
result = check_nsec3param(zone, db);
if (result != ISC_R_SUCCESS)
goto cleanup;
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub) {
+ zone->type == dns_zone_stub ||
+ (zone->type == dns_zone_redirect &&
+ zone->masters != NULL)) {
isc_time_t t;
isc_uint32_t delay;
cleanup:
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_stub ||
- zone->type == dns_zone_key) {
+ zone->type == dns_zone_key ||
+ (zone->type == dns_zone_redirect && zone->masters != NULL)) {
if (zone->journal != NULL)
zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
if (zone->masterfile != NULL)
if (zone->task != NULL)
zone_settimer(zone, &now);
result = ISC_R_SUCCESS;
- } else if (zone->type == dns_zone_master)
+ } else if (zone->type == dns_zone_master ||
+ zone->type == dns_zone_redirect)
dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
return (result);
}
* Expire check.
*/
switch (zone->type) {
+ case dns_zone_redirect:
+ if (zone->masters == NULL)
+ break;
case dns_zone_slave:
case dns_zone_stub:
LOCK_ZONE(zone);
* Up to date check.
*/
switch (zone->type) {
+ case dns_zone_redirect:
+ if (zone->masters == NULL)
+ break;
case dns_zone_slave:
case dns_zone_stub:
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
case dns_zone_master:
case dns_zone_slave:
case dns_zone_key:
+ case dns_zone_redirect:
LOCK_ZONE(zone);
if (zone->masterfile != NULL &&
isc_time_compare(&now, &zone->dumptime) >= 0 &&
"master %s exceeded (source %s)",
master, source);
/* Try with slave with TCP. */
- if (zone->type == dns_zone_slave &&
+ if ((zone->type == dns_zone_slave ||
+ zone->type == dns_zone_redirect) &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
if (!dns_zonemgr_unreachable(zone->zmgr,
&zone->masteraddr,
* Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
*/
if (msg->rcode == dns_rcode_refused &&
- zone->type == dns_zone_slave)
+ (zone->type == dns_zone_slave ||
+ zone->type == dns_zone_redirect))
goto tcp_transfer;
goto next_master;
}
* If truncated punt to zone transfer which will query again.
*/
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
- if (zone->type == dns_zone_slave) {
+ if (zone->type == dns_zone_slave ||
+ zone->type == dns_zone_redirect) {
dns_zone_log(zone, ISC_LOG_INFO,
"refresh: truncated UDP answer, "
"initiating TCP zone xfer "
dns_zone_log(zone, ISC_LOG_INFO,
"refresh: skipping %s as master %s "
"(source %s) is unreachable (cached)",
- zone->type == dns_zone_slave ?
+ (zone->type == dns_zone_slave ||
+ zone->type == dns_zone_redirect) ?
"zone transfer" : "NS query",
master, source);
goto next_master;
LOCK_ZONE(zone);
dns_request_destroy(&zone->request);
UNLOCK_ZONE(zone);
- if (zone->type == dns_zone_slave) {
+ if (zone->type == dns_zone_slave ||
+ zone->type == dns_zone_redirect) {
queue_xfrin(zone);
} else {
INSIST(zone->type == dns_zone_stub);
isc_time_settoepoch(&next);
switch (zone->type) {
+ case dns_zone_redirect:
+ if (zone->masters != NULL)
+ goto treat_as_slave;
+ /* FALLTHROUGH */
+
case dns_zone_master:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
next = zone->notifytime;
isc_time_compare(&zone->dumptime, &next) < 0)
next = zone->dumptime;
}
+ if (zone->type == dns_zone_redirect)
+ break;
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
!isc_time_isepoch(&zone->refreshkeytime)) {
if (isc_time_isepoch(&next) ||
break;
case dns_zone_slave:
+ treat_as_slave:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
next = zone->notifytime;
- /*FALLTHROUGH*/
+ /* FALLTHROUGH */
case dns_zone_stub:
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
* Leave space for terminating '\0'.
*/
isc_buffer_init(&buffer, buf, length - 1);
- if (dns_name_dynamic(&zone->origin))
- result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
- if (result != ISC_R_SUCCESS &&
- isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
- isc_buffer_putstr(&buffer, "<UNKNOWN>");
+ if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
+ if (dns_name_dynamic(&zone->origin))
+ result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
+ if (result != ISC_R_SUCCESS &&
+ isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
+ isc_buffer_putstr(&buffer, "<UNKNOWN>");
- if (isc_buffer_availablelength(&buffer) > 0)
- isc_buffer_putstr(&buffer, "/");
- (void)dns_rdataclass_totext(zone->rdclass, &buffer);
+ if (isc_buffer_availablelength(&buffer) > 0)
+ isc_buffer_putstr(&buffer, "/");
+ (void)dns_rdataclass_totext(zone->rdclass, &buffer);
+ }
if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
strcmp(zone->view->name, "_default") != 0 &&
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
- level, "%s %s: %s", (zone->type == dns_zone_key) ?
- "managed-keys-zone" : "zone", zone->strnamerd, message);
+ level, "%s%s: %s", (zone->type == dns_zone_key) ?
+ "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
+ "redirect-zone" : "zone ", zone->strnamerd, message);
}
void
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "%s %s: %s", (zone->type == dns_zone_key) ?
- "managed-keys-zone" : "zone", zone->strnamerd, message);
+ level, "%s%s: %s", (zone->type == dns_zone_key) ?
+ "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
+ "redirect-zone" : "zone ", zone->strnamerd, message);
}
static void
&oldserial, NULL, NULL, NULL, NULL,
NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (zone->type == dns_zone_slave &&
- !isc_serial_gt(serial, oldserial)) {
+ if ((zone->type == dns_zone_slave ||
+ (zone->type == dns_zone_redirect &&
+ zone->masters != NULL))
+ && !isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
serialmin = (oldserial + 1) & 0xffffffffU;
serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
dns_zone_forcereload(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
- if (zone->type == dns_zone_master)
+ if (zone->type == dns_zone_master ||
+ (zone->type == dns_zone_redirect && zone->masters == NULL))
return;
LOCK_ZONE(zone);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
dns_zone_notify(zone);
- if (zone->type != dns_zone_master &&
+ if (zone->type != dns_zone_master && zone->masters != NULL &&
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
dns_zone_refresh(zone);
}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.c,v 1.132 2011/02/03 05:41:55 marka Exp $ */
+/* $Id: namedconf.c,v 1.133 2011/02/23 03:08:11 marka Exp $ */
/*! \file */
static const char *zonetype_enums[] = {
"master", "slave", "stub", "static-stub", "hint", "forward",
- "delegation-only", NULL };
+ "delegation-only", "redirect", NULL };
static cfg_type_t cfg_type_zonetype = {
"zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
&cfg_rep_string, &zonetype_enums