]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Squashed commit of the following:
authorVernon Schryver <vjs@isc.org>
Thu, 31 May 2012 02:03:34 +0000 (02:03 +0000)
committerVernon Schryver <vjs@isc.org>
Thu, 31 May 2012 02:03:34 +0000 (02:03 +0000)
commit aea73609ac5d41ed091360e94370798965f28f05
commit eef7f44c57a060b24a426eb8888e16176a0a69b1
commit a88a26d864ad399fa2d40e3b9659b4d26f454ca1
commit 1b90d59568e7e3b65690c6bd075cf4d60b03e454
Merge: 74d8f73 cd02924
commit 74d8f73ed553bb64a305e284905762f7ff0029aa
commit 9a59ef6bbd4befe91e5691e8b85afe1cb7ab0706
commit c63606a53b4f1bb7066b37d3cfe588e9dc21a119
commit 2c392a840c8838455d144ce163bd873bee400c97
commit 0241f53563e6e7bed462a883d98a8931f01e0980
commit 79fe22b5d6f04bdaa3073cf54d41952194e879e1
commit 351b3049625f2edd39729dd85413e961b97d4b3b
commit 7207674fc77c9a10d84c0cb94e36d1c09bb31459
commit 543ad34cf08f901c20b438c9d2f45482cff13d5e
commit fc45b99ce4438627fdcbeb4365695ba0065fa46f
commit c425207f57e0a5157372aa7edbb79b13170563e5
commit ef8c5e23ca284e0ea02f69ce1f356d537c19d93b
commit ba0d4e3aa51efe412cfa1d031651f949442d1802
commit 41c7969c7cb6884b93011f7ace3fd9522efc021e
  and more from CVS

for rt26172

Add
  - optional "recursive-only yes|no" to the response-policy statement
  - optional max-policy-ttl to limit the lies that "recursive-only no"
      can introduce into resolvers' caches
  - test that queries with RD=0 are not rewritten by default
  - performance smoke test

Change encoding of PASSTHRU action to "rpz-passthru".
      (The old encoding is still accepted.)
Fix rt26180  assert botch in zone_findrdataset() in this branch
     as well.

Fix missing signatures on NOERROR results despite RPZ hits
    when there are signatures and the client asks for DNSSEC,

31 files changed:
bin/named/query.c
bin/named/server.c
bin/tests/system/rpz/clean.sh
bin/tests/system/rpz/ns1/root.db
bin/tests/system/rpz/ns2/base-tld2s.db [new file with mode: 0644]
bin/tests/system/rpz/ns2/named.conf
bin/tests/system/rpz/ns2/tld2.db
bin/tests/system/rpz/ns3/base.db
bin/tests/system/rpz/ns3/crash2
bin/tests/system/rpz/ns3/named.conf
bin/tests/system/rpz/ns4/named.conf
bin/tests/system/rpz/ns4/tld4.db
bin/tests/system/rpz/ns5/hints [new file with mode: 0644]
bin/tests/system/rpz/ns5/named.conf [new file with mode: 0644]
bin/tests/system/rpz/qperf.sh [new file with mode: 0644]
bin/tests/system/rpz/rpz.c
bin/tests/system/rpz/setup.sh
bin/tests/system/rpz/test1
bin/tests/system/rpz/test2
bin/tests/system/rpz/test5
bin/tests/system/rpz/tests.sh
doc/arm/Bv9ARM-book.xml
lib/dns/db.c
lib/dns/include/dns/db.h
lib/dns/include/dns/rpz.h
lib/dns/include/dns/view.h
lib/dns/rbtdb.c
lib/dns/rpz.c
lib/dns/view.c
lib/isccfg/namedconf.c
util/copyrights

index a096df037d766ffc20f67e4b949b4f568f8326df..11b204d6044f201a442df3fc7b9e0e820f2ffd1f 100644 (file)
@@ -3880,6 +3880,13 @@ rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
                dns_rdataset_disassociate(*rdatasetp);
 }
 
+static void
+rpz_match_clear(dns_rpz_st_t *st)
+{
+       rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
+       st->m.version = NULL;
+}
+
 static inline isc_result_t
 rpz_ready(ns_client_t *client, dns_zone_t **zonep, dns_db_t **dbp,
          dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp)
@@ -3899,10 +3906,9 @@ static void
 rpz_st_clear(ns_client_t *client) {
        dns_rpz_st_t *st = client->query.rpz_st;
 
-       rpz_clean(&st->m.zone, &st->m.db, &st->m.node, NULL);
-       st->m.version = NULL;
        if (st->m.rdataset != NULL)
                query_putrdataset(client, &st->m.rdataset);
+       rpz_match_clear(st);
 
        rpz_clean(NULL, &st->r.db, NULL, NULL);
        if (st->r.ns_rdataset != NULL)
@@ -4058,6 +4064,9 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
        for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
             rpz != NULL;
             rpz = ISC_LIST_NEXT(rpz, link)) {
+               if (!RECURSIONOK(client) && rpz->recursive_only)
+                       continue;
+
                /*
                 * Do not check policy zones that cannot replace a policy
                 * already known to match.
@@ -4086,9 +4095,8 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
                 * hit, if any.  Note the domain name and quality of the
                 * best hit.
                 */
-               (void)dns_db_rpz_findips(rpz, rpz_type, zone, db, version,
-                                        rdataset, st,
-                                        client->query.rpz_st->qname);
+               dns_db_rpz_findips(rpz, rpz_type, zone, db, version,
+                                  rdataset, st, client->query.rpz_st->qname);
                rpz_clean(&zone, &db, NULL, NULL);
        }
        return (ISC_R_SUCCESS);
@@ -4193,8 +4201,8 @@ rpz_rewrite_rrsets(ns_client_t *client, dns_rpz_type_t rpz_type,
  */
 static isc_result_t
 rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
-        dns_name_t *sname, dns_rpz_type_t rpz_type, dns_zone_t **zonep,
-        dns_db_t **dbp, dns_dbversion_t **versionp,
+        dns_name_t *sname, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
+        dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
         dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
         dns_rpz_policy_t *policyp)
 {
@@ -4239,7 +4247,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
                if (result != ISC_R_SUCCESS) {
                        dns_db_detachnode(*dbp, nodep);
                        rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type,
-                                    qnamef, "allrdatasets()", result);
+                                    qnamef, "allrdatasets() ", result);
                        *policyp = DNS_RPZ_POLICY_ERROR;
                        return (DNS_R_SERVFAIL);
                }
@@ -4256,7 +4264,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
                if (result != ISC_R_SUCCESS) {
                        if (result != ISC_R_NOMORE) {
                                rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
-                                            rpz_type, qnamef, "rdatasetiter",
+                                            rpz_type, qnamef, "rdatasetiter ",
                                             result);
                                *policyp = DNS_RPZ_POLICY_ERROR;
                                return (DNS_R_SERVFAIL);
@@ -4284,7 +4292,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
                if ((*rdatasetp)->type != dns_rdatatype_cname) {
                        policy = DNS_RPZ_POLICY_RECORD;
                } else {
-                       policy = dns_rpz_decode_cname(*rdatasetp, sname);
+                       policy = dns_rpz_decode_cname(rpz, *rdatasetp, sname);
                        if ((policy == DNS_RPZ_POLICY_RECORD ||
                             policy == DNS_RPZ_POLICY_WILDCNAME) &&
                            qtype != dns_rdatatype_cname &&
@@ -4355,6 +4363,9 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
        for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
             rpz != NULL;
             rpz = ISC_LIST_NEXT(rpz, link)) {
+               if (!RECURSIONOK(client) && rpz->recursive_only)
+                       continue;
+
                /*
                 * Do not check policy zones that cannot replace a policy
                 * already known to match.
@@ -4400,11 +4411,11 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
                }
 
                /*
-                * See if the policy record exists.
+                * See if the policy record exists and get its policy.
                 */
-               result = rpz_find(client, qtype, rpz_qname, qname, rpz_type,
-                                 &zone, &db, &version, &node, rdatasetp,
-                                 &policy);
+               result = rpz_find(client, qtype, rpz_qname, qname, rpz,
+                                 rpz_type, &zone, &db, &version, &node,
+                                 rdatasetp, &policy);
                switch (result) {
                case DNS_R_NXDOMAIN:
                case DNS_R_EMPTYNAME:
@@ -4440,8 +4451,7 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
                                continue;
                        }
 
-                       rpz_clean(&st->m.zone, &st->m.db, &st->m.node,
-                                 &st->m.rdataset);
+                       rpz_match_clear(st);
                        st->m.rpz = rpz;
                        st->m.type = rpz_type;
                        st->m.prefix = 0;
@@ -4455,9 +4465,11 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
                                trdataset = st->m.rdataset;
                                st->m.rdataset = *rdatasetp;
                                *rdatasetp = trdataset;
-                               st->m.ttl = st->m.rdataset->ttl;
+                               st->m.ttl = ISC_MIN(st->m.rdataset->ttl,
+                                                   rpz->max_policy_ttl);
                        } else {
-                               st->m.ttl = DNS_RPZ_TTL_DEFAULT;
+                               st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT,
+                                                   rpz->max_policy_ttl);
                        }
                        st->m.node = node;
                        node = NULL;
@@ -4552,13 +4564,13 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
        case DNS_R_BROKENCHAIN:
                rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, DNS_RPZ_TYPE_QNAME,
                             client->query.qname,
-                            "stop on qresult in rpz_rewrite()",
+                            "stop on qresult in rpz_rewrite() ",
                             qresult);
                return (ISC_R_SUCCESS);
        default:
                rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, DNS_RPZ_TYPE_QNAME,
                             client->query.qname,
-                            "stop on unrecognized qresult in rpz_rewrite()",
+                            "stop on unrecognized qresult in rpz_rewrite() ",
                             qresult);
                return (ISC_R_SUCCESS);
        }
@@ -4737,10 +4749,11 @@ cleanup:
        if (st->m.policy == DNS_RPZ_POLICY_MISS ||
            st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
            st->m.policy == DNS_RPZ_POLICY_ERROR) {
-               if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU)
+               if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU &&
+                   result != DNS_R_DELEGATION)
                        rpz_log_rewrite(client, "", st->m.policy, st->m.type,
                                        st->qname);
-               rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
+               rpz_match_clear(st);
        }
        if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
                st->m.type = DNS_RPZ_TYPE_BAD;
@@ -4753,6 +4766,64 @@ cleanup:
        return (result);
 }
 
+/*
+ * See if response policy zone rewriting is allowed a lack of interest
+ * by the client in DNSSEC or a lack of signatures.
+ */
+static isc_boolean_t
+rpz_ck_dnssec(ns_client_t *client, isc_result_t result,
+             dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+       dns_fixedname_t fixed;
+       dns_name_t *found;
+       dns_rdataset_t trdataset;
+       dns_rdatatype_t type;
+
+       if (client->view->rpz_break_dnssec)
+               return (ISC_TRUE);
+       /*
+        * sigrdataset == NULL if and only !WANTDNSSEC(client)
+        */
+       if (sigrdataset == NULL)
+               return (ISC_TRUE);
+       if (dns_rdataset_isassociated(sigrdataset))
+               return (ISC_FALSE);
+
+       /*
+        * We are happy to rewrite nothing.
+        */
+       if (rdataset == NULL || !dns_rdataset_isassociated(rdataset))
+               return (ISC_TRUE);
+       /*
+        * Do not rewrite if there is any sign of signatures.
+        */
+       if (rdataset->type == dns_rdatatype_nsec ||
+           rdataset->type == dns_rdatatype_nsec3 ||
+           rdataset->type == dns_rdatatype_rrsig)
+               return (ISC_FALSE);
+
+       /*
+        * Look for a signature in a negative cache rdataset.
+        */
+       if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
+               return (ISC_TRUE);
+       dns_fixedname_init(&fixed);
+       found = dns_fixedname_name(&fixed);
+       dns_rdataset_init(&trdataset);
+       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);
+       }
+       return (ISC_TRUE);
+}
+
 /*
  * Add a CNAME to the query response, including translating foo.evil.com and
  *     *.evil.com CNAME *.example.com
@@ -4797,7 +4868,8 @@ rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st,
         * Turn off DNSSEC because the results of a
         * response policy zone cannot verify.
         */
-       client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+       client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
+                               DNS_MESSAGEFLAG_AD);
        return (ISC_R_SUCCESS);
 }
 
@@ -5727,9 +5799,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
        CTRACE("query_find: resume");
 
        if (!ISC_LIST_EMPTY(client->view->rpz_zones) &&
-           RECURSIONOK(client) && !RECURSING(client) &&
-           (!WANTDNSSEC(client) || sigrdataset == NULL ||
-            !dns_rdataset_isassociated(sigrdataset)) &&
+           (RECURSIONOK(client) || !client->view->rpz_recursive_only) &&
+           rpz_ck_dnssec(client, result, rdataset, sigrdataset) &&
+           !RECURSING(client) &&
            (client->query.rpz_st == NULL ||
             (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
            !dns_name_equal(client->query.qname, dns_rootname)) {
@@ -5803,10 +5875,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                                break;
                        case DNS_RPZ_POLICY_RECORD:
                                result = rpz_st->m.result;
-                               if (type == dns_rdatatype_any &&
-                                   result != DNS_R_CNAME &&
-                                   dns_rdataset_isassociated(rdataset))
-                                       dns_rdataset_disassociate(rdataset);
+                               if (qtype == dns_rdatatype_any &&
+                                   result != DNS_R_CNAME) {
+                                       /*
+                                        * We will add all of the rdatasets of
+                                        * the node by iterating, setting the
+                                        * TTL then.
+                                        */
+                                       if (dns_rdataset_isassociated(rdataset))
+                                           dns_rdataset_disassociate(rdataset);
+                               } else {
+                                       /*
+                                        * We will add this rdataset.
+                                        */
+                                       rdataset->ttl = ISC_MIN(rdataset->ttl,
+                                                           rpz_st->m.ttl);
+                               }
                                break;
                        case DNS_RPZ_POLICY_WILDCNAME:
                                result = dns_rdataset_first(rdataset);
@@ -5845,7 +5929,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                         * Turn off DNSSEC because the results of a
                         * response policy zone cannot verify.
                         */
-                       client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+                       client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
+                                               DNS_MESSAGEFLAG_AD);
                        query_putrdataset(client, &sigrdataset);
                        is_zone = ISC_TRUE;
                        rpz_log_rewrite(client, "", rpz_st->m.policy,
@@ -6804,6 +6889,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                                        noqname = rdataset;
                                else
                                        noqname = NULL;
+                               rpz_st = client->query.rpz_st;
+                               if (rpz_st != NULL)
+                                       rdataset->ttl = ISC_MIN(rdataset->ttl,
+                                                           rpz_st->m.ttl);
                                query_addrrset(client,
                                               fname != NULL ? &fname : &tname,
                                               &rdataset, NULL,
@@ -7096,8 +7185,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
         */
        rpz_st = client->query.rpz_st;
        if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) {
-               rpz_clean(&rpz_st->m.zone, &rpz_st->m.db, &rpz_st->m.node,
-                         &rpz_st->m.rdataset);
+               rpz_match_clear(rpz_st);
                rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
        }
        if (rdataset != NULL)
index 46864c83141ea9d48337278d933eca5823677597..de26986bd1ffed184e22466fa744c49e1cf0b39e 100644 (file)
@@ -1440,15 +1440,14 @@ cleanup:
 }
 
 static isc_result_t
-configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
-       const cfg_obj_t *rpz_obj, *policy_obj;
+configure_rpz(dns_view_t *view, const cfg_listelt_t *element,
+             isc_boolean_t recursive_only_def, dns_ttl_t ttl_def)
+{
+       const cfg_obj_t *rpz_obj, *policy_obj, *obj;
        const char *str;
-       dns_fixedname_t fixed;
-       dns_name_t *origin;
        dns_rpz_zone_t *old, *new;
        dns_zone_t *zone = NULL;
        isc_result_t result;
-       unsigned int l1, l2;
 
        new = isc_mem_get(view->mctx, sizeof(*new));
        if (new == NULL) {
@@ -1457,9 +1456,10 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
        }
 
        memset(new, 0, sizeof(*new));
-       dns_name_init(&new->nsdname, NULL);
        dns_name_init(&new->origin, NULL);
+       dns_name_init(&new->nsdname, NULL);
        dns_name_init(&new->cname, NULL);
+       dns_name_init(&new->passthru, NULL);
        ISC_LIST_INITANDAPPEND(view->rpz_zones, new, link);
 
        rpz_obj = cfg_listelt_value(element);
@@ -1467,15 +1467,31 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
        if (cfg_obj_isvoid(policy_obj)) {
                new->policy = DNS_RPZ_POLICY_GIVEN;
        } else {
-               str = cfg_obj_asstring(policy_obj);
+               str = cfg_obj_asstring(cfg_tuple_get(policy_obj,
+                                                    "policy name"));
                new->policy = dns_rpz_str2policy(str);
                INSIST(new->policy != DNS_RPZ_POLICY_ERROR);
        }
 
-       dns_fixedname_init(&fixed);
-       origin = dns_fixedname_name(&fixed);
-       str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "name"));
-       result = dns_name_fromstring(origin, str, DNS_NAME_DOWNCASE, NULL);
+       obj = cfg_tuple_get(rpz_obj, "recursive-only");
+       if (cfg_obj_isvoid(obj)) {
+               new->recursive_only = recursive_only_def;
+       } else {
+               new->recursive_only = cfg_obj_asboolean(obj);
+       }
+       if (!new->recursive_only)
+               view->rpz_recursive_only = ISC_FALSE;
+
+       obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
+       if (cfg_obj_isuint32(obj)) {
+               new->max_policy_ttl = cfg_obj_asuint32(obj);
+       } else {
+               new->max_policy_ttl = ttl_def;
+       }
+
+       str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "zone name"));
+       result = dns_name_fromstring(&new->origin, str, DNS_NAME_DOWNCASE,
+                                    view->mctx);
        if (result != ISC_R_SUCCESS) {
                cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
                            "invalid zone '%s'", str);
@@ -1483,31 +1499,28 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
        }
 
        result = dns_name_fromstring2(&new->nsdname, DNS_RPZ_NSDNAME_ZONE,
-                                     origin, DNS_NAME_DOWNCASE, view->mctx);
+                                     &new->origin, DNS_NAME_DOWNCASE,
+                                     view->mctx);
        if (result != ISC_R_SUCCESS) {
                cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
                            "invalid zone '%s'", str);
                goto cleanup;
        }
 
-       /*
-        * The origin is part of 'nsdname' so we don't need to keep it
-        * seperately.
-        */
-       l1 = dns_name_countlabels(&new->nsdname);
-       l2 = dns_name_countlabels(origin);
-       dns_name_getlabelsequence(&new->nsdname, l1 - l2, l2, &new->origin);
+       result = dns_name_fromstring(&new->passthru, DNS_RPZ_PASSTHRU_ZONE,
+                                    DNS_NAME_DOWNCASE, view->mctx);
+       if (result != ISC_R_SUCCESS) {
+               cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+                           "invalid zone '%s'", str);
+               goto cleanup;
+       }
 
-       /*
-        * Are we configured to with the reponse policy zone?
-        */
        result = dns_view_findzone(view, &new->origin, &zone);
        if (result != ISC_R_SUCCESS) {
                cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
                            "unknown zone '%s'", str);
                goto cleanup;
        }
-
        if (dns_zone_gettype(zone) != dns_zone_master &&
            dns_zone_gettype(zone) != dns_zone_slave) {
                cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
@@ -1531,8 +1544,9 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
        }
 
        if (new->policy == DNS_RPZ_POLICY_CNAME) {
-               str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "cname"));
-               result = dns_name_fromstring(&new->cname, str, 0, view->mctx);
+               str = cfg_obj_asstring(cfg_tuple_get(policy_obj, "cname"));
+               result = dns_name_fromstring(&new->cname, str,
+                                            DNS_NAME_DOWNCASE, view->mctx);
                if (result != ISC_R_SUCCESS) {
                        cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
                                    "invalid cname '%s'", str);
@@ -2877,19 +2891,39 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
         * Make the list of response policy zone names for views that
         * are used for real lookups and so care about hints.
         */
-       zonelist = NULL;
-       if (view->rdclass == dns_rdataclass_in && need_hints) {
-               obj = NULL;
-               result = ns_config_get(maps, "response-policy", &obj);
-               if (result == ISC_R_SUCCESS)
-                       cfg_map_get(obj, "zone", &zonelist);
-       }
+       obj = NULL;
+       if (view->rdclass == dns_rdataclass_in && need_hints &&
+           ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) {
+               const cfg_obj_t *recursive_only_obj;
+               const cfg_obj_t *break_dnssec_obj, *ttl_obj;
+               isc_boolean_t recursive_only_def;
+               dns_ttl_t ttl_def;
+
+               recursive_only_obj = cfg_tuple_get(obj, "recursive-only");
+               if (!cfg_obj_isvoid(recursive_only_obj) &&
+                   !cfg_obj_asboolean(recursive_only_obj))
+                       recursive_only_def = ISC_FALSE;
+               else
+                       recursive_only_def = ISC_TRUE;
 
-       if (zonelist != NULL) {
-               for (element = cfg_list_first(zonelist);
+               break_dnssec_obj = cfg_tuple_get(obj, "break-dnssec");
+               if (!cfg_obj_isvoid(break_dnssec_obj) &&
+                   cfg_obj_asboolean(break_dnssec_obj))
+                       view->rpz_break_dnssec = ISC_TRUE;
+               else
+                       view->rpz_break_dnssec = ISC_FALSE;
+
+               ttl_obj = cfg_tuple_get(obj, "max-policy-ttl");
+               if (cfg_obj_isuint32(ttl_obj))
+                       ttl_def = cfg_obj_asuint32(ttl_obj);
+               else
+                       ttl_def = DNS_RPZ_MAX_TTL_DEFAULT;
+
+               for (element = cfg_list_first(cfg_tuple_get(obj, "zone list"));
                     element != NULL;
                     element = cfg_list_next(element)) {
-                       result = configure_rpz(view, element);
+                       result = configure_rpz(view, element,
+                                              recursive_only_def, ttl_def);
                        if (result != ISC_R_SUCCESS)
                                goto cleanup;
                        dns_rpz_set_need(ISC_TRUE);
index f95d11a81b85e123ef827546b8d63c1b6fa0b6d3..82cfcb29094b6e4044b6dd902dfde8de15e15476 100644 (file)
@@ -17,8 +17,8 @@
 
 # Clean up after rpz tests.
 
-rm -f proto.* dig.out* nsupdate.tmp
-rm -f  */named.memstats */named.run */named.rpz */session.key
-rm -f ns3/bl*.db */*.jnl */*.core */*.pid
-rm -f ns2/signed-tld2.db
-rm -f ns2/K*.private ns2/K*.key dsset-*
+rm -f proto.*  dsset-* random.data trusted.conf dig.out* nsupdate.tmp ns*/*tmp
+rm -f ns*/*.key ns*/*.private ns2/tld2s.db
+rm -f ns3/bl*.db ns*/*switch ns5/requests ns5/example.db ns5/bl.db ns5/*.perf
+rm -f */named.memstats */named.run */named.rpz */session.key
+rm -f */*.jnl */*.core */*.pid
index c691b6e419dee71edcc339ca355f3db7a82db1ab..c8d8671c7f6b60751cd181a8c1e6f4ac205d5e7f 100644 (file)
@@ -23,12 +23,9 @@ ns.          A       10.53.0.1
 ; rewrite responses from this zone
 tld2.          NS      ns.tld2.
 ns.tld2.       A       10.53.0.2
-ns2.tld2.      A       10.53.0.2
 
-; rewrite responses from this zone unless dnssec requested
-signed-tld2.           NS      ns.signed-tld2.
-ns.signed-tld2.                A       10.53.0.2
-ns2.signed-tld2.       A       10.53.0.2
+; rewrite responses from this secure zone unless dnssec requested (DO=1)
+tld2s.         NS      ns.tld2.
 
 ; requests come from here
 tld3.          NS      ns.tld3.
@@ -37,4 +34,3 @@ ns.tld3.      A       10.53.0.3
 ; rewrite responses from this zone
 tld4.          NS      ns.tld4.
 ns.tld4.       A       10.53.0.4
-ns2.tld4.      A       10.53.0.4
diff --git a/bin/tests/system/rpz/ns2/base-tld2s.db b/bin/tests/system/rpz/ns2/base-tld2s.db
new file mode 100644 (file)
index 0000000..5c3881c
--- /dev/null
@@ -0,0 +1,31 @@
+; Copyright (C) 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: base-tld2s.db,v 1.1.2.1 2012/02/24 17:22:37 vjs Exp $
+
+
+; RPZ rewrite responses from this signed zone
+
+$TTL   120
+@              SOA     tld2s.  hostmaster.ns.tld2. ( 1 3600 1200 604800 60 )
+               NS      ns
+               NS      .                       ; check for RT 24985
+ns             A       10.53.0.2
+
+
+a0-1           A       192.168.0.1
+a0-1-scname    CNAME   a0-1.tld2.
+
+a3-5           A       192.168.3.5
+
index 32640f6362c57089fea028d41420604718c86a65..a2fcd8254f8baad573884b558d35feb9483e87ed 100644 (file)
@@ -31,6 +31,7 @@ options {
        notify no;
 };
 
+include "../trusted.conf";
 zone "." { type hint; file "hints"; };
 
 zone "tld2."               {type master; file "tld2.db";};
@@ -40,4 +41,5 @@ zone "sub2.tld2."         {type master; file "tld2.db";};
 zone "subsub.sub2.tld2."    {type master; file "tld2.db";};
 zone "sub3.tld2."          {type master; file "tld2.db";};
 zone "subsub.sub3.tld2."    {type master; file "tld2.db";};
-zone "signed-tld2."        {type master; file "signed-tld2.db";};
+
+zone "tld2s."              {type master; file "tld2s.db";};
index 5f5550a94c5ef57c920b32243cbb1436c6c6f6fb..9ce888c6eb7a22b282578a812b0fc5bd385d0efa 100644 (file)
@@ -12,7 +12,7 @@
 ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 ; PERFORMANCE OF THIS SOFTWARE.
 
-; $Id: tld2.db,v 1.4 2011/10/13 01:32:33 vjs Exp $
+; $Id: tld2.db,v 1.4.4.2 2012/02/24 17:22:37 vjs Exp $
 
 
 ; RPZ rewrite responses from this zone
 $TTL   120
 @              SOA     tld2.  hostmaster.ns.tld2. ( 1 3600 1200 604800 60 )
                NS      ns
-               NS      ns2
                NS      .                       ; check for RT 24985
 ns             A       10.53.0.2
-ns2            A       10.53.0.2
 
 
 txt-only       TXT     "txt-only-tld2"
@@ -36,6 +34,8 @@ a12-cname     CNAME   a12
 a0-1           A       192.168.0.1
                AAAA    2001:2::1
                TXT     "a0-1 tld2 text"
+a0-1-scname    CNAME   a0-1.tld2s.
+
 
 a3-1           A       192.168.3.1
                AAAA    2001:2:3::1
@@ -115,3 +115,8 @@ a5-3                A       192.168.5.3
 
 a5-4           A       192.168.5.4
                TXT     "a5-4 tld2 text"
+
+a6-1           A       192.168.6.1
+               TXT     "a6-1 tld2 text"
+a6-2           A       192.168.6.2
+               TXT     "a6-2 tld2 text"
index 23bf71d016fd8314e6e8f12213e42012304fbecb..cdc4466b19141ccd957e938b02fb5aafe4445809 100644 (file)
 ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 ; PERFORMANCE OF THIS SOFTWARE.
 
-; $Id: base.db,v 1.6 2011/10/13 01:32:33 vjs Exp $
+; $Id: base.db,v 1.6.4.1 2011/10/15 23:03:38 vjs Exp $
 
 
 ; RPZ test
+;   This basic file is copied to several zone files before being used.
+;   Its contents are also changed with nsupdate
+
 
 $TTL   120
 @      SOA     blx.  hostmaster.ns.blx. ( 1 3600 1200 604800 60 )
-       NS      ns.tld.
+       NS      ns
 ns     A       10.53.0.3
 
 ; Poke the radix tree a little.
@@ -34,6 +37,6 @@ ns    A       10.53.0.3
 
 
 ; regression testing for some old crashes
-redirect       IN      A       127.0.0.1
-*.redirect     IN      A       127.0.0.1
-*.credirect    IN      CNAME   google.com.
+redirect       A       127.0.0.1
+*.redirect     A       127.0.0.1
+*.credirect    CNAME   google.com.
index d042c3c7bf5854074b579fd2226d705d29d88dfe..cd613bce90549e108d1438c79e96f0433fdb8b93 100644 (file)
@@ -21,8 +21,8 @@ $TTL  120
        NS      ns
 ns     A       10.53.0.3
 
-; #18 in test1, crashed new ASSERT() in rbtdb.c
-c1     A       172.16.1.1
+; #24 in test1, crashed new ASSERT() in rbtdb.c
+c1     A       172.16.1.24
 
 ; #16 in test2, crashed new ASSERT() in rbtdb.c
 c2     A       172.16.1.16
index 57244b8735dea1e2f22d47facaf840ea911daf6b..dfc7341d0851d69618ef49a0e98c7bd463a5a052 100644 (file)
 /* $Id: named.conf,v 1.5 2011/10/28 11:46:50 marka Exp $ */
 
 
+/*
+ * Main rpz test DNS server.
+ */
+
 options {
        query-source address 10.53.0.3;
        notify-source 10.53.0.3;
@@ -29,13 +33,13 @@ options {
        notify no;
 
        response-policy {
-           zone "bl";
+           zone "bl"                                   max-policy-ttl 100;
            zone "bl-2";
-           zone "bl-given"     policy given;
+           zone "bl-given"     policy given            recursive-only yes;
            zone "bl-passthru"  policy passthru;
-           zone "bl-no-op"     policy no-op;       # obsolete for passthru
+           zone "bl-no-op"     policy no-op;           # obsolete for passthru
            zone "bl-disabled"  policy disabled;
-           zone "bl-nodata"    policy nodata;
+           zone "bl-nodata"    policy nodata           recursive-only no;
            zone "bl-nxdomain"  policy nxdomain;
            zone "bl-cname"     policy cname txt-only.tld2.;
            zone "bl-wildcname" policy cname *.tld4.;
@@ -63,6 +67,7 @@ logging {
 };
 
 
+// include "../trusted.conf";
 zone "." { type hint; file "hints"; };
 
 zone "bl."             {type master; file "bl.db";
index 78644b127ed419267e2620609f1beb765c6e4902..f8c6c902e86c2a0ff1e9e5116246e2b9219b0723 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.2 2011/10/13 04:53:06 marka Exp $ */
+/* $Id: named.conf,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $ */
 
 controls { /* empty */ };
 
@@ -30,6 +30,7 @@ options {
        notify no;
 };
 
+include "../trusted.conf";
 zone "." { type hint; file "hints"; };
 
 zone "tld4."               {type master; file "tld4.db";};
index 24999de9932c16523042e4e73798c7f4822ae3d1..54356d8f390c7a950d2a0ee6845d2f4949a2d7e3 100644 (file)
 ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 ; PERFORMANCE OF THIS SOFTWARE.
 
-; $Id: tld4.db,v 1.2 2011/10/13 04:53:07 marka Exp $
+; $Id: tld4.db,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $
 
 ; RPZ rewrite responses from this zone
 
 $TTL   120
 @              SOA     tld4.  hostmaster.ns.tld4. ( 1 3600 1200 604800 60 )
                NS      ns
-               NS      ns2
 ns             A       10.53.0.4
-ns2            A       10.53.0.4
 
 
 txt-only       TXT     "txt-only-tld4"
diff --git a/bin/tests/system/rpz/ns5/hints b/bin/tests/system/rpz/ns5/hints
new file mode 100644 (file)
index 0000000..2c01349
--- /dev/null
@@ -0,0 +1,19 @@
+; Copyright (C) 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: hints,v 1.1.2.1 2011/10/15 23:00:04 vjs Exp $
+
+
+.      0       NS      ns1.
+ns1.   0       A       10.53.0.1
diff --git a/bin/tests/system/rpz/ns5/named.conf b/bin/tests/system/rpz/ns5/named.conf
new file mode 100644 (file)
index 0000000..760c02c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 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.1.2.2 2012/02/24 17:22:38 vjs Exp $ */
+
+
+/*
+ * Test rpz performance.
+ */
+
+options {
+       query-source address 10.53.0.5;
+       notify-source 10.53.0.5;
+       transfer-source 10.53.0.5;
+       port 5300;
+       pid-file "named.pid";
+       session-keyfile "session.key";
+       listen-on { 10.53.0.5; };
+       listen-on-v6 { none; };
+       notify no;
+
+       # Eventually turn rpz on.
+       include "rpz-switch";
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-md5;
+};
+controls { inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; }; };
+
+
+include "../trusted.conf";
+zone "."               {type hint; file "hints"; };
+
+zone "example.com."    {type master; file "example.db"; };
+
+zone "bl."             {type master; file "bl.db"; };
diff --git a/bin/tests/system/rpz/qperf.sh b/bin/tests/system/rpz/qperf.sh
new file mode 100644 (file)
index 0000000..3d227e2
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+#
+# Copyright (C) 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: qperf.sh,v 1.1.2.1 2011/10/15 23:03:37 vjs Exp $
+
+for QDIR in `echo "$PATH" | tr : ' '` ../../../../contrib/queryperf; do
+    QPERF=$QDIR/queryperf
+    if test -f $QPERF -a -x $QPERF; then
+       echo $QPERF
+       exit 0
+    fi
+done
+
+exit 0
index f1dd3261f19fc5400c814cfe060abfb1a2135ae5..3d6a21386224d163149511f6bf490ca8af7f3893 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rpz.c,v 1.3 2011/01/13 04:59:24 tbox Exp $ */
+/* $Id: rpz.c,v 1.3.226.1 2011/10/15 23:03:37 vjs Exp $ */
 
 #include <config.h>
 
@@ -39,7 +39,7 @@ main(int argc, char **argv)
 #else
                return (1);
 #endif
-           }
+       }
 
        if (!strcasecmp(argv[1], "nsdname")) {
 #ifdef ENABLE_RPZ_NSDNAME
@@ -47,8 +47,8 @@ main(int argc, char **argv)
 #else
                return (1);
 #endif
-           }
+       }
 
-           fputs(USAGE, stderr);
-           return (1);
+       fputs(USAGE, stderr);
+       return (1);
 }
index d13c32b4502ddddf2110a7ae7c4044cf055293d6..1bc879c78972636bcb6b1bc4ec0d97acad6d81b6 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#! /bin/sh
 #
 # Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
 #
 
 # $Id: setup.sh,v 1.6 2012/01/07 23:46:53 tbox Exp $
 
+set -e
+
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
-. ./clean.sh
 
-#  NO-OP is an obsolete synonym for PASSHTRU
+QPERF=`sh qperf.sh`
+
+sh clean.sh
+
+# set up test policy zones.  bl-2 is used to check competing zones.
+#      bl-{given,disabled,passthru,no-data,nxdomain,cname,wildcard,garden}
+#      are used to check policy overrides in named.conf.
+#      NO-OP is an obsolete synonym for PASSHTRU
 for NM in '' -2 -given -disabled -passthru -no-op -nodata -nxdomain -cname -wildcname -garden; do
     sed -e "/SOA/s/blx/bl$NM/g" ns3/base.db >ns3/bl$NM.db
 done
 
+# sign the root and a zone in ns2
 ../../../tools/genrandom 400 random.data
-$KEYGEN -Kns2 -q -r random.data -3 signed-tld2. > /dev/null 2>&1
-$KEYGEN -Kns2 -q -r random.data -3fk signed-tld2. > /dev/null 2>&1
-$SIGNER -S -Kns2 -o signed-tld2. -f ns2/signed-tld2.db ns2/tld2.db > /dev/null 2>&1
+
+# $1=directory, $2=domain name, $3=input zone file, $4=output file
+signzone () {
+    KEYNAME=`$KEYGEN -q -r random.data -b 512 -K $1 $2`
+    cat $1/$3 $1/$KEYNAME.key > $1/tmp
+    $SIGNER -Pp -K $1 -o $2 -f $1/$4 $1/tmp >/dev/null
+    sed -n -e 's/\(.*\) IN DNSKEY \([0-9]\{1,\} [0-9]\{1,\} [0-9]\{1,\}\) \(.*\)/trusted-keys {"\1" \2 "\3";};/p' $1/$KEYNAME.key >>trusted.conf
+    rm dsset-$2 $1/tmp
+}
+signzone ns2 tld2s. base-tld2s.db tld2s.db
+
+
+# Performance checks.
+# First with rpz off.
+cat <<EOF >ns5/rpz-switch
+response-policy {zone "bl";}
+    recursive-only no
+    max-policy-ttl 90
+    break-dnssec yes;
+EOF
+
+cat <<EOF >ns5/example.db
+\$TTL  120
+@      SOA     .  hostmaster.ns.example. ( 1 3600 1200 604800 60 )
+       NS      ns
+ns     A       10.53.0.5
+EOF
+
+cat <<EOF >ns5/bl.db
+\$TTL  120
+@              SOA     .  hostmaster.ns.blperf. ( 1 3600 1200 604800 60 )
+               NS      ns
+ns             A       10.53.0.5
+
+; used only in failure for "recursive-only no" in #8 test5
+a3-5.tld2      CNAME   *.
+; for "break-dnssec" in #9 test5
+a3-5.tld2s     CNAME   *.
+; for "max-policy-ttl 90" in test5
+a3-17.tld2     500 A   17.17.17.17
+
+; dummy NSDNAME policies to trigger lookups
+ns-1.example.com.rpz-nsdname   CNAME   .
+ns-2.example.com.rpz-nsdname   CNAME   .
+ns-3.example.com.rpz-nsdname   CNAME   .
+ns-4.example.com.rpz-nsdname   CNAME   .
+ns-5.example.com.rpz-nsdname   CNAME   .
+EOF
+
+if test -n "$QPERF"; then
+    # do not build the full zones if we will not use them to avoid the long
+    # time otherwise required to shut down the server
+    $PERL -e 'for ($val = 1; $val <= 65535; ++$val) {
+       printf("host-%d-%d\tA    192.168.%d.%d\n",
+               $val/256, $val%256, $val/256, $val%256);
+       }' >>ns5/example.db
+
+    echo >>ns5/bl.db
+    echo "; rewrite some names" >>ns5/bl.db
+    $PERL -e 'for ($val = 2; $val <= 65535; $val += 69) {
+       printf("host-%d.sub%d.example.com\tCNAME\t.\n", $val/256, $val%256);
+       }' >>ns5/bl.db
+
+    echo >>ns5/bl.db
+    echo "; rewrite with some not entirely trivial patricia trees" >>ns5/bl.db
+    $PERL -e 'for ($val = 3; $val <= 65535; $val += 69) {
+       printf("32.%d.%d.168.192.rpz-ip  \tCNAME\t.\n",
+               $val%256, $val/256);
+       printf("32.%d.%d.168.192.rpz-nsip\tCNAME\t.\n",
+               ($val+1)%256, ($val+1)/256);
+       }' >>ns5/bl.db
+fi
+
+# some psuedo-random queryperf requests
+$PERL -e 'for ($cnt = $val = 1; $cnt <= 2000; ++$cnt) {
+       printf("host-%d.sub%d.example.com A\n", $val%256, $val/256);
+               $val = ($val * 9 + 32771) % 65536;
+       }' >ns5/requests
index 27becfe590754c7031468cd438bb43bc5aec8823..aa885c3ed8965166fc66c90f4f32f913d2d9cce0 100644 (file)
@@ -25,13 +25,13 @@ server 10.53.0.3 5300
 ; QNAME tests
 
 ; NXDOMAIN
+;      2, 20, 25
 update add  a0-1.tld2.bl.      300 CNAME .
-update add  a0-1.signed-tld2.bl.       300 CNAME .
-;
 ; NODATA
+;      3, 21
 update add  a3-1.tld2.bl.      300 CNAME *.
 ; and no assert-botch
-;      5
+;      5, 22
 update add  a3-2.tld2.bl.      300 DNAME example.com.
 ;
 ; NXDOMAIN for a4-2-cname.tld2 via its target a4-2.tld2.
@@ -57,24 +57,32 @@ update add nxc2.sub1.tld2.bl.       300 CNAME a12-cname.tld2.
 ;
 ; prefer the first conflicting zone
 ;      13
-update add a4-4.tld2.bl.       300 A   127.0.0.1
+update add a4-4.tld2.bl.       300 A   127.4.4.1
+update add a6-1.tld2.bl.       300 CNAME a6-1.tld2.
+update add a6-2.tld2.bl.       300 A   127.6.2.1
+update add a6-1.tld2.bl.       300 A   127.6.1.1
+update add a6-2.tld2.bl.       300 CNAME a6-2.tld2.
 send
-update add a4-4.tld2.bl-2.     300 A   127.0.0.2
+update add a4-4.tld2.bl-2.     300 A   127.4.4.2
 send
-;
+
 ; wildcard CNAME
-;      14
+;      16
 update add  a3-6.tld2.bl.      300 CNAME *.tld4.
-;      15
+;      17
 update add  *.sub1.tld2.bl.    300 CNAME *.tld4.
-; CNAME chains
-;      16
+; CNAME chain
+;      18
 update add  a4-5.tld2.bl.      300 A   127.0.0.16
-;      17
+; stop at first hit in CNAME chain
+;      19
 update add  a4-6.tld2.bl.      300 CNAME .
 update add  a4-6-cname.tld2.bl.        300 A   127.0.0.17
-
-;      18
+;
+; assert in rbtdb.c
+;      24
 update add c1.crash2.tld3.bl.  300 CNAME .
-
+; DO=1 without signatures, DO=0 with signatures are rewritten
+;      26 - 27
+update add  a0-1.tld2s.bl.     300 CNAME .
 send
index 3038260f5b8626be6c1654d32dca3d131f794308..2a467af930dda44a2a8fc891e514972bb0119840 100644 (file)
 ;      single requests
 ; Separate update requests for distinct TLDs with blank lines or 'send'
 ; End the file with a blank line or 'send'
+; CNAME targets are absolute even without trailing "."
 
 ; IP tests
 
 server 10.53.0.3 5300
 
 ; NODATA a3-1.tld2
+;      1
 update add  32.1.3.168.192.rpz-ip.bl   300 CNAME *.
 ;
-; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2
+; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2 and a4-2.tld2
+;      4
 update add  24.0.4.168.192.rpz-ip.bl   300 CNAME .
 ;
-; poke hole in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged
+; old passthru in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged
+;      3
 update add  32.1.4.168.192.rpz-ip.bl   300 CNAME 32.1.4.168.192
 ;
 ; NODATA for a4-3.tld2
+;      8
 update add  32.3.4.168.192.rpz-ip.bl   300 CNAME *.
 ;
 ; NXDOMAIN for IPv6 a3-1.tld2
+;      9
 update add  128.1.zz.3.2.2001.rpz-ip.bl        300 CNAME .
 ;
 ; apply the policy with the lexically smallest address of 192.168.5.1
 ; to an RRset of more than one A RR
+;      11
 update add  32.1.5.168.192.rpz-ip.bl   300 A   127.0.0.1
 update add  32.2.5.168.192.rpz-ip.bl   300 A   127.0.0.2
 ;
 ; prefer first conflicting IP zone for a5-3.tld2
+;      12
 update add 32.3.5.168.192.rpz-ip.bl    300 A   127.0.0.1
 send
 update add 32.3.5.168.192.rpz-ip.bl-2  300 A   127.0.0.2
 send
 
 ; prefer QNAME to IP for a5-4.tld2
+;      13
 update add 32.4.5.168.192.rpz-ip.bl    300 CNAME a12.tld2.
 update add a5-4.tld2.bl                        300 CNAME a14.tld4.
 ;
+; poke hole in NXDOMAIN CIDR block to leave a4-4.tld2 unchanged
+;      15
+update add  32.4.4.168.192.rpz-ip.bl   300 CNAME rpz-passthru.
+;
 ; assert in rbtdb.c
 ;      16
 update add 32.16.1.16.172.rpz-ip.bl    300 CNAME .
index 481118e49735ea4f3fe910e4302a232d425cf1a0..a6510d30bde75eb64a4ec13a8f970796d9217574 100644 (file)
@@ -12,7 +12,7 @@
 ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 ; PERFORMANCE OF THIS SOFTWARE.
 
-; $Id: test5,v 1.5 2011/10/13 01:32:33 vjs Exp $
+; $Id: test5,v 1.5.4.1 2012/02/24 17:22:37 vjs Exp $
 
 
 ; Use comment lines instead of blank lines to combine update requests into
 
 server 10.53.0.3 5300
 
+;      1
 update add  a3-1.tld2.bl-given.            300 A 127.0.0.1
 send
+;      2
 update add  a3-2.tld2.bl-passthru.  300 A 127.0.0.2
 send
+;      3
 update add  a3-3.tld2.bl-no-op.            300 A 127.0.0.3
 send
+;      4
 update add  a3-4.tld2.bl-disabled.  300 A 127.0.0.4
 send
+;      5 - 8
 update add  a3-5.tld2.bl-nodata.    300 A 127.0.0.5
+;      9 - 10
+update add  a3-5.tld2s.bl-nodata.   300 A 127.0.0.9
 send
-update add  a3-6.tld2.bl-nxdomain.  300 A 127.0.0.6
+;      11
+update add  a3-6.tld2.bl-nxdomain.  300 A 127.0.0.11
 send
-update add  a3-7.tld2.bl-cname.            300 A 127.0.0.7
+;      12
+update add  a3-7.tld2.bl-cname.            300 A 127.0.0.12
 send
-update add  a3-8.tld2.bl-wildcname. 300 A 127.0.0.8
-update add  *.sub9.tld2.bl-wildcname. 300 A 127.0.1.9
+;      13
+update add  a3-8.tld2.bl-wildcname. 300 A 127.0.0.13
+;      14
+update add  *.sub9.tld2.bl-wildcname. 300 A 127.0.1.14
 send
-update add  a3-10.tld2.bl-garden.    300 A 127.0.0.10
+;      15
+update add  a3-15.tld2.bl-garden.   300 A 127.0.0.15
+send
+;      16
+update add  a3-16.tld2.bl.         300 A 127.0.0.16
 send
index 6d841462597d9aa5fede566937be3cee62df26cb..2df240f762b78992344e46bfffa392a7e580a480 100644 (file)
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
-ns1=10.53.0.1                      # root, defining the other two
-ns2=10.53.0.2                      # server whose answers are rewritten
-ns3=10.53.0.3                      # resolve that does the rewriting
-ns4=10.53.0.4                      # another server that is rewritten
-
-RNDCCMD="$RNDC -c ../common/rndc.conf -s $ns3 -p 9953"
+ns=10.53.0
+ns1=$ns.1                          # root, defining the others
+ns2=$ns.2                          # server whose answers are rewritten
+ns3=$ns.3                          # resolve that does the rewriting
+ns4=$ns.4                          # another server that is rewritten
+ns5=$ns.5                          # check performance with this server
 
 HAVE_CORE=
 
@@ -44,9 +44,18 @@ fi
 trap 'exit 1' 1 2 15
 
 
+RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"
+
 digcmd () {
-    #echo I:dig +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $* 1>&2
-    $DIG +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $*
+    digcmd_args="+noadd +nosearch +time=1 +tries=1 -p 5300 $*"
+    if ! expr "$digcmd_args" : '.*@' >/dev/null; then
+       digcmd_args="$digcmd_args @$ns3"
+    fi
+    if ! expr "$digcmd_args" : '.*+[no]*auth' >/dev/null; then
+       digcmd_args="+noauth $digcmd_args"
+    fi
+    #echo I:dig $digcmd_args 1>&2
+    $DIG $digcmd_args
 }
 
 # set DIGNM=file name for dig output
@@ -77,20 +86,41 @@ load_db () {
 }
 
 restart () {
-    $RNDCCMD stop >/dev/null 2>&1
-    rm -f ns3/*.jnl
-    for NM in ns3/bl*.db; do
-       cp -f ns3/base.db $NM
-    done
-    (cd ..; $PERL start.pl --noclean --restart rpz ns3)
+    # try to ensure that the server really has stopped
+    # and won't mess with ns$1/name.pid
+    if test -z "$HAVE_CORE" -a -f ns$1/named.pid; then
+       $RNDCCMD $ns$1 halt >/dev/null 2>&1
+       if test -f ns$1/named.pid; then
+           sleep 1
+           PID=`cat ns$1/named.pid 2>/dev/null`
+           if test -n "$PID"; then
+               echo "I:killing ns$1 server $PID"
+               kill -9 $PID
+           fi
+       fi
+    fi
+    rm -f ns$1/*.jnl
+    if test -f ns$1/base.db; then
+       for NM in ns$1/bl*.db; do
+           cp -f ns$1/base.db $NM
+       done
+    fi
+    $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns$1
     load_db
 }
 
+# $1=server and irrelevant args  $2=error message
 ckalive () {
-    $RNDCCMD status >/dev/null 2>&1 && return 0
+    CKALIVE_NS=`expr "$1" : '.*@ns\([1-9]\).*'`
+    if test -z "$CKALIVE_NS"; then
+       CKALIVE_NS=3
+    fi
+    eval CKALIVE_IP=\$ns$CKALIVE_NS
+    $RNDCCMD $CKALIVE_IP status >/dev/null 2>&1 && return 0
     HAVE_CORE=yes
-    setret "$1"
-    restart
+    setret "$2"
+    # restart the server to avoid stalling waiting for it to stop
+    restart $CKALIVE_NS
     return 1
 }
 
@@ -113,15 +143,29 @@ end_group () {
        sed -e 's/[      ]add[   ]/ delete /' $TEST_FILE | $NSUPDATE
        TEST_FILE=
     fi
+    ckalive $ns3 "I:failed; ns3 server crashed and restarted"
+    if test "$status" -eq 0; then
+       # look for complaints from rpz.c
+       EMSGS=`grep -l 'invalid rpz' */*.run`
+       if test -n "$EMSGS"; then
+           setret "I:'invalid rpz' complaints in $EMSGS starting with:"
+           grep 'invalid rpz' */*.run | sed -e '4,$d' -e 's/^/I:    /'
+       fi
+       # look for complaints from rpz.c and query.c
+       EMSGS=`grep -l 'rpz .*failed' */*.run`
+       if test -n "$EMSGS"; then
+           setret "I:'rpz failed' complaints in $EMSGS starting with:"
+           grep 'rpz .*failed' */*.run | sed -e '4,$d' -e 's/^/I:    /'
+       fi
+    fi
     status=`expr $status + $ret`
-    ckalive "I:failed; server crashed"
     GROUP_NM=
 }
 
 # $1=dig args $2=other dig output file
 ckresult () {
-    #ckalive "I:server crashed by 'dig $1'" || return 1
-    if $PERL ../digcomp.pl $DIGNM $2 >/dev/null; then
+    #ckalive "$1" "I:server crashed by 'dig $1'" || return 1
+    if $PERL $SYSTEMTESTTOP/digcomp.pl $DIGNM $2 >/dev/null; then
        rm -f ${DIGNM}*
        return 0
     fi
@@ -132,8 +176,8 @@ ckresult () {
 # check only that the server does not crash
 # $1=target domain  $2=optional query type
 nocrash () {
-    digcmd $* @$ns3 >/dev/null
-    ckalive "I:server crashed by 'dig $*'"
+    digcmd $* >/dev/null
+    ckalive "$*" "I:server crashed by 'dig $*'"
 }
 
 
@@ -141,8 +185,10 @@ nocrash () {
 # $1=target domain  $2=optional query type
 nxdomain () {
     make_dignm
-    digcmd +noauth $* @$ns3                                            \
-       | sed -e 's/^[a-z].*    IN      CNAME   /;xxx &/' >$DIGNM
+    digcmd $*                                                          \
+       | sed -e 's/^[a-z].*    IN      CNAME   /;xxx &/'               \
+               -e 's/^[a-z].*  IN      RRSIG   /;xxx &/'               \
+           >$DIGNM
     ckresult "$*" proto.nxdomain
 }
 
@@ -150,33 +196,37 @@ nxdomain () {
 # $1=target domain  $2=optional query type
 nodata () {
     make_dignm
-    digcmd +noauth $* @$ns3                                            \
+    digcmd $*                                                          \
        | sed -e 's/^[a-z].*    IN      CNAME   /;xxx &/' >$DIGNM
     ckresult "$*" proto.nodata
 }
 
 # check rewrite to an address
 #   modify the output so that it is easily compared, but save the original line
-# $1=IPv4 address, $2=target domain  $3=optional query type
+# $1=IPv4 address  $2=digcmd args  $3=optional TTL
 addr () {
     ADDR=$1
-    shift
-    ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'`
     make_dignm
-    digcmd +noauth $* @$ns3 >$DIGNM
-    #ckalive "I:server crashed by 'dig $*'" || return
-    if grep -i '^[a-z].*       A       '"$ADDR_ESC"'$' $DIGNM >/dev/null; then
-       rm -f ${DIGNM}*
-       return 0
+    digcmd $2 >$DIGNM
+    #ckalive "$2" "I:server crashed by 'dig $2'" || return 1
+    ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'`
+    ADDR_TTL=`sed -n -e  "s/^[-.a-z0-9]\{1,\}  *\([0-9]*\)     IN      A\{1,4\}        ${ADDR_ESC}\$/\1/p" $DIGNM`
+    if test -z "$ADDR_TTL"; then
+       setret "I:'dig $2' wrong; no address $ADDR record in $DIGNM"
+       return 1
     fi
-    setret "I:'dig $*' wrong; no A $ADDR record in $DIGNM $2"
+    if test -n "$3" && test "$ADDR_TTL" -ne "$3"; then
+       setret "I:'dig $2' wrong; TTL=$ADDR_TTL instead of $3 in $DIGNM"
+       return 1
+    fi
+    rm -f ${DIGNM}*
 }
 
 # check that a response is not rewritten
 # $1=target domain  $2=optional query type
 nochange () {
     make_dignm
-    digcmd $* @$ns3 >$DIGNM
+    digcmd $* >$DIGNM
     digcmd $* @$ns2 >${DIGNM}_OK
     ckresult "$*" ${DIGNM}_OK && rm -f ${DIGNM}_OK
 }
@@ -185,23 +235,23 @@ nochange () {
 here () {
     make_dignm
     sed -e 's/^[        ]*//' >${DIGNM}_OK
-    digcmd $* @$ns3 >$DIGNM
+    digcmd $* >$DIGNM
     ckresult "$*" ${DIGNM}_OK
 }
 
 # make prototype files to check against rewritten results
-digcmd +noauth nonexistent @$ns2 >proto.nxdomain
-digcmd +noauth txt-only.tld2 @$ns2 >proto.nodata
+digcmd nonexistent @$ns2 >proto.nxdomain
+digcmd txt-only.tld2 @$ns2 >proto.nodata
 
 
 status=0
 
 start_group "QNAME rewrites" test1
-nochange .
-nxdomain a0-1.tld2
-nodata a3-1.tld2
-nodata a3-2.tld2
-nodata sub.a3-2.tld2                   # 5 no crash on DNAME
+nochange .                             # 1 do not crash or rewrite root
+nxdomain a0-1.tld2                     # 2
+nodata a3-1.tld2                       # 3
+nodata a3-2.tld2                       # 4 no crash on DNAME
+nodata sub.a3-2.tld2
 nxdomain a4-2.tld2                     # 6 rewrite based on CNAME target
 nxdomain a4-2-cname.tld2               # 7
 nodata a4-3-cname.tld2                 # 8
@@ -209,32 +259,43 @@ addr 12.12.12.12  a4-1.sub1.tld2  # 9 A replacement
 addr 12.12.12.12  a4-1.sub2.tld2       # 10 A replacement with wildcard
 addr 12.12.12.12  nxc1.sub1.tld2       # 11 replace NXDOMAIN with CNAME
 addr 12.12.12.12  nxc2.sub1.tld2       # 12 replace NXDOMAIN with CNAME chain
-addr 127.0.0.1   a4-4.tld2             # 13 prefer 1st conflicting QNAME zone
-addr 56.56.56.56  a3-6.tld2            # 14 wildcard CNAME
-addr 57.57.57.57  a3-7.sub1.tld2       # 15 wildcard CNAME
-addr 127.0.0.16          a4-5-cname3.tld2      # 16 CNAME chain
-addr 127.0.0.17          a4-6-cname3.tld2      # 17 stop short in CNAME chain
-nxdomain c1.crash2.tld3                        # 18 assert in rbtdb.c
-nochange a0-1.tld2      +norecurse
-nxdomain a0-1.tld2      +dnssec
-nxdomain a0-1.signed-tld2
-nochange a0-1.signed-tld2       +dnssec
+addr 127.4.4.1   a4-4.tld2             # 13 prefer 1st conflicting QNAME zone
+nochange a6-1.tld2                     # 14
+addr 127.6.2.1   a6-2.tld2             # 15
+addr 56.56.56.56  a3-6.tld2            # 16 wildcard CNAME
+addr 57.57.57.57  a3-7.sub1.tld2       # 17 wildcard CNAME
+addr 127.0.0.16          a4-5-cname3.tld2      # 18 CNAME chain
+addr 127.0.0.17          a4-6-cname3.tld2      # 19 stop short in CNAME chain
+nochange a0-1.tld2         +norecurse  # 20 check that RD=1 is required
+nochange a3-1.tld2         +norecurse  # 21
+nochange a3-2.tld2         +norecurse  # 22
+nochange sub.a3-2.tld2     +norecurse  # 23
+nxdomain c1.crash2.tld3                        # 24 assert in rbtdb.c
+nxdomain a0-1.tld2         +dnssec     # 25 simple DO=1 without signatures
+nxdomain a0-1.tld2s                    # 26 simple DO=0 with signatures
+nochange a0-1.tld2s        +dnssec     # 27 simple DO=1 with signatures
+nxdomain a0-1s-cname.tld2s  +dnssec    # 28 DNSSEC too early in CNAME chain
+nochange a0-1-scname.tld2   +dnssec    # 29 DNSSEC on target in CNAME chain
+nochange a0-1.tld2s srv +auth +dnssec  # 30 no write for +DNSSEC and no record
+nxdomain a0-1.tld2s srv                        # 31
 end_group
 
 start_group "IP rewrites" test2
-nodata a3-1.tld2
-nochange a3-2.tld2
-nochange a4-1.tld2
-nxdomain a4-2.tld2
-nochange a4-2.tld2 -taaaa
-nochange a4-2.tld2 -ttxt
-nxdomain a4-2.tld2 -tany
-nodata a4-3.tld2
-nxdomain a3-1.tld2 -tAAAA
-nochange a4-1-aaaa.tld2 -tAAAA
+nodata a3-1.tld2                       # 1 NODATA
+nochange a3-2.tld2                     # 2 no policy record so no change
+nochange a4-1.tld2                     # 3 obsolete PASSTHRU record style
+nxdomain a4-2.tld2                     # 4
+nochange a4-2.tld2 -taaaa              # 5 no A => no policy rewrite
+nochange a4-2.tld2 -ttxt               # 6 no A => no policy rewrite
+nxdomain a4-2.tld2 -tany               # 7 no A => no policy rewrite
+nodata a4-3.tld2                       # 8
+nxdomain a3-1.tld2 -taaaa              # 9 IPv6 policy
+nochange a4-1-aaaa.tld2 -taaaa         # 10
 addr 127.0.0.1  a5-1-2.tld2            # 11 prefer smallest policy address
 addr 127.0.0.1  a5-3.tld2              # 12 prefer first conflicting IP zone
 addr 14.14.14.14 a5-4.tld2             # 13 prefer QNAME to IP
+nochange a5-4.tld2         +norecurse  # 14 check that RD=1 is required
+nochange a4-4.tld2                     # 15 PASSTHRU
 nxdomain c2.crash2.tld3                        # 16 assert in rbtdb.c
 end_group
 
@@ -256,7 +317,7 @@ end_group
 if ./rpz nsdname; then
     start_group "NSDNAME rewrites" test3
     nochange a3-1.tld2
-    nochange a3-1.tld2 +dnssec         # 2 this once caused problems
+    nochange a3-1.tld2     +dnssec     # 2 this once caused problems
     nxdomain a3-1.sub1.tld2            # 3 NXDOMAIN *.sub1.tld2 by NSDNAME
     nxdomain a3-1.subsub.sub1.tld2
     nxdomain a3-1.subsub.sub1.tld2 -tany
@@ -284,21 +345,29 @@ else
 fi
 
 # policies in ./test5 overridden by response-policy{} in ns3/named.conf
+#   and in ns5/named.conf
 start_group "policy overrides" test5
 addr 127.0.0.1 a3-1.tld2               # 1 bl-given
 nochange a3-2.tld2                     # 2 bl-passthru
 nochange a3-3.tld2                     # 3 bl-no-op    obsolete for passthru
 nochange a3-4.tld2                     # 4 bl-disabled
 nodata a3-5.tld2                       # 5 bl-nodata
-nxdomain a3-6.tld2                     # 6 bl-nxdomain
-here +noauth a3-7.tld2 -tany <<'EOF'   # 7 bl_cname
+nodata a3-5.tld2    +norecurse         # 6 bl-nodata       recursive-only no
+nodata a3-5.tld2                       # 7 bl-nodata
+nodata a3-5.tld2    +norecurse @$ns5   # 8 bl-nodata       recursive-only no
+nodata a3-5.tld2s              @$ns5   # 9 bl-nodata
+nodata a3-5.tld2s   +dnssec    @$ns5   # 10 bl-nodata      break-dnssec
+nxdomain a3-6.tld2                     # 11 bl-nxdomain
+here a3-7.tld2 -tany <<'EOF'
     ;; status: NOERROR, x
-    a3-7.tld2.     300 IN      CNAME   txt-only.tld2.
-    txt-only.tld2.  120 IN     TXT     "txt-only-tld2"
+    a3-7.tld2.     x   IN      CNAME   txt-only.tld2.
+    txt-only.tld2.  x  IN      TXT     "txt-only-tld2"
 EOF
-addr 58.58.58.58 a3-8.tld2             # 8 bl_wildcname
-addr 59.59.59.59 a3-9.sub9.tld2                # 9 bl_wildcname
-addr 12.12.12.12 a3-10.tld2            # 10 bl-garden
+addr 58.58.58.58 a3-8.tld2             # 13 bl_wildcname
+addr 59.59.59.59 a3-9.sub9.tld2                # 14 bl_wildcname
+addr 12.12.12.12 a3-15.tld2            # 15 bl-garden  via CNAME to a12.tld2
+addr 127.0.0.16 a3-16.tld2         100 # 16 bl             max-policy-ttl 100
+addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl         max-policy-ttl 90
 end_group
 
 # check that miscellaneous bugs are still absent
@@ -312,12 +381,61 @@ for Q in RRSIG SIG ANY 'ANY +dnssec'; do
 done
 end_group
 
-# restart the server to see if that creates a core file
+
+# superficial test for major performance bugs
+QPERF=`sh qperf.sh`
+if test -n "$QPERF"; then
+    perf () {
+       echo "I:checking performance $1"
+       # don't measure the costs of -d99
+       $RNDCCMD $ns5 notrace >/dev/null
+       $QPERF -1 -l2 -d ns5/requests -s $ns5 -p 5300 >ns5/$2.perf
+       ckalive $ns5 "I:failed; server #5 crashed"
+    }
+    trim () {
+       sed -n -e 's/.*Queries per second: *\([0-9]*\).*/\1/p' ns5/$1.perf
+    }
+
+    # Dry run to prime disk cache
+    #  Otherwise a first test of either flavor is 25% low
+    perf 'to prime disk cache' rpz
+
+    # get queries/second with rpz
+    perf 'with rpz' rpz
+
+    # turn off rpz and measure queries/second again
+    # Don't wait for a clean stop.  Clean stops of this server need seconds
+    # until the sockets are close.  5 or 10 seconds after that, the
+    # server really stops and deletes named.pid.
+    echo "# rpz off" >ns5/rpz-switch
+    PID=`cat ns5/named.pid`
+    test -z "$PID" || kill -9 "$PID"
+    $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns5
+    perf 'without rpz' norpz
+
+    NORPZ=`trim norpz`
+    RPZ=`trim rpz`
+    echo "I:$RPZ qps with RPZ versus $NORPZ qps without"
+
+    # fail if RPZ costs more than 100%
+    NORPZ2=`expr "$NORPZ" / 2`
+    if test "$RPZ" -le "$NORPZ2"; then
+       echo "I:rpz $RPZ qps too far below non-RPZ $NORPZ qps"
+       status=`expr $status + 1`
+    fi
+else
+    echo "I:performance not checked; queryperf not available"
+fi
+
+
+# restart the main test RPZ server to see if that creates a core file
 if test -z "$HAVE_CORE"; then
-    $RNDCCMD halt
-    restart
-    test -s ns3/named.core && setret "I:found stray core file; memory leak?"
+    $PERL $SYSTEMTESTTOP/stop.pl . ns3
+    restart 3
+    HAVE_CORE=`find ns* -name '*core*' -print`
+    test -z "$HAVE_CORE" || setret "I:found $HAVE_CORE; memory leak?"
 fi
 
+
 echo "I:exit status: $status"
 exit $status
index 698e108e37177370349bb9d97ef597a32bcb80e5..252f18bb02896df732e0982e6f599503d95dd058 100644 (file)
@@ -5334,7 +5334,11 @@ badresp:1,adberr:0,findfail:0,valfail:0]
     <optional> resolver-query-timeout <replaceable>number</replaceable> ; </optional>
     <optional> deny-answer-addresses { <replaceable>address_match_list</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
     <optional> deny-answer-aliases { <replaceable>namelist</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
-    <optional> response-policy { <replaceable>zone_name</replaceable> <optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional> ; } ; </optional>
+    <optional> response-policy { <replaceable>zone_name</replaceable>
+       <optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional>
+       <optional> recursive-only <replaceable>yes_or_no</replaceable> </optional> <optional> max-policy-ttl <replaceable>number</replaceable> </optional> ;
+    } <optional> recursive-only <replaceable>yes_or_no</replaceable> </optional> <optional> max-policy-ttl <replaceable>number</replaceable> </optional>
+       <optional> break-dnssec <replaceable>yes_or_no</replaceable> </optional> ; </optional>
 };
 </programlisting>
 
@@ -9479,17 +9483,15 @@ deny-answer-aliases { "example.net"; };
         <sect3>
          <title>Response Policy Zone (RPZ) Rewriting</title>
          <para>
-           <acronym>BIND</acronym> 9 includes an intentionally limited
-           mechanism to modify DNS responses for recursive requests
-           somewhat similar to email anti-spam DNS blacklists.
+           <acronym>BIND</acronym> 9 includes a limited
+           mechanism to modify DNS responses for requests
+           analogous to email anti-spam DNS blacklists.
            Responses can be changed to deny the existence of domains(NXDOMAIN),
            deny the existence of IP addresses for domains (NODATA),
            or contain other IP addresses or data.
          </para>
 
          <para>
-           The actions encoded in a response policy zone (RPZ) are applied
-           only to queries that ask for recursion (RD=1).
            Response policy zones are named in the
            <command>response-policy</command> option for the view or among the
            global options if there is no response-policy option for the view.
@@ -9500,22 +9502,21 @@ deny-answer-aliases { "example.net"; };
          </para>
 
          <para>
-           There are four kinds of RPZ records, QNAME, IP, NSIP,
+           Four policy triggers are encoded in RPZ records, QNAME, IP, NSIP,
            and NSDNAME.
-           QNAME records are applied to query names of requests and targets
+           QNAME RPZ records triggered by query names of requests and targets
            of CNAME records resolved to generate the response.
            The owner name of a QNAME RPZ record is the query name relativized
            to the RPZ.
          </para>
 
          <para>
-           The second kind of RPZ record, an IP policy record,
-           is triggered by addresses in A and AAAA records
-           for the ANSWER sections of responses.
-           IP policy records have owner names that are
-           subdomains of <userinput>rpz-ip</userinput> relativized to the
-           RPZ origin name and encode an IP address or address block.
-           IPv4 addresses are encoded as
+           The second kind of RPZ trigger is an IP address in an A and AAAA
+           record in the ANSWER section of a response.
+           IP address triggers are encoded in records that have owner names
+           that are subdomains of <userinput>rpz-ip</userinput> relativized
+           to the RPZ origin name and encode an IP address or address block.
+           IPv4 trigger addresses are represented as
            <userinput>prefixlength.B4.B3.B2.B1.rpz-ip</userinput>.
            The prefix length must be between 1 and 32.
            All four bytes, B4, B3, B2, and B1, must be present.
@@ -9534,43 +9535,45 @@ deny-answer-aliases { "example.net"; };
          </para>
 
          <para>
-           NSDNAME policy records match names of authoritative servers
-           for the query name, a parent of the query name, a CNAME,
-           or a parent of a CNAME.
+           NSDNAME triggers match names of authoritative servers
+           for the query name, a parent of the query name, a CNAME for
+           query name, or a parent of a CNAME.
            They are encoded as subdomains of
            <userinput>rpz-nsdomain</userinput> relativized
            to the RPZ origin name.
          </para>
 
          <para>
-           NSIP policy records match IP addresses in A and AAAA RRsets
-           for domains that can be checked against NSDNAME policy records.
-           The are encoded like IP policies except as subdomains of
+           NSIP triggers match IP addresses in A and
+           AAAA RRsets for domains that can be checked against NSDNAME
+           policy records.
+           NSIP triggers are encoded like IP triggers except as subdomains of
            <userinput>rpz-nsip</userinput>.
          </para>
 
          <para>
            The query response is checked against all RPZs, so
-           two or more policy records can apply to a single response.
-           Because DNS responses can be rewritten according by at most a
-           single policy record, a single policy (other than
-           <command>DISABLED</command> policies) must be chosen.
-           Policies are chosen in the following order:
+           two or more policy records can be triggered by a response.
+           Because DNS responses can be rewritten according to at most one
+           policy record, a single record encoding an action (other than
+           <command>DISABLED</command> actions) must be chosen.
+           Triggers or the records that encode them are chosen in
+           the following order:
            <itemizedlist>
-             <listitem>Among applicable zones, use the RPZ that appears first
-               in the response-policy option.
+             <listitem>Choose the triggered record in the zone that appears
+               first in the response-policy option.
              </listitem>
-             <listitem>Prefer QNAME to IP to NSDNAME to NSIP policy records
-               in a single RPZ
+             <listitem>Prefer QNAME to IP to NSDNAME to NSIP triggers
+               in a single zone.
              </listitem>
-             <listitem>Among applicable NSDNAME policy records, prefer the
-               policy record that matches the lexically smallest name
+             <listitem>Among NSDNAME triggers, prefer the
+               trigger that matches the smallest name under the DNSSEC ordering.
              </listitem>
-             <listitem>Among IP or NSIP policy records, prefer the record
+             <listitem>Among IP or NSIP triggers, prefer the trigger
                with the longest prefix.
              </listitem>
-             <listitem>Among records with the same prefex length,
-               prefer the IP or NSIP policy record that matches
+             <listitem>Among triggers with the same prefex length,
+               prefer the IP or NSIP trigger that matches
                the smallest IP address.
              </listitem>
            </itemizedlist>
@@ -9578,8 +9581,8 @@ deny-answer-aliases { "example.net"; };
 
          <para>
            When the processing of a response is restarted to resolve
-           DNAME or CNAME records and an applicable policy record set has
-           not been found,
+           DNAME or CNAME records and a policy record set has
+           not been triggered,
            all RPZs are again consulted for the DNAME or CNAME names
            and addresses.
          </para>
@@ -9596,55 +9599,56 @@ deny-answer-aliases { "example.net"; };
          </para>
 
          <para>
-           RPZ record sets are special CNAME records or one or more
-           of any types of DNS record except DNAME or DNSSEC.
-           Except when a policy record is a CNAME, there can be more
-           more than one record and more than one type
-           in a set of policy records.
-           Except for three kinds of CNAME records that are illegal except
-           in policy zones, the records in a set are used in the response as if
-           their owner name were the query name.  They are copied to the
-           response as dictated by their types.
+           RPZ record sets are sets of any types of DNS record except
+           DNAME or DNSSEC that encode actions or responses to queries.
            <itemizedlist>
-             <listitem>A CNAME whose target is the root domain (.)
-               specifies the <command>NXDOMAIN</command> policy,
-               which generates an NXDOMAIN response.
+             <listitem>The <command>NXDOMAIN</command> response is encoded
+               by a CNAME whose target is the root domain (.)
              </listitem>
              <listitem>A CNAME whose target is the wildcard top-level
-               domain (*.) specifies the <command>NODATA</command> policy,
+               domain (*.) specifies the <command>NODATA</command> action,
                which rewrites the response to NODATA or ANCOUNT=1.
              </listitem>
-             <listitem>A CNAME whose target is a wildcard hostname such
-               as *.example.com is used normally after the astrisk (*)
+             <listitem>The <command>Local Data</command> action is
+               represented by a set ordinary DNS records that are used
+               to answer queries.  Queries for record types not the
+               set are answered with NODATA.
+
+               A special form of local data is a CNAME whose target is a
+               wildcard such as *.example.com.
+               It is used as if were an ordinary CNAME after the astrisk (*)
                has been replaced with the query name.
-               These records are usually resolved with ordinary CNAMEs
-               outside the policy zones.  They can be useful for logging.
+               The purpose for this special form is query logging in the
+               walled garden's authority DNS server.
              </listitem>
              <listitem>The <command>PASSTHRU</command> policy is specified
-               by a CNAME whose target is the variable part of its own
-               owner name.  It causes the response to not be rewritten
+               by a CNAME whose target is <command>rpz_passthru.</command>
+               It causes the response to not be rewritten
                and is most often used to "poke holes" in policies for
                CIDR blocks.
+               (A CNAME whose target is the variable part of its owner name
+               is an obsolete specification of the PASSTHRU policy.)
              </listitem>
            </itemizedlist>
          </para>
 
          <para>
-           The policies specified in individual records
-           in an RPZ can be overridden with a <command>policy</command> clause
-           in the <command>response-policy</command> option.
+           The actions specified in an RPZ can be overridden with a
+           <command>policy</command> clause in the
+           <command>response-policy</command> option.
            An organization using an RPZ provided by another organization might
            use this mechanism to redirect domains to its own walled garden.
            <itemizedlist>
-             <listitem><command>GIVEN</command> says "do not override."
+             <listitem><command>GIVEN</command> says "do not override but
+               perform the action specified in the zone."
              </listitem>
              <listitem><command>DISABLED</command> causes policy records to do
                nothing but log what they might have done.
                The response to the DNS query will be written according to
-               any matching policy records that are not disabled.
-               Policy zones overridden with <command>DISABLED</command> should
-               appear first, because they will often not be logged
-               if a higher precedence policy is found first.
+               any triggered policy records that are not disabled.
+               Disabled policy zones should appear first,
+               because they will often not be logged
+               if a higher precedence trigger is found first.
              </listitem>
              <listitem><command>PASSTHRU</command> causes all policy records
                to act as if they were CNAME records with targets the variable
@@ -9663,6 +9667,37 @@ deny-answer-aliases { "example.net"; };
            </itemizedlist>
          </para>
 
+         <para>
+           By default, the actions encoded in an RPZ are applied
+           only to queries that ask for recursion (RD=1).
+           That default can be changed for a single RPZ or all RPZs in a view
+           with a <command>recursive-only no</command> clause.
+           This feature is useful for serving the same zone files
+           both inside and outside an RFC 1918 cloud and using RPZ to
+           delete answers that would otherwise contain RFC 1918 values
+           on the externally visible name server or view.
+         </para>
+
+         <para>
+           Also by default, RPZ actions are applied only to DNS requests that
+           either do not request DNSSEC metadata (DO=0) or when no DNSSEC
+           records are available for request name in the original zone (not
+           the response policy zone).
+           This default can be changed for all RPZs in a view with a
+           <command>break-dnssec yes</command> clause.
+           In that case, RPZ actions are applied regardless of DNSSEC.
+           The name of the clause option reflects the fact that results
+           rewritten by RPZ actions cannot verify.
+         </para>
+
+         <para>
+           The TTL of a record modified by RPZ policies is set from the
+           TTL of the relevant record in policy zone.  It is then limited
+           to a maximum value.
+           The <command>max-policy-ttl</command> clause changes that
+           maximum from its default of 5.
+         </para>
+
          <para>
            For example, you might use this option statement
           </para>
@@ -9685,7 +9720,7 @@ bad.domain.com          A       10.0.0.1        ; redirect to a walled garden
                         AAAA    2001:2::1
 
 ; do not rewrite (PASSTHRU) OK.DOMAIN.COM
-ok.domain.com           CNAME   ok.domain.com.
+ok.domain.com           CNAME   rpz-passthru.
 
 bzone.domain.com        CNAME   garden.example.com.
 
@@ -9695,7 +9730,7 @@ bzone.domain.com        CNAME   garden.example.com.
 
 ; IP policy records that rewrite all answers for 127/8 except 127.0.0.1
 8.0.0.0.127.rpz-ip      CNAME   .
-32.1.0.0.127.rpz-ip     CNAME   32.1.0.0.127.   ; PASSTHRU for 127.0.0.1
+32.1.0.0.127.rpz-ip     CNAME   rpz-passthru.
 
 ; NSDNAME and NSIP policy records
 ns.domain.com.rpz-nsdname   CNAME   .
index 6a3307770471d75b0835192964697837f2b5f9c2..f02a9f911e704e96d9ffc63478c241647178b4d0 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.c,v 1.99 2011/10/13 01:32:33 vjs Exp $ */
+/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */
 
 /*! \file */
 
@@ -1034,14 +1034,13 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
                (db->methods->rpz_enabled)(db, st);
 }
 
-isc_result_t
+void
 dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
                   dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
                   dns_rdataset_t *ardataset, dns_rpz_st_t *st,
                   dns_name_t *query_qname)
 {
-       if (db->methods->rpz_findips == NULL)
-               return (ISC_R_NOTIMPLEMENTED);
-       return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
-                                          ardataset, st, query_qname));
+       if (db->methods->rpz_findips != NULL)
+               (db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
+                                          ardataset, st, query_qname);
 }
index 16faa3353e4b0f6adb19542038b5bb01c1b74c32..b9d88af536a878d3ce2dce1bfb5f6b167c063c62 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.107 2011/10/13 01:32:34 vjs Exp $ */
+/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */
 
 #ifndef DNS_DB_H
 #define DNS_DB_H 1
@@ -174,7 +174,7 @@ typedef struct dns_dbmethods {
        isc_boolean_t   (*isdnssec)(dns_db_t *db);
        dns_stats_t     *(*getrrsetstats)(dns_db_t *db);
        void            (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st);
-       isc_result_t    (*rpz_findips)(dns_rpz_zone_t *rpz,
+       void            (*rpz_findips)(dns_rpz_zone_t *rpz,
                                       dns_rpz_type_t rpz_type,
                                       dns_zone_t *zone, dns_db_t *db,
                                       dns_dbversion_t *version,
@@ -1578,7 +1578,7 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
  * DNS_RPZ_TYPE_NSDNAME records.
  */
 
-isc_result_t
+void
 dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
                   dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
                   dns_rdataset_t *ardataset, dns_rpz_st_t *st,
@@ -1595,10 +1595,6 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
  * \li 'ardataset' is an A or AAAA rdataset of addresses to check
  * \li 'found' specifies the previous best match if any or
  *         or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_UNEXPECTED
  */
 
 ISC_LANG_ENDDECLS
index accec2abe628946207d0200ee55c3a37021c930f..84f792902c99f96ca7fc99d424a2f9dcaee4b448 100644 (file)
@@ -30,6 +30,7 @@ ISC_LANG_BEGINDECLS
 #define DNS_RPZ_IP_ZONE                "rpz-ip"
 #define DNS_RPZ_NSIP_ZONE      "rpz-nsip"
 #define DNS_RPZ_NSDNAME_ZONE   "rpz-nsdname"
+#define DNS_RPZ_PASSTHRU_ZONE  "rpz-passthru"
 
 typedef isc_uint8_t            dns_rpz_cidr_bits_t;
 
@@ -66,11 +67,14 @@ typedef struct dns_rpz_zone dns_rpz_zone_t;
 
 struct dns_rpz_zone {
        ISC_LINK(dns_rpz_zone_t) link;
-       int                      num;
+       int                      num;     /* ordinal in list of policy zones */
        dns_name_t               origin;  /* Policy zone name */
        dns_name_t               nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
-       dns_rpz_policy_t         policy;  /* DNS_RPZ_POLICY_GIVEN or override */
+       dns_name_t               passthru;/* DNS_RPZ_PASSTHRU_ZONE. */
        dns_name_t               cname;   /* override value for ..._CNAME */
+       dns_ttl_t                max_policy_ttl;
+       dns_rpz_policy_t         policy;  /* DNS_RPZ_POLICY_GIVEN or override */
+       isc_boolean_t            recursive_only; 
 };
 
 /*
@@ -143,6 +147,7 @@ typedef struct {
 } dns_rpz_st_t;
 
 #define DNS_RPZ_TTL_DEFAULT            5
+#define DNS_RPZ_MAX_TTL_DEFAULT                DNS_RPZ_TTL_DEFAULT
 
 /*
  * So various response policy zone messages can be turned up or down.
@@ -152,6 +157,7 @@ typedef struct {
 #define DNS_RPZ_DEBUG_LEVEL1   ISC_LOG_DEBUG(1)
 #define DNS_RPZ_DEBUG_LEVEL2   ISC_LOG_DEBUG(2)
 #define DNS_RPZ_DEBUG_LEVEL3   ISC_LOG_DEBUG(3)
+#define DNS_RPZ_DEBUG_QUIET    (DNS_RPZ_DEBUG_LEVEL3+1)
 
 const char *
 dns_rpz_type2str(dns_rpz_type_t type);
@@ -192,7 +198,8 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
                  dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix);
 
 dns_rpz_policy_t
-dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname);
+dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
+                    dns_name_t *selfname);
 
 ISC_LANG_ENDDECLS
 
index b9a951f59c9d05c7f84c8255bb563aba31480189..00127d1a07ff994395f25843cb3e8f3d89843a19 100644 (file)
@@ -164,6 +164,8 @@ struct dns_view {
        dns_dns64list_t                 dns64;
        unsigned int                    dns64cnt;
        ISC_LIST(dns_rpz_zone_t)        rpz_zones;
+       isc_boolean_t                   rpz_recursive_only;
+       isc_boolean_t                   rpz_break_dnssec;
 
        /*
         * Configurable data for server use only,
index b78a6249d22a57b6f106ccd454142c7aa52825e7..222df68a1a18522088ddc3ee16b3260105800ea9 100644 (file)
@@ -4605,7 +4605,7 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
  * configured earlier than this policy zone and does not have a higher
  * precedence type.
  */
-static isc_result_t
+static void
 rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
            dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
            dns_rdataset_t *ardataset, dns_rpz_st_t *st,
@@ -4630,7 +4630,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
 
        if (rbtdb->rpz_cidr == NULL) {
                RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-               return (ISC_R_UNEXPECTED);
+               return;
        }
 
        dns_fixedname_init(&selfnamef);
@@ -4692,7 +4692,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
                        dns_name_format(qname, namebuf, sizeof(namebuf));
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
                                      DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
-                                     "rpz_findips findnode(%s): %s",
+                                     "rpz_findips findnode(%s) failed: %s",
                                      namebuf, isc_result_totext(result));
                        continue;
                }
@@ -4713,7 +4713,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
                        if (zrdataset.type != dns_rdatatype_cname) {
                                rpz_policy = DNS_RPZ_POLICY_RECORD;
                        } else {
-                               rpz_policy = dns_rpz_decode_cname(&zrdataset,
+                               rpz_policy = dns_rpz_decode_cname(rpz,
+                                                                 &zrdataset,
                                                                  selfname);
                                if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
                                    rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
@@ -4771,7 +4772,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
                st->m.type = rpz_type;
                st->m.prefix = prefix;
                st->m.policy = rpz_policy;
-               st->m.ttl = ttl;
+               st->m.ttl = ISC_MIN(ttl, rpz->max_policy_ttl);
                st->m.result = result;
                dns_name_copy(qname, st->qname, NULL);
                if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
@@ -4788,7 +4789,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
        }
 
        RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-       return (ISC_R_SUCCESS);
 }
 #endif
 
index e3f49897865dd6acdc51fbd0ccd8ef5ae58f9321..78658590ae480521795f20d84bb102615e476825 100644 (file)
@@ -118,9 +118,9 @@ struct dns_rpz_cidr {
        isc_mem_t               *mctx;
        isc_boolean_t           have_nsdname;   /* zone has NSDNAME record */
        dns_rpz_cidr_node_t     *root;
-       dns_name_t              ip_name;        /* RPZ_IP_ZONE.LOCALHOST. */
-       dns_name_t              nsip_name;      /* RPZ_NSIP_ZONE.LOCALHOST. */
-       dns_name_t              nsdname_name;   /* RPZ_NSDNAME_ZONE.LOCALHOST */
+       dns_name_t              ip_name;        /* RPZ_IP_ZONE.origin. */
+       dns_name_t              nsip_name;      /* RPZ_NSIP_ZONE.origin. */
+       dns_name_t              nsdname_name;   /* RPZ_NSDNAME_ZONE.origin */
 };
 
 static isc_boolean_t           have_rpz_zones = ISC_FALSE;
@@ -183,7 +183,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) {
                str = "NODATA";
                break;
        case DNS_RPZ_POLICY_RECORD:
-               str = "records";
+               str = "Local-Data";
                break;
        case DNS_RPZ_POLICY_CNAME:
        case DNS_RPZ_POLICY_WILDCNAME:
@@ -255,6 +255,8 @@ dns_rpz_view_destroy(dns_view_t *view) {
                ISC_LIST_UNLINK(view->rpz_zones, zone, link);
                if (dns_name_dynamic(&zone->origin))
                        dns_name_free(&zone->origin, view->mctx);
+               if (dns_name_dynamic(&zone->passthru))
+                       dns_name_free(&zone->passthru, view->mctx);
                if (dns_name_dynamic(&zone->nsdname))
                        dns_name_free(&zone->nsdname, view->mctx);
                if (dns_name_dynamic(&zone->cname))
@@ -427,14 +429,16 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
 }
 
 static void
-badname(int level, dns_name_t *name, const char *comment) {
+badname(int level, dns_name_t *name, const char *str1, const char *str2) {
        char printname[DNS_NAME_FORMATSIZE];
 
-       if (isc_log_wouldlog(dns_lctx, level)) {
+       if (level < DNS_RPZ_DEBUG_QUIET
+           && isc_log_wouldlog(dns_lctx, level)) {
                dns_name_format(name, printname, sizeof(printname));
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
                              DNS_LOGMODULE_RBTDB, level,
-                             "invalid rpz \"%s\"%s", printname, comment);
+                             "invalid rpz IP address \"%s\"%s%s",
+                             printname, str1, str2);
        }
 }
 
@@ -566,11 +570,11 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
           dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip,
           dns_rpz_cidr_bits_t *tgt_prefix)
 {
-       isc_buffer_t buffer;
-       unsigned char data[DNS_NAME_MAXWIRE+1];
+       isc_result_t result;
        dns_fixedname_t fname;
-       dns_name_t *name;
-       const char *cp, *end;
+       dns_name_t *ipname;
+       char ipstr[DNS_NAME_FORMATSIZE];
+       const char *prefix_str, *cp, *end;
        char *cp2;
        int ip_labels;
        dns_rpz_cidr_bits_t bits;
@@ -585,37 +589,43 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
        ip_labels -= dns_name_countlabels(&cidr->ip_name);
        ip_labels--;
        if (ip_labels < 1) {
-               badname(level, src_name, ", too short");
+               badname(level, src_name, "; too short", "");
                return (ISC_R_FAILURE);
        }
 
        /*
-        * Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST.
+        * Get text for the IP address
         */
        dns_fixedname_init(&fname);
-       name = dns_fixedname_name(&fname);
+       ipname = dns_fixedname_name(&fname);
        dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name),
-                      name, NULL);
-       isc_buffer_init(&buffer, data, sizeof(data));
-       dns_name_totext(name, ISC_TRUE, &buffer);
-       isc_buffer_putuint8(&buffer, '\0');
-       cp = isc_buffer_base(&buffer);
-
-       prefix = strtoul(cp, &cp2, 10);
-       if (prefix < 1U || prefix > 128U || *cp2 != '.') {
-               badname(level, src_name, ", bad prefix length");
+                      ipname, NULL);
+       dns_name_format(ipname, ipstr, sizeof(ipstr));
+       end = &ipstr[strlen(ipstr)+1];
+       prefix_str = ipstr;
+
+       prefix = strtoul(prefix_str, &cp2, 10);
+       if (*cp2 != '.') {
+               badname(level, src_name,
+                       "; invalid leading prefix length", "");
+               return (ISC_R_FAILURE);
+       }
+       *cp2 = '\0';
+       if (prefix < 1U || prefix > 128U) {
+               badname(level, src_name,
+                       "; invalid prefix length of ", prefix_str);
                return (ISC_R_FAILURE);
        }
        cp = cp2+1;
 
-       end = isc_buffer_used(&buffer);
        if (ip_labels == 4 && !strchr(cp, 'z')) {
                /*
                 * Convert an IPv4 address
                 * from the form "prefix.w.z.y.x"
                 */
                if (prefix > 32U) {
-                       badname(level, src_name, "; bad IPv4 prefix length");
+                       badname(level, src_name,
+                               "; invalid IPv4 prefix length of ", prefix_str);
                        return (ISC_R_FAILURE);
                }
                prefix += 96;
@@ -627,7 +637,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
                for (i = 0; i < 32; i += 8) {
                        l = strtoul(cp, &cp2, 10);
                        if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
-                               badname(level, src_name, "; bad IPv4 address");
+                               if (*cp2 == '.')
+                                       *cp2 = '\0';
+                               badname(level, src_name,
+                                       "; invalid IPv4 octet ", cp);
                                return (ISC_R_FAILURE);
                        }
                        tgt_ip->w[3] |= l << i;
@@ -654,7 +667,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
                                l = strtoul(cp, &cp2, 16);
                                if (l > 0xffffu ||
                                    (*cp2 != '.' && *cp2 != '\0')) {
-                                       badname(level, src_name, "");
+                                       if (*cp2 == '.')
+                                           *cp2 = '\0';
+                                       badname(level, src_name,
+                                               "; invalid IPv6 word ", cp);
                                        return (ISC_R_FAILURE);
                                }
                                if ((i & 1) == 0)
@@ -667,7 +683,7 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
                }
        }
        if (cp != end) {
-               badname(level, src_name, "");
+               badname(level, src_name, "", "");
                return (ISC_R_FAILURE);
        }
 
@@ -681,7 +697,8 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
                i = bits % DNS_RPZ_CIDR_WORD_BITS;
                aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS];
                if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) {
-                       badname(level, src_name, "; wrong prefix length");
+                       badname(level, src_name,
+                               "; too small prefix length of ", prefix_str);
                        return (ISC_R_FAILURE);
                }
                bits -= i;
@@ -689,13 +706,13 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
        }
 
        /*
-        * Convert the IPv6 address back to a canonical policy domain name
+        * Convert the address back to a canonical policy domain name
         * to ensure that it is in canonical form.
         */
-       if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix,
-                                    type, NULL, name) ||
-           !dns_name_equal(src_name, name)) {
-               badname(level, src_name, "; not canonical");
+       result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix,
+                        type, NULL, ipname);
+       if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) {
+               badname(level, src_name, "; not canonical", "");
                return (ISC_R_FAILURE);
        }
 
@@ -934,6 +951,7 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
  */
 void
 dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+       isc_result_t result;
        dns_rpz_cidr_key_t tgt_ip;
        dns_rpz_cidr_bits_t tgt_prefix;
        dns_rpz_type_t type;
@@ -956,19 +974,22 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
        case DNS_RPZ_TYPE_BAD:
                return;
        }
-       if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
-                                       type, &tgt_ip, &tgt_prefix))
+       result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
+                           type, &tgt_ip, &tgt_prefix);
+       if (result != ISC_R_SUCCESS)
                return;
 
-       if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type,
-                                  ISC_TRUE, NULL) &&
-           isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
+       result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL);
+       if (result == ISC_R_EXISTS &&
+           isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL))
+       {
                char printname[DNS_NAME_FORMATSIZE];
 
                dns_name_format(name, printname, sizeof(printname));
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
                              DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
-                             "duplicate rpz name \"%s\"", printname);
+                             "rpz add failed; \"%s\" is a duplicate name",
+                             printname);
        }
 }
 
@@ -978,6 +999,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
  */
 void
 dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+       isc_result_t result;
        dns_rpz_cidr_key_t tgt_ip;
        dns_rpz_cidr_bits_t tgt_prefix;
        dns_rpz_type_t type;
@@ -1010,19 +1032,14 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
        /*
         * Do not get excited about the deletion of interior rbt nodes.
         */
-       if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name,
-                                       type, &tgt_ip, &tgt_prefix))
+       result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name,
+                           type, &tgt_ip, &tgt_prefix);
+       if (result != ISC_R_SUCCESS)
                return;
-       if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
-                                   ISC_FALSE, &tgt)) {
-               if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
-                       char printname[DNS_NAME_FORMATSIZE];
-
-                       dns_name_format(name, printname, sizeof(printname));
-                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
-                                     DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
-                                     "missing rpz node \"%s\"", printname);
-               }
+
+       result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt);
+       if (result != ISC_R_SUCCESS) {
+               badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", "");
                return;
        }
 
@@ -1135,7 +1152,9 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
  * Translate CNAME rdata to a QNAME response policy action.
  */
 dns_rpz_policy_t
-dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
+dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
+                    dns_name_t *selfname)
+{
        dns_rdata_t rdata = DNS_RDATA_INIT;
        dns_rdata_cname_t cname;
        isc_result_t result;
@@ -1171,7 +1190,13 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
        }
 
        /*
-        * 128.1.0.127.rpz-ip CNAME  128.1.0.0.127. means "do not rewrite"
+        * CNAME PASSTHRU.origin means "do not rewrite.
+        */
+       if (dns_name_equal(&cname.cname, &rpz->passthru))
+               return (DNS_RPZ_POLICY_PASSTHRU);
+
+       /*
+        * 128.1.0.127.rpz-ip CNAME  128.1.0.0.127. is obsolete PASSTHRU
         */
        if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
                return (DNS_RPZ_POLICY_PASSTHRU);
index 517f018bb0f40eda40c342760e917c65b5b9d9e1..c048e1967a4f92c6863a19e62d9d3cbe9c9eccf7 100644 (file)
@@ -195,6 +195,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
        view->v6_aaaa = dns_aaaa_ok;
        view->aaaa_acl = NULL;
        ISC_LIST_INIT(view->rpz_zones);
+       view->rpz_recursive_only = ISC_TRUE;
+       view->rpz_break_dnssec = ISC_FALSE;
        dns_fixedname_init(&view->dlv_fixed);
        view->managed_keys = NULL;
        view->redirect = NULL;
index 563e8d4a94a2c372a0eb4cdc850a6774343e7547..95fa294e606234eb7ce71edff557e06729fdf6d5 100644 (file)
@@ -1025,66 +1025,60 @@ static cfg_type_t cfg_type_masterformat = {
 
 
 
-/*
+/*%
  *  response-policy {
  *     zone <string> [ policy (given|disabled|passthru|
- *                                     nxdomain|nodata|cname <domain> ) ];
- *  };
- *
- * this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
+ *                                     nxdomain|nodata|cname <domain> ) ]
+ *                   [ recursive-only yes|no ]
+ *                   [ max-policy-ttl number ] ;
+ *  } [ recursive-only yes|no ] [ break-dnssec yes|no ]
+ *     [ max-policy-ttl number ] ;
  */
+
 static void
-doc_rpz_policies(cfg_printer_t *pctx, const cfg_type_t *type) {
-       const keyword_type_t *kw;
+doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) {
        const char * const *p;
-
-       kw = type->of;
-       cfg_print_chars(pctx, "[ ", 2);
-       cfg_print_cstr(pctx, kw->name);
-       cfg_print_chars(pctx, " ", 1);
-
+       /*
+        * This is cfg_doc_enum() without the trailing " )".
+        */
        cfg_print_chars(pctx, "( ", 2);
-       for (p = kw->type->of; *p != NULL; p++) {
+       for (p = type->of; *p != NULL; p++) {
                cfg_print_cstr(pctx, *p);
                if (p[1] != NULL)
                        cfg_print_chars(pctx, " | ", 3);
        }
 }
 
-/*
- * print_qstring() from parser.c
- */
-static void
-print_rpz_cname(cfg_printer_t *pctx, const cfg_obj_t *obj)
-{
-       cfg_print_chars(pctx, "\"", 1);
-       cfg_print_ustring(pctx, obj);
-       cfg_print_chars(pctx, "\"", 1);
-}
-
 static void
 doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
        cfg_doc_terminal(pctx, type);
-       cfg_print_chars(pctx, " ) ]", 4);
+       cfg_print_chars(pctx, " )", 2);
 }
 
+/*
+ * Parse
+ *     given|disabled|passthru|nxdomain|nodata|cname <domain>
+ */
 static isc_result_t
-parse_rpz(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
+                    cfg_obj_t **ret)
+{
        isc_result_t result;
-       cfg_obj_t *obj = NULL;
-       const cfg_tuplefielddef_t *fields = type->of;
+       cfg_obj_t *obj;
+       const cfg_tuplefielddef_t *fields;
 
        CHECK(cfg_create_tuple(pctx, type, &obj));
+
+       fields = type->of;
        CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
-       CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1]));
        /*
         * parse cname domain only after "policy cname"
         */
-       if (cfg_obj_isvoid(obj->value.tuple[1]) ||
-           strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[1]))) {
-               CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
+       if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) {
+               CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
        } else {
-               CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
+               CHECK(cfg_parse_obj(pctx, fields[1].type,
+                                   &obj->value.tuple[1]));
        }
 
        *ret = obj;
@@ -1095,50 +1089,160 @@ cleanup:
        return (result);
 }
 
+/*
+ * Parse a tuple consisting of any kind of  required field followed
+ * by 2 or more optional keyvalues that can be in any order.
+ */
+static isc_result_t
+cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+       const cfg_tuplefielddef_t *fields, *f;
+       cfg_obj_t *obj;
+       int fn;
+       isc_result_t result;
+
+       obj = NULL;
+       CHECK(cfg_create_tuple(pctx, type, &obj));
+
+       /*
+        * The zone first field is required and always first.
+        */
+       fields = type->of;
+       CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
+
+       for (;;) {
+               CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
+               if (pctx->token.type != isc_tokentype_string)
+                       break;
+
+               for (fn = 1, f = &fields[1]; ; ++fn, ++f) {
+                       if (f->name == NULL) {
+                               cfg_parser_error(pctx, 0, "unexpected '%s'",
+                                                TOKEN_STRING(pctx));
+                               result = ISC_R_UNEXPECTEDTOKEN;
+                               goto cleanup;
+                       }
+                       if (obj->value.tuple[fn] == NULL &&
+                           strcasecmp(f->name, TOKEN_STRING(pctx)) == 0)
+                               break;
+               }
+
+               CHECK(cfg_gettoken(pctx, 0));
+               CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn]));
+       }
+
+       for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) {
+               if (obj->value.tuple[fn] == NULL)
+                       CHECK(cfg_parse_void(pctx, NULL,
+                                            &obj->value.tuple[fn]));
+       }
+
+       *ret = obj;
+       return (ISC_R_SUCCESS);
+
+cleanup:
+       CLEANUP_OBJ(obj);
+       return (result);
+}
+
+static void
+cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+       unsigned int i;
+       const cfg_tuplefielddef_t *fields, *f;
+       const cfg_obj_t *fieldobj;
+
+       fields = obj->type->of;
+       for (f = fields, i = 0; f->name != NULL; f++, i++) {
+               fieldobj = obj->value.tuple[i];
+               if (fieldobj->type->print == cfg_print_void)
+                       continue;
+               if (i != 0) {
+                       cfg_print_chars(pctx, " ", 1);
+                       cfg_print_cstr(pctx, f->name);
+                       cfg_print_chars(pctx, " ", 1);
+               }
+               cfg_print_obj(pctx, fieldobj);
+       }
+}
+
+static void
+cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) {
+       const cfg_tuplefielddef_t *fields, *f;
+
+       fields = type->of;
+       for (f = fields; f->name != NULL; f++) {
+               if (f != fields) {
+                       cfg_print_chars(pctx, " [ ", 3);
+                       cfg_print_cstr(pctx, f->name);
+                       if (f->type->doc != cfg_doc_void)
+                               cfg_print_chars(pctx, " ", 1);
+               }
+               cfg_doc_obj(pctx, f->type);
+               if (f != fields)
+                       cfg_print_chars(pctx, " ]", 2);
+       }
+}
+
+static keyword_type_t zone_kw = {"zone", &cfg_type_qstring};
+static cfg_type_t cfg_type_rpz_zone = {
+       "zone", parse_keyvalue, print_keyvalue,
+       doc_keyvalue, &cfg_rep_string,
+       &zone_kw
+};
 static const char *rpz_policies[] = {
        "given", "disabled", "passthru", "no-op", "nxdomain", "nodata",
        "cname", NULL
 };
-static cfg_type_t cfg_type_rpz_policylist = {
-       "policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
-       &cfg_rep_string, &rpz_policies
+static cfg_type_t cfg_type_rpz_policy_name = {
+       "policy name", cfg_parse_enum, cfg_print_ustring,
+       doc_rpz_policy, &cfg_rep_string,
+       &rpz_policies
 };
-static keyword_type_t rpz_policies_kw = {
-       "policy", &cfg_type_rpz_policylist
+static cfg_type_t cfg_type_rpz_cname = {
+       "quoted_string", cfg_parse_astring, NULL,
+       doc_rpz_cname, &cfg_rep_string,
+       NULL
 };
-static cfg_type_t cfg_type_rpz_policy = {
-       "optional_policy", parse_optional_keyvalue, print_keyvalue,
-       doc_rpz_policies, &cfg_rep_string, &rpz_policies_kw
+static cfg_tuplefielddef_t rpz_policy_fields[] = {
+       { "policy name", &cfg_type_rpz_policy_name, 0 },
+       { "cname", &cfg_type_rpz_cname, 0 },
+       { NULL, NULL, 0 }
 };
-static cfg_type_t cfg_type_cname = {
-       "domain", cfg_parse_astring, print_rpz_cname, doc_rpz_cname,
-       &cfg_rep_string, NULL
+static cfg_type_t cfg_type_rpz_policy = {
+       "policy tuple", cfg_parse_rpz_policy,
+       cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
+       rpz_policy_fields
 };
-static cfg_tuplefielddef_t rpzone_fields[] = {
-       { "name", &cfg_type_astring, 0 },
+static cfg_tuplefielddef_t rpz_zone_fields[] = {
+       { "zone name", &cfg_type_rpz_zone, 0 },
        { "policy", &cfg_type_rpz_policy, 0 },
-       { "cname", &cfg_type_cname, 0 },
+       { "recursive-only", &cfg_type_boolean, 0 },
+       { "max-policy-ttl", &cfg_type_uint32, 0 },
        { NULL, NULL, 0 }
 };
-static cfg_type_t cfg_type_rpzone = {
-       "rpzone", parse_rpz, cfg_print_tuple, cfg_doc_tuple,
-       &cfg_rep_tuple, rpzone_fields
+static cfg_type_t cfg_type_rpz_tuple = {
+       "rpz tuple", cfg_parse_kv_tuple,
+       cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
+       rpz_zone_fields
 };
-static cfg_clausedef_t rpz_clauses[] = {
-       { "zone", &cfg_type_rpzone, CFG_CLAUSEFLAG_MULTI },
-       { NULL, NULL, 0 }
+static cfg_type_t cfg_type_rpz_list = {
+       "zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+       cfg_doc_bracketed_list, &cfg_rep_list,
+       &cfg_type_rpz_tuple
 };
-static cfg_clausedef_t *rpz_clausesets[] = {
-       rpz_clauses,
-       NULL
+static cfg_tuplefielddef_t rpz_fields[] = {
+       { "zone list", &cfg_type_rpz_list, 0 },
+       { "recursive-only", &cfg_type_boolean, 0 },
+       { "break-dnssec", &cfg_type_boolean, 0 },
+       { "max-policy-ttl", &cfg_type_uint32, 0 },
+       { NULL, NULL, 0 }
 };
 static cfg_type_t cfg_type_rpz = {
-       "rpz", cfg_parse_map, cfg_print_map, cfg_doc_map,
-       &cfg_rep_map, rpz_clausesets
+       "rpz", cfg_parse_kv_tuple,
+       cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
+       rpz_fields
 };
 
 
-
 /*%
  * dnssec-lookaside
  */
index 3f35b7e40449b7f394430f73a92872f30b0a9eab..4908bcc221a8eaaac067770b0e137359249b7ee6 100644 (file)
 ./bin/tests/system/rpz/clean.sh                        SH      2011,2012
 ./bin/tests/system/rpz/ns1/named.conf          CONF-C  2011
 ./bin/tests/system/rpz/ns1/root.db             ZONE    2011,2012
+./bin/tests/system/rpz/ns2/base-tld2s.db       ZONE    2012
 ./bin/tests/system/rpz/ns2/hints               ZONE    2011
 ./bin/tests/system/rpz/ns2/named.conf          CONF-C  2011,2012
 ./bin/tests/system/rpz/ns2/tld2.db             ZONE    2011
 ./bin/tests/system/rpz/ns3/crash2              X       2011
 ./bin/tests/system/rpz/ns3/hints               ZONE    2011
 ./bin/tests/system/rpz/ns3/named.conf          CONF-C  2011
-./bin/tests/system/rpz/ns4/hints               X       2011
+./bin/tests/system/rpz/ns4/hints               ZONE    2011
 ./bin/tests/system/rpz/ns4/named.conf          CONF-C  2011
 ./bin/tests/system/rpz/ns4/tld4.db             ZONE    2011
+./bin/tests/system/rpz/ns5/hints               ZONE    2011
+./bin/tests/system/rpz/ns5/named.conf          CONF-C  2012
+./bin/tests/system/rpz/qperf.sh                        SH      2012
 ./bin/tests/system/rpz/rpz.c                   C       2011
 ./bin/tests/system/rpz/setup.sh                        SH      2011,2012
 ./bin/tests/system/rpz/test1                   X       2011,2012