]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2039. [func] Redirect on NXDOMAIN support. [RT #23146]
authorMark Andrews <marka@isc.org>
Wed, 23 Feb 2011 03:08:11 +0000 (03:08 +0000)
committerMark Andrews <marka@isc.org>
Wed, 23 Feb 2011 03:08:11 +0000 (03:08 +0000)
32 files changed:
CHANGES
bin/named/bind.keys.h
bin/named/config.c
bin/named/named.conf.docbook
bin/named/query.c
bin/named/server.c
bin/named/zoneconf.c
bin/tests/system/conf.sh.in
bin/tests/system/redirect/clean.sh [new file with mode: 0644]
bin/tests/system/redirect/conf/bad1.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/bad2.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/bad3.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/good1.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/good2.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/good3.conf [new file with mode: 0644]
bin/tests/system/redirect/conf/good4.conf [new file with mode: 0644]
bin/tests/system/redirect/ns1/example.db [new file with mode: 0644]
bin/tests/system/redirect/ns1/named.conf [new file with mode: 0644]
bin/tests/system/redirect/ns1/redirect.db [new file with mode: 0644]
bin/tests/system/redirect/ns1/root.db [new file with mode: 0644]
bin/tests/system/redirect/ns1/sign.sh [new file with mode: 0644]
bin/tests/system/redirect/ns2/named.conf [new file with mode: 0644]
bin/tests/system/redirect/ns2/redirect.db [new file with mode: 0644]
bin/tests/system/redirect/setup.sh [new file with mode: 0644]
bin/tests/system/redirect/tests.sh [new file with mode: 0644]
doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/include/dns/view.h
lib/dns/include/dns/zone.h
lib/dns/view.c
lib/dns/zone.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index 017223a37122220874b252c9c136092c9a21e199..e238e99858663b01c1272f827076cf6035c618c3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+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
index 61e3f700c6cf0823ad49dcf9c8543048cf4179cb..0177214159e7119caca748cac24dc30e9638a7db 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * 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\
index 4fc64e60ef73d6a55a73b76197434e7f54055d84..7122e27a32b1fd578aad95a61586c239529da58f 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -377,6 +377,8 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
                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);
index aa1e54b687dbd81f9cc6fd85dd9a9999a8b7eab6..87971075de9d67b69934fdfe08944422c38aabfa 100644 (file)
@@ -17,7 +17,7 @@
  - 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>
@@ -563,7 +563,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
     <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>;
 
index b00689186d35b9505248de9d8ccb174a38ce9d48..bab7cfd857c0919f95ea2130c6f3e6961afff4ae 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -4928,6 +4928,106 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
        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'
@@ -5844,6 +5944,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t 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
@@ -5904,6 +6009,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                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);
index 0c3c4e23e5a0583c623a26e6d7062abd5bd3a18a..d5e2445964533aa5634bdaaf99d0ab6c823f3073 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -3341,6 +3341,37 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                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.
         */
@@ -3366,9 +3397,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
         *     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)
@@ -3924,6 +3954,9 @@ removed(dns_zone_t *zone, void *uap) {
        case dns_zone_stub:
                type = "stub";
                break;
+       case dns_zone_redirect:
+               type = "redirect";
+               break;
        default:
                type = "other";
                break;
@@ -5017,6 +5050,8 @@ load_zones(ns_server_t *server, isc_boolean_t stop) {
                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));
        }
 
        /*
@@ -5050,6 +5085,8 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) {
                /* 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));
        }
 
        /*
index 7254eece047ba4b5b0b0545e6140971b78197300..f32e654505c83fd73c86c17736ed7c7d9513dd00 100644 (file)
@@ -15,7 +15,7 @@
  * 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 $ */
 
 /*% */
 
@@ -973,7 +973,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
         * 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);
@@ -1046,7 +1047,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                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)) {
@@ -1119,6 +1120,32 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                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);
        }
 
        /*
@@ -1320,6 +1347,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
        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);
index 0102932c539ac62ae26c7678579ca36a1a10aa0d..04718f468d108681d74b68f39c9cfc14c108baa0 100644 (file)
@@ -15,7 +15,7 @@
 # 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
@@ -55,7 +55,7 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint
 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"
 
diff --git a/bin/tests/system/redirect/clean.sh b/bin/tests/system/redirect/clean.sh
new file mode 100644 (file)
index 0000000..8d2ae47
--- /dev/null
@@ -0,0 +1,27 @@
+#!/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
diff --git a/bin/tests/system/redirect/conf/bad1.conf b/bin/tests/system/redirect/conf/bad1.conf
new file mode 100644 (file)
index 0000000..c92fce8
--- /dev/null
@@ -0,0 +1,11 @@
+zone "." {
+       type hint;
+       file "hint.db";
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+       allow-query { 10.0.1.0; };
+       forwarders { 1.2.3.4; };
+};
diff --git a/bin/tests/system/redirect/conf/bad2.conf b/bin/tests/system/redirect/conf/bad2.conf
new file mode 100644 (file)
index 0000000..9973ef8
--- /dev/null
@@ -0,0 +1,11 @@
+zone "." {
+       type hint;
+       file "hint.db";
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+       allow-query { 10.0.1.0; };
+       also-notify { 1.2.3.4; };
+};
diff --git a/bin/tests/system/redirect/conf/bad3.conf b/bin/tests/system/redirect/conf/bad3.conf
new file mode 100644 (file)
index 0000000..b5b56d1
--- /dev/null
@@ -0,0 +1,10 @@
+zone "." {
+       type hint;
+       file "hint.db";
+};
+
+zone "x" {
+       type redirect;
+       file "redirect.db";
+       allow-query { 10.0.1.0; };
+};
diff --git a/bin/tests/system/redirect/conf/good1.conf b/bin/tests/system/redirect/conf/good1.conf
new file mode 100644 (file)
index 0000000..834c286
--- /dev/null
@@ -0,0 +1,9 @@
+zone "." {
+       type hint;
+       file "hint.db";
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+};
diff --git a/bin/tests/system/redirect/conf/good2.conf b/bin/tests/system/redirect/conf/good2.conf
new file mode 100644 (file)
index 0000000..d953365
--- /dev/null
@@ -0,0 +1,9 @@
+zone "." {
+       type master;
+       file "master.db";
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+};
diff --git a/bin/tests/system/redirect/conf/good3.conf b/bin/tests/system/redirect/conf/good3.conf
new file mode 100644 (file)
index 0000000..897a034
--- /dev/null
@@ -0,0 +1,10 @@
+zone "." {
+       type slave;
+       file "slave.db";
+       masters { 1.2.3.4; };
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+};
diff --git a/bin/tests/system/redirect/conf/good4.conf b/bin/tests/system/redirect/conf/good4.conf
new file mode 100644 (file)
index 0000000..f1095b3
--- /dev/null
@@ -0,0 +1,10 @@
+zone "." {
+       type hint;
+       file "hint.db";
+};
+
+zone "." {
+       type redirect;
+       file "redirect.db";
+       allow-query { 10.0.1.0; };
+};
diff --git a/bin/tests/system/redirect/ns1/example.db b/bin/tests/system/redirect/ns1/example.db
new file mode 100644 (file)
index 0000000..cb49045
--- /dev/null
@@ -0,0 +1,55 @@
+; 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
diff --git a/bin/tests/system/redirect/ns1/named.conf b/bin/tests/system/redirect/ns1/named.conf
new file mode 100644 (file)
index 0000000..40dd6d3
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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";
diff --git a/bin/tests/system/redirect/ns1/redirect.db b/bin/tests/system/redirect/ns1/redirect.db
new file mode 100644 (file)
index 0000000..5b04315
--- /dev/null
@@ -0,0 +1,12 @@
+; 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
diff --git a/bin/tests/system/redirect/ns1/root.db b/bin/tests/system/redirect/ns1/root.db
new file mode 100644 (file)
index 0000000..600763d
--- /dev/null
@@ -0,0 +1,24 @@
+; 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
diff --git a/bin/tests/system/redirect/ns1/sign.sh b/bin/tests/system/redirect/ns1/sign.sh
new file mode 100644 (file)
index 0000000..4c19b07
--- /dev/null
@@ -0,0 +1,44 @@
+#!/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
diff --git a/bin/tests/system/redirect/ns2/named.conf b/bin/tests/system/redirect/ns2/named.conf
new file mode 100644 (file)
index 0000000..a2c9a4c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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; };
+};
diff --git a/bin/tests/system/redirect/ns2/redirect.db b/bin/tests/system/redirect/ns2/redirect.db
new file mode 100644 (file)
index 0000000..12997dc
--- /dev/null
@@ -0,0 +1,12 @@
+; 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
diff --git a/bin/tests/system/redirect/setup.sh b/bin/tests/system/redirect/setup.sh
new file mode 100644 (file)
index 0000000..7ec058c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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
diff --git a/bin/tests/system/redirect/tests.sh b/bin/tests/system/redirect/tests.sh
new file mode 100644 (file)
index 0000000..d426e37
--- /dev/null
@@ -0,0 +1,336 @@
+#!/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
index 98babd1dc16f4fd9de93523bb692b8681065bc11..5792a45e94d22343c6359a0d6c8d35e9e4703e55 100644 (file)
@@ -18,7 +18,7 @@
  - 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>
 
@@ -10097,6 +10097,13 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
     <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;
 };
@@ -10337,6 +10344,26 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
                       </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>
index 7e7de7ef107183a1e3a21a6fee1aa693d2aab847..05b8ba2dd0bab57c763e8e8a8aa204e9a86fd3a7 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -1223,7 +1223,9 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
 #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;
@@ -1252,30 +1254,30 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        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 },
@@ -1283,17 +1285,17 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        { "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 },
@@ -1301,20 +1303,21 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        { "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"));
@@ -1344,6 +1347,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
                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",
@@ -1351,6 +1356,11 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
                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;
@@ -1392,7 +1402,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
 
                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)
index 153c52e5c261dc2b1123c8d07b6d8193081db8be..f0cdc462f443bfeab99f2bfee62a0dbcfd1694b9 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -182,6 +182,7 @@ struct dns_view {
        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 */
index de16129325e72c4045e94cfc8978bdc34c45299a..6c5927421e1af47df6a03279175d9c4995761298 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -43,7 +43,8 @@ typedef enum {
        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 */
index 44f868c20cc7a4d0621454a017a714431b685468..b649f5daf1ebab8d3af2b64e9392edd038511e6d 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -195,6 +195,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
        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;
@@ -430,6 +431,8 @@ destroy(dns_view_t *view) {
        }
        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);
@@ -499,6 +502,11 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
                                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);
index 3fea87f932ec09ba8d56434b5cdcaac86996a682..982ec7ecac805c76902b98d81b9cc2403706eb0f 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -1058,6 +1058,7 @@ dns_zone_getserial(dns_zone_t *zone) {
  */
 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);
@@ -1068,6 +1069,12 @@ dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
        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);
 }
 
@@ -1367,6 +1374,8 @@ zone_isdynamic(dns_zone_t *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))));
@@ -1476,7 +1485,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
                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)) {
@@ -1514,7 +1524,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
                        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");
@@ -1580,7 +1592,8 @@ get_master_options(dns_zone_t *zone) {
        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;
@@ -3331,7 +3344,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
         */
        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");
@@ -3436,6 +3451,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
        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);
@@ -3452,7 +3468,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                        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;
@@ -3527,7 +3544,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                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;
 
@@ -3629,7 +3648,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
  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)
@@ -3640,7 +3660,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                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);
 }
@@ -7803,6 +7824,9 @@ zone_maintenance(dns_zone_t *zone) {
         * 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);
@@ -7821,6 +7845,9 @@ zone_maintenance(dns_zone_t *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) &&
@@ -7838,6 +7865,7 @@ zone_maintenance(dns_zone_t *zone) {
        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 &&
@@ -9329,7 +9357,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                                     "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,
@@ -9398,7 +9427,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                 * 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;
        }
@@ -9407,7 +9437,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
         * 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 "
@@ -9531,7 +9562,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                        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;
@@ -9541,7 +9573,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                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);
@@ -10332,6 +10365,11 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
        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;
@@ -10342,6 +10380,8 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
                            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) ||
@@ -10371,9 +10411,10 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
                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) &&
@@ -11035,15 +11076,17 @@ zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
         * 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 &&
@@ -11152,8 +11195,9 @@ dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
        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
@@ -11168,8 +11212,9 @@ dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
        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
@@ -11447,8 +11492,10 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
                                          &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;
@@ -13056,7 +13103,8 @@ void
 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);
@@ -13148,7 +13196,7 @@ dns_zone_dialup(dns_zone_t *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);
 }
index d1a8df4cc1186e7d3a1db3cabb285afbda06539c..4b666b25db8269ec0f7cd00fbef671884b0e048d 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -594,7 +594,7 @@ static cfg_type_t cfg_type_forwardtype = {
 
 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