]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Improve performance for delegation heavy answers and also general query performance...
authorMukund Sivaraman <muks@isc.org>
Sat, 22 Apr 2017 02:55:10 +0000 (08:25 +0530)
committerMukund Sivaraman <muks@isc.org>
Sat, 22 Apr 2017 03:52:44 +0000 (09:22 +0530)
134 files changed:
CHANGES
bin/named/config.c
bin/named/include/named/server.h
bin/named/query.c
bin/named/server.c
bin/tests/system/additional/ns1/named1.conf
bin/tests/system/additional/ns1/named2.conf
bin/tests/system/additional/ns1/named3.conf
bin/tests/system/additional/ns1/named4.conf
bin/tests/system/autosign/clean.sh
bin/tests/system/autosign/ns2/keygen.sh
bin/tests/system/autosign/ns4/named.conf
bin/tests/system/autosign/ns5/named.conf
bin/tests/system/autosign/tests.sh
bin/tests/system/cacheclean/ns1/named.conf
bin/tests/system/case/ns1/named.conf
bin/tests/system/case/ns2/named.conf
bin/tests/system/checknames/ns2/named.conf
bin/tests/system/checknames/ns3/named.conf
bin/tests/system/checknames/ns4/named.conf
bin/tests/system/cookie/ns1/named.conf
bin/tests/system/cookie/ns2/named.conf
bin/tests/system/cookie/ns3/named.conf
bin/tests/system/digdelv/ns3/named.conf
bin/tests/system/dlv/ns5/named.conf
bin/tests/system/dnssec/ns2/named.conf
bin/tests/system/dnssec/ns3/named.conf
bin/tests/system/dnssec/ns4/named1.conf
bin/tests/system/dnssec/ns4/named2.conf
bin/tests/system/dnssec/ns4/named3.conf
bin/tests/system/dnssec/ns4/named4.conf
bin/tests/system/dnssec/ns5/named1.conf
bin/tests/system/dnssec/ns6/named.conf
bin/tests/system/dnssec/tests.sh
bin/tests/system/emptyzones/ns1/named1.conf
bin/tests/system/emptyzones/ns1/named2.conf
bin/tests/system/filter-aaaa/ns1/named1.conf
bin/tests/system/filter-aaaa/ns1/named2.conf
bin/tests/system/filter-aaaa/ns1/root.db
bin/tests/system/filter-aaaa/ns1/signed.db.in
bin/tests/system/filter-aaaa/ns1/unsigned.db
bin/tests/system/filter-aaaa/ns2/named1.conf
bin/tests/system/filter-aaaa/ns2/named2.conf
bin/tests/system/filter-aaaa/ns3/named1.conf
bin/tests/system/filter-aaaa/ns3/named2.conf
bin/tests/system/filter-aaaa/ns4/named1.conf
bin/tests/system/filter-aaaa/ns4/named2.conf
bin/tests/system/filter-aaaa/ns4/root.db
bin/tests/system/filter-aaaa/ns4/signed.db.in
bin/tests/system/filter-aaaa/ns4/unsigned.db
bin/tests/system/glue/ns1/root.db
bin/tests/system/glue/tests.sh
bin/tests/system/limits/ns1/named.conf
bin/tests/system/notify/ns3/named.conf
bin/tests/system/notify/ns4/named.conf
bin/tests/system/notify/ns5/named.conf
bin/tests/system/nsupdate/ns1/named.conf
bin/tests/system/nsupdate/ns2/named.conf
bin/tests/system/resolver/ns1/named.conf
bin/tests/system/rpz/ns1/named.conf
bin/tests/system/rpz/ns2/named.conf
bin/tests/system/rpz/ns3/named.conf
bin/tests/system/rpz/ns4/named.conf
bin/tests/system/rpz/ns5/named.conf
bin/tests/system/rpz/ns6/named.conf
bin/tests/system/rpz/ns7/named.conf
bin/tests/system/rrl/broken.conf
bin/tests/system/rrl/ns2/named.conf
bin/tests/system/rrl/ns4/named.conf
bin/tests/system/rrsetorder/clean.sh
bin/tests/system/rrsetorder/ns1/root.db
bin/tests/system/rrsetorder/ns3/named.conf
bin/tests/system/rrsetorder/ns4/named.conf
bin/tests/system/rrsetorder/tests.sh
bin/tests/system/sfcache/ns5/named.conf
bin/tests/system/statschannel/ns2/named.conf
bin/tests/system/stress/ns3/named.conf
bin/tests/system/stress/ns4/named.conf
bin/tests/system/stub/ns1/named.conf
bin/tests/system/stub/ns2/named.conf
bin/tests/system/stub/ns3/named.conf
bin/tests/system/tkey/ns1/named.conf.in
bin/tests/system/tkey/tests.sh
bin/tests/system/upforwd/ns1/named.conf
bin/tests/system/upforwd/ns2/named.conf
bin/tests/system/upforwd/ns3/named.conf
bin/tests/system/v6synth/ns2/named.conf
bin/tests/system/v6synth/ns3/named.conf
bin/tests/system/xfer/ns3/named.conf
bin/tests/system/zero/ns1/named.conf
bin/tests/system/zero/ns2/named.conf
bin/tests/system/zero/ns3/named.conf
bin/tests/system/zero/ns4/named.conf
doc/arm/Bv9ARM-book.xml
doc/misc/options
lib/bind9/check.c
lib/dns/Makefile.in
lib/dns/acache.c [deleted file]
lib/dns/compress.c
lib/dns/ecdb.c
lib/dns/include/dns/Makefile.in
lib/dns/include/dns/acache.h [deleted file]
lib/dns/include/dns/compress.h
lib/dns/include/dns/log.h
lib/dns/include/dns/rdataset.h
lib/dns/include/dns/types.h
lib/dns/include/dns/view.h
lib/dns/include/dns/zone.h
lib/dns/log.c
lib/dns/message.c
lib/dns/name.c
lib/dns/ncache.c
lib/dns/order.c
lib/dns/rbtdb.c
lib/dns/rdatalist.c
lib/dns/rdataset.c
lib/dns/rdataslab.c
lib/dns/sdb.c
lib/dns/sdlz.c
lib/dns/ssu_external.c
lib/dns/view.c
lib/dns/win32/libdns.def.in
lib/dns/win32/libdns.dsp.in
lib/dns/win32/libdns.mak.in
lib/dns/win32/libdns.vcxproj.filters.in
lib/dns/win32/libdns.vcxproj.in
lib/dns/zone.c
lib/isc/hash.c
lib/isc/include/isc/buffer.h
lib/isc/include/isc/msgs.h
lib/isc/mem.c
lib/isc/rwlock.c
lib/isccfg/namedconf.c
util/copyrights

diff --git a/CHANGES b/CHANGES
index e26704590f0eb121c1438981c326a9cbd5e7f5d1..5180259f3b80baaf9e82d56e8d71023a9bb60ecb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+4605.  [performance]   Improve performance for delegation heavy answers
+                       and also general query performance. Removes the
+                       acache feature that didn't significantly improve
+                       performance. Adds a glue cache. Removes
+                       additional-from-cache and additional-from-auth
+                       features. Enables minimal-responses by
+                       default. Improves performance of compression
+                       code, owner case restoration, hash function,
+                       etc. Uses inline buffer implementation by
+                       default. Many other performance changes and fixes.
+                       [RT #44029]
+
 4604.  [bug]           Don't use ERR_load_crypto_strings() when building
                        with OpenSSL 1.1.0. [RT #45117]
 
index c8fbcf682d9671cbf2891c34c752f635604d8116..585528fc84bfdf6f8ce65d624ce9d68994216220 100644 (file)
@@ -94,7 +94,6 @@ options {\n\
 "\
        recursive-clients 1000;\n\
        resolver-query-timeout 10;\n\
-       rrset-order { order random; };\n\
 #      serial-queries <obsolete>;\n\
        serial-query-rate 20;\n\
        server-id none;\n\
@@ -140,15 +139,13 @@ options {\n\
 #      topology <none>\n\
        auth-nxdomain false;\n\
        minimal-any false;\n\
-       minimal-responses false;\n\
+       minimal-responses true;\n\
        recursion true;\n\
        provide-ixfr true;\n\
        request-ixfr true;\n\
        request-expire true;\n\
 #      fetch-glue <obsolete>;\n\
 #      rfc2308-type1 <obsolete>;\n\
-       additional-from-auth true;\n\
-       additional-from-cache true;\n\
        query-source address *;\n\
        query-source-v6 address *;\n\
        notify-source *;\n\
@@ -167,9 +164,6 @@ options {\n\
        check-dup-records warn;\n\
        check-mx warn;\n\
        check-spf warn;\n\
-       acache-enable no;\n\
-       acache-cleaning-interval 60;\n\
-       max-acache-size 16M;\n\
        dnssec-enable yes;\n\
        dnssec-validation yes; \n\
        dnssec-accept-expired no;\n\
index 65a45d24166fc93fbda0ed349845dfafa723a27c..355c64d53dcd1735eadb0157b8cc1ec95633c0c3 100644 (file)
@@ -108,8 +108,6 @@ struct ns_server {
        unsigned int            dispatchgen;
        ns_dispatchlist_t       dispatches;
 
-       dns_acache_t            *acache;
-
        ns_statschannellist_t   statschannels;
 
        dns_tsigkey_t           *sessionkey;
index a8ceba16eafb7d288904a40bcfe710e9674128ab..1c63f2ce0b29487b24a2120e08debc3988a7d941 100644 (file)
@@ -210,11 +210,6 @@ client_trace(ns_client_t *client, int level, const char *message) {
 #define SAVE(a, b) do { INSIST(a == NULL); a = b; b = NULL; } while (0)
 #define RESTORE(a, b) SAVE(a, b)
 
-typedef struct client_additionalctx {
-       ns_client_t *client;
-       dns_rdataset_t *rdataset;
-} client_additionalctx_t;
-
 static isc_boolean_t
 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
         dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
@@ -1032,10 +1027,11 @@ query_validatezonedb(ns_client_t *client, const dns_name_t *name,
         * CNAMES or DNAMES into other zones and prevents returning
         * additional data from other zones.
         */
-       if (!client->view->additionalfromauth &&
-           client->query.authdbset &&
-           db != client->query.authdb)
+       if (client->query.rpz_st == NULL &&
+           client->query.authdbset && db != client->query.authdb)
+       {
                return (DNS_R_REFUSED);
+       }
 
        /*
         * Non recursive query to a static-stub zone is prohibited; its
@@ -1580,9 +1576,9 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
        dns_rdataset_t *rdataset, *sigrdataset, *trdataset;
        isc_buffer_t *dbuf;
        isc_buffer_t b;
+       ns_dbversion_t *dbversion;
        dns_dbversion_t *version;
        isc_boolean_t added_something, need_addname;
-       dns_zone_t *zone;
        dns_rdatatype_t type;
        dns_clientinfomethods_t cm;
        dns_clientinfo_t ci;
@@ -1609,7 +1605,6 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
        node = NULL;
        added_something = ISC_FALSE;
        need_addname = ISC_FALSE;
-       zone = NULL;
        additionaltype = dns_rdatasetadditional_fromauth;
 
        dns_clientinfomethods_init(&cm, ns_client_sourceip);
@@ -1643,14 +1638,26 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
        }
 
        /*
-        * Look for a zone database that might contain authoritative
+        * If we want only minimal responses and are here, then it must
+        * be for glue.
+        */
+       if (client->view->minimalresponses == dns_minimal_yes)
+               goto try_glue;
+
+       /*
+        * Look within the same zone database for authoritative
         * additional data.
         */
-       result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
-                                &zone, &db, &version);
-       if (result != ISC_R_SUCCESS)
+       if (!client->query.authdbset || client->query.authdb == NULL)
                goto try_cache;
 
+       dbversion = query_findversion(client, client->query.authdb);
+       if (dbversion == NULL)
+               goto try_cache;
+
+       dns_db_attach(client->query.authdb, &db);
+       version = dbversion->version;
+
        CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find");
 
        /*
@@ -1684,13 +1691,17 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
         */
 
  try_cache:
+       if (!client->view->recursion)
+               goto try_glue;
+
        additionaltype = dns_rdatasetadditional_fromcache;
        result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                /*
                 * Most likely the client isn't allowed to query the cache.
                 */
                goto try_glue;
+       }
        /*
         * Attempt to validate glue.
         */
@@ -1699,6 +1710,8 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
                if (sigrdataset == NULL)
                        goto cleanup;
        }
+
+       version = NULL;
        result = dns_db_findext(db, name, version, type,
                                client->query.dboptions |
                                DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
@@ -1744,8 +1757,12 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
        if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
                goto cleanup;
 
-       dns_db_attach(client->query.gluedb, &db);
+       dbversion = query_findversion(client, client->query.gluedb);
+       if (dbversion == NULL)
+               goto cleanup;
 
+       dns_db_attach(client->query.gluedb, &db);
+       version = dbversion->version;
        additionaltype = dns_rdatasetadditional_fromglue;
        result = dns_db_findext(db, name, version, type,
                                client->query.dboptions | DNS_DBFIND_GLUEOK,
@@ -1826,15 +1843,14 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
                                             dns_rdatatype_a, 0,
                                             client->now,
                                             rdataset, sigrdataset);
-               if (result == DNS_R_NCACHENXDOMAIN)
+               if (result == DNS_R_NCACHENXDOMAIN) {
                        goto addname;
-               if (result == DNS_R_NCACHENXRRSET) {
+               } else if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
                        if (sigrdataset != NULL &&
                            dns_rdataset_isassociated(sigrdataset))
                                dns_rdataset_disassociate(sigrdataset);
-               }
-               if (result == ISC_R_SUCCESS) {
+               } else if (result == ISC_R_SUCCESS) {
                        mname = NULL;
 #ifdef ALLOW_FILTER_AAAA
                        have_a = ISC_TRUE;
@@ -1887,15 +1903,14 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
                                             dns_rdatatype_aaaa, 0,
                                             client->now,
                                             rdataset, sigrdataset);
-               if (result == DNS_R_NCACHENXDOMAIN)
+               if (result == DNS_R_NCACHENXDOMAIN) {
                        goto addname;
-               if (result == DNS_R_NCACHENXRRSET) {
+               } else if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
                        if (sigrdataset != NULL &&
                            dns_rdataset_isassociated(sigrdataset))
                                dns_rdataset_disassociate(sigrdataset);
-               }
-               if (result == ISC_R_SUCCESS) {
+               } else if (result == ISC_R_SUCCESS) {
                        mname = NULL;
                        /*
                         * There's an A; check whether we're filtering AAAA
@@ -1992,562 +2007,15 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
                dns_db_detachnode(db, &node);
        if (db != NULL)
                dns_db_detach(&db);
-       if (zone != NULL)
-               dns_zone_detach(&zone);
 
        CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done");
        return (eresult);
 }
 
-static inline void
-query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base,
-                  dns_rdatasetadditional_t additionaltype,
-                  dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp,
-                  dns_dbversion_t **versionp, dns_dbnode_t **nodep,
-                  dns_name_t *fname)
-{
-       dns_rdataset_t *rdataset;
-
-       while  ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) {
-               ISC_LIST_UNLINK(fname->list, rdataset, link);
-               query_putrdataset(client, &rdataset);
-       }
-       if (*versionp != NULL)
-               dns_db_closeversion(*dbp, versionp, ISC_FALSE);
-       if (*nodep != NULL)
-               dns_db_detachnode(*dbp, nodep);
-       if (*dbp != NULL)
-               dns_db_detach(dbp);
-       if (*zonep != NULL)
-               dns_zone_detach(zonep);
-       (void)dns_rdataset_putadditional(client->view->acache, rdataset_base,
-                                        additionaltype, type);
-}
-
-static inline isc_result_t
-query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0,
-                  dns_dbversion_t *version)
-{
-       isc_result_t result = ISC_R_SUCCESS;
-       dns_dbversion_t *version_current = NULL;
-       dns_db_t *db_current = db0;
-
-       if (db_current == NULL) {
-               result = dns_zone_getdb(zone, &db_current);
-               if (result != ISC_R_SUCCESS)
-                       return (result);
-       }
-       dns_db_currentversion(db_current, &version_current);
-       if (db_current != db || version_current != version) {
-               result = ISC_R_FAILURE;
-               goto cleanup;
-       }
-
- cleanup:
-       dns_db_closeversion(db_current, &version_current, ISC_FALSE);
-       if (db0 == NULL && db_current != NULL)
-               dns_db_detach(&db_current);
-
-       return (result);
-}
-
-static isc_result_t
-query_addadditional2(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
-       client_additionalctx_t *additionalctx = arg;
-       dns_rdataset_t *rdataset_base;
-       ns_client_t *client;
-       isc_result_t result, eresult;
-       dns_dbnode_t *node, *cnode;
-       dns_db_t *db, *cdb;
-       dns_name_t *fname, *mname0, cfname;
-       dns_rdataset_t *rdataset, *sigrdataset;
-       dns_rdataset_t *crdataset, *crdataset_next;
-       isc_buffer_t *dbuf;
-       isc_buffer_t b;
-       dns_dbversion_t *version, *cversion;
-       isc_boolean_t added_something, need_addname, needadditionalcache;
-       isc_boolean_t need_sigrrset;
-       dns_zone_t *zone;
-       dns_rdatatype_t type;
-       dns_rdatasetadditional_t additionaltype;
-       dns_clientinfomethods_t cm;
-       dns_clientinfo_t ci;
-
-       /*
-        * If we don't have an additional cache call query_addadditional.
-        */
-       client = additionalctx->client;
-       REQUIRE(NS_CLIENT_VALID(client));
-
-       if (qtype != dns_rdatatype_a || client->view->acache == NULL) {
-               /*
-                * This function is optimized for "address" types.  For other
-                * types, use a generic routine.
-                * XXX: ideally, this function should be generic enough.
-                */
-               return (query_addadditional(additionalctx->client,
-                                           name, qtype));
-       }
-
-       /*
-        * Initialization.
-        */
-       rdataset_base = additionalctx->rdataset;
-       eresult = ISC_R_SUCCESS;
-       fname = NULL;
-       rdataset = NULL;
-       sigrdataset = NULL;
-       db = NULL;
-       cdb = NULL;
-       version = NULL;
-       cversion = NULL;
-       node = NULL;
-       cnode = NULL;
-       added_something = ISC_FALSE;
-       need_addname = ISC_FALSE;
-       zone = NULL;
-       needadditionalcache = ISC_FALSE;
-       POST(needadditionalcache);
-       additionaltype = dns_rdatasetadditional_fromauth;
-       dns_name_init(&cfname, NULL);
-       dns_clientinfomethods_init(&cm, ns_client_sourceip);
-       dns_clientinfo_init(&ci, client, NULL);
-
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2");
-
-       /*
-        * We treat type A additional section processing as if it
-        * were "any address type" additional section processing.
-        * To avoid multiple lookups, we do an 'any' database
-        * lookup and iterate over the node.
-        * XXXJT: this approach can cause a suboptimal result when the cache
-        * DB only has partial address types and the glue DB has remaining
-        * ones.
-        */
-       type = dns_rdatatype_any;
-
-       /*
-        * Get some resources.
-        */
-       dbuf = query_getnamebuf(client);
-       if (dbuf == NULL)
-               goto cleanup;
-       fname = query_newname(client, dbuf, &b);
-       if (fname == NULL)
-               goto cleanup;
-       dns_name_setbuffer(&cfname, &b); /* share the buffer */
-
-       /* Check additional cache */
-       result = dns_rdataset_getadditional(rdataset_base, additionaltype,
-                                           type, client->view->acache, &zone,
-                                           &cdb, &cversion, &cnode, &cfname,
-                                           client->message, client->now);
-       if (result != ISC_R_SUCCESS)
-               goto findauthdb;
-       if (zone == NULL) {
-               CTRACE(ISC_LOG_DEBUG(3),
-                      "query_addadditional2: auth zone not found");
-               goto try_cache;
-       }
-
-       /* Is the cached DB up-to-date? */
-       result = query_iscachevalid(zone, cdb, NULL, cversion);
-       if (result != ISC_R_SUCCESS) {
-               CTRACE(ISC_LOG_DEBUG(3),
-                      "query_addadditional2: old auth additional cache");
-               query_discardcache(client, rdataset_base, additionaltype,
-                                  type, &zone, &cdb, &cversion, &cnode,
-                                  &cfname);
-               goto findauthdb;
-       }
-
-       if (cnode == NULL) {
-               /*
-                * We have a negative cache.  We don't have to check the zone
-                * ACL, since the result (not using this zone) would be same
-                * regardless of the result.
-                */
-               CTRACE(ISC_LOG_DEBUG(3),
-                      "query_addadditional2: negative auth additional cache");
-               dns_db_closeversion(cdb, &cversion, ISC_FALSE);
-               dns_db_detach(&cdb);
-               dns_zone_detach(&zone);
-               goto try_cache;
-       }
-
-       result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG,
-                                     zone, cdb, NULL);
-       if (result != ISC_R_SUCCESS) {
-               query_discardcache(client, rdataset_base, additionaltype,
-                                  type, &zone, &cdb, &cversion, &cnode,
-                                  &cfname);
-               goto try_cache;
-       }
-
-       /* We've got an active cache. */
-       CTRACE(ISC_LOG_DEBUG(3),
-              "query_addadditional2: auth additional cache");
-       dns_db_closeversion(cdb, &cversion, ISC_FALSE);
-       db = cdb;
-       node = cnode;
-       dns_name_clone(&cfname, fname);
-       query_keepname(client, fname, dbuf);
-       goto foundcache;
-
-       /*
-        * Look for a zone database that might contain authoritative
-        * additional data.
-        */
- findauthdb:
-       result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
-                                &zone, &db, &version);
-       if (result != ISC_R_SUCCESS) {
-               /* Cache the negative result */
-               (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
-                                                type, client->view->acache,
-                                                NULL, NULL, NULL, NULL,
-                                                NULL);
-               goto try_cache;
-       }
-
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: db_find");
-
-       /*
-        * Since we are looking for authoritative data, we do not set
-        * the GLUEOK flag.  Glue will be looked for later, but not
-        * necessarily in the same database.
-        */
-       node = NULL;
-       result = dns_db_findext(db, name, version, type,
-                               client->query.dboptions,
-                               client->now, &node, fname, &cm, &ci,
-                               NULL, NULL);
-       if (result == ISC_R_SUCCESS)
-               goto found;
-
-       /* Cache the negative result */
-       (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
-                                        type, client->view->acache, zone, db,
-                                        version, NULL, fname);
-
-       if (node != NULL)
-               dns_db_detachnode(db, &node);
-       version = NULL;
-       dns_db_detach(&db);
-
-       /*
-        * No authoritative data was found.  The cache is our next best bet.
-        */
-
- try_cache:
-       additionaltype = dns_rdatasetadditional_fromcache;
-       result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
-       if (result != ISC_R_SUCCESS)
-               /*
-                * Most likely the client isn't allowed to query the cache.
-                */
-               goto try_glue;
-
-       result = dns_db_findext(db, name, version, type,
-                               client->query.dboptions |
-                                DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
-                               client->now, &node, fname, &cm, &ci,
-                               NULL, NULL);
-       if (result == ISC_R_SUCCESS)
-               goto found;
-
-       if (node != NULL)
-               dns_db_detachnode(db, &node);
-       dns_db_detach(&db);
-
- try_glue:
-       /*
-        * No cached data was found.  Glue is our last chance.
-        * RFC1035 sayeth:
-        *
-        *      NS records cause both the usual additional section
-        *      processing to locate a type A record, and, when used
-        *      in a referral, a special search of the zone in which
-        *      they reside for glue information.
-        *
-        * This is the "special search".  Note that we must search
-        * the zone where the NS record resides, not the zone it
-        * points to, and that we only do the search in the delegation
-        * case (identified by client->query.gluedb being set).
-        */
-       if (client->query.gluedb == NULL)
-               goto cleanup;
-
-       /*
-        * Don't poison caches using the bailiwick protection model.
-        */
-       if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
-               goto cleanup;
-
-       /* Check additional cache */
-       additionaltype = dns_rdatasetadditional_fromglue;
-       result = dns_rdataset_getadditional(rdataset_base, additionaltype,
-                                           type, client->view->acache, NULL,
-                                           &cdb, &cversion, &cnode, &cfname,
-                                           client->message, client->now);
-       if (result != ISC_R_SUCCESS)
-               goto findglue;
-
-       result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion);
-       if (result != ISC_R_SUCCESS) {
-               CTRACE(ISC_LOG_DEBUG(3),
-                      "query_addadditional2: old glue additional cache");
-               query_discardcache(client, rdataset_base, additionaltype,
-                                  type, &zone, &cdb, &cversion, &cnode,
-                                  &cfname);
-               goto findglue;
-       }
-
-       if (cnode == NULL) {
-               /* We have a negative cache. */
-               CTRACE(ISC_LOG_DEBUG(3),
-                      "query_addadditional2: negative glue additional cache");
-               dns_db_closeversion(cdb, &cversion, ISC_FALSE);
-               dns_db_detach(&cdb);
-               goto cleanup;
-       }
-
-       /* Cache hit. */
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: glue additional cache");
-       dns_db_closeversion(cdb, &cversion, ISC_FALSE);
-       db = cdb;
-       node = cnode;
-       dns_name_clone(&cfname, fname);
-       query_keepname(client, fname, dbuf);
-       goto foundcache;
-
- findglue:
-       dns_db_attach(client->query.gluedb, &db);
-       result = dns_db_findext(db, name, version, type,
-                               client->query.dboptions | DNS_DBFIND_GLUEOK,
-                               client->now, &node, fname, &cm, &ci,
-                               NULL, NULL);
-       if (!(result == ISC_R_SUCCESS ||
-             result == DNS_R_ZONECUT ||
-             result == DNS_R_GLUE)) {
-               /* cache the negative result */
-               (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
-                                                type, client->view->acache,
-                                                NULL, db, version, NULL,
-                                                fname);
-               goto cleanup;
-       }
-
- found:
-       /*
-        * We have found a DB node to iterate over from a DB.
-        * We are going to look for address RRsets (i.e., A and AAAA) in the DB
-        * node we've just found.  We'll then store the complete information
-        * in the additional data cache.
-        */
-       dns_name_clone(fname, &cfname);
-       query_keepname(client, fname, dbuf);
-       needadditionalcache = ISC_TRUE;
-
-       rdataset = query_newrdataset(client);
-       if (rdataset == NULL)
-               goto cleanup;
-
-       sigrdataset = query_newrdataset(client);
-       if (sigrdataset == NULL)
-               goto cleanup;
-
-       if (additionaltype == dns_rdatasetadditional_fromcache &&
-           query_isduplicate(client, fname, dns_rdatatype_a, NULL))
-               goto aaaa_lookup;
-       /*
-        * Find A RRset with sig RRset.  Even if we don't find a sig RRset
-        * for a client using DNSSEC, we'll continue the process to make a
-        * complete list to be cached.  However, we need to cancel the
-        * caching when something unexpected happens, in order to avoid
-        * caching incomplete information.
-        */
-       result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0,
-                                    client->now, rdataset, sigrdataset);
-       /*
-        * If we can't promote glue/pending from the cache to secure
-        * then drop it.
-        */
-       if (result == ISC_R_SUCCESS &&
-           additionaltype == dns_rdatasetadditional_fromcache &&
-           (DNS_TRUST_PENDING(rdataset->trust) ||
-            DNS_TRUST_GLUE(rdataset->trust)) &&
-           !validate(client, db, fname, rdataset, sigrdataset)) {
-               dns_rdataset_disassociate(rdataset);
-               if (dns_rdataset_isassociated(sigrdataset))
-                       dns_rdataset_disassociate(sigrdataset);
-               result = ISC_R_NOTFOUND;
-       }
-       if (result == DNS_R_NCACHENXDOMAIN)
-               goto setcache;
-       if (result == DNS_R_NCACHENXRRSET) {
-               dns_rdataset_disassociate(rdataset);
-               if (dns_rdataset_isassociated(sigrdataset))
-                       dns_rdataset_disassociate(sigrdataset);
-       }
-       if (result == ISC_R_SUCCESS) {
-               /* Remember the result as a cache */
-               ISC_LIST_APPEND(cfname.list, rdataset, link);
-               if (dns_rdataset_isassociated(sigrdataset)) {
-                       ISC_LIST_APPEND(cfname.list, sigrdataset, link);
-                       sigrdataset = query_newrdataset(client);
-               }
-               rdataset = query_newrdataset(client);
-               if (sigrdataset == NULL || rdataset == NULL) {
-                       /* do not cache incomplete information */
-                       goto foundcache;
-               }
-       }
-
- aaaa_lookup:
-       if (additionaltype == dns_rdatasetadditional_fromcache &&
-           query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
-               goto foundcache;
-       /* Find AAAA RRset with sig RRset */
-       result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa,
-                                    0, client->now, rdataset, sigrdataset);
-       /*
-        * If we can't promote glue/pending from the cache to secure
-        * then drop it.
-        */
-       if (result == ISC_R_SUCCESS &&
-           additionaltype == dns_rdatasetadditional_fromcache &&
-           (DNS_TRUST_PENDING(rdataset->trust) ||
-            DNS_TRUST_GLUE(rdataset->trust)) &&
-           !validate(client, db, fname, rdataset, sigrdataset)) {
-               dns_rdataset_disassociate(rdataset);
-               if (dns_rdataset_isassociated(sigrdataset))
-                       dns_rdataset_disassociate(sigrdataset);
-               result = ISC_R_NOTFOUND;
-       }
-       if (result == ISC_R_SUCCESS) {
-               ISC_LIST_APPEND(cfname.list, rdataset, link);
-               rdataset = NULL;
-               if (dns_rdataset_isassociated(sigrdataset)) {
-                       ISC_LIST_APPEND(cfname.list, sigrdataset, link);
-                       sigrdataset = NULL;
-               }
-       }
-
- setcache:
-       /*
-        * Set the new result in the cache if required.  We do not support
-        * caching additional data from a cache DB.
-        */
-       if (needadditionalcache == ISC_TRUE &&
-           (additionaltype == dns_rdatasetadditional_fromauth ||
-            additionaltype == dns_rdatasetadditional_fromglue)) {
-               (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
-                                                type, client->view->acache,
-                                                zone, db, version, node,
-                                                &cfname);
-       }
-
- foundcache:
-       need_sigrrset = ISC_FALSE;
-       mname0 = NULL;
-       for (crdataset = ISC_LIST_HEAD(cfname.list);
-            crdataset != NULL;
-            crdataset = crdataset_next) {
-               dns_name_t *mname;
-
-               crdataset_next = ISC_LIST_NEXT(crdataset, link);
-
-               mname = NULL;
-               if (crdataset->type == dns_rdatatype_a ||
-                   crdataset->type == dns_rdatatype_aaaa) {
-                       if (!query_isduplicate(client, fname, crdataset->type,
-                                              &mname)) {
-                               if (mname != fname) {
-                                       if (mname != NULL) {
-                                               /*
-                                                * A different type of this
-                                                * name is already stored
-                                                * in the additional
-                                                * section.  We'll reuse
-                                                * the name.  Note that
-                                                * this should happen at
-                                                * most once.  Otherwise,
-                                                * fname->link could leak
-                                                * below.
-                                                */
-                                               INSIST(mname0 == NULL);
-
-                                               query_releasename(client,
-                                                                 &fname);
-                                               fname = mname;
-                                               mname0 = mname;
-                                       } else
-                                               need_addname = ISC_TRUE;
-                               }
-                               ISC_LIST_UNLINK(cfname.list, crdataset, link);
-                               ISC_LIST_APPEND(fname->list, crdataset, link);
-                               added_something = ISC_TRUE;
-                               need_sigrrset = ISC_TRUE;
-                       } else
-                               need_sigrrset = ISC_FALSE;
-               } else if (crdataset->type == dns_rdatatype_rrsig &&
-                          need_sigrrset && WANTDNSSEC(client)) {
-                       ISC_LIST_UNLINK(cfname.list, crdataset, link);
-                       ISC_LIST_APPEND(fname->list, crdataset, link);
-                       added_something = ISC_TRUE; /* just in case */
-                       need_sigrrset = ISC_FALSE;
-               }
-       }
-
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: addname");
-
-       /*
-        * If we haven't added anything, then we're done.
-        */
-       if (!added_something)
-               goto cleanup;
-
-       /*
-        * We may have added our rdatasets to an existing name, if so, then
-        * need_addname will be ISC_FALSE.  Whether we used an existing name
-        * or a new one, we must set fname to NULL to prevent cleanup.
-        */
-       if (need_addname)
-               dns_message_addname(client->message, fname,
-                                   DNS_SECTION_ADDITIONAL);
-       fname = NULL;
-
- cleanup:
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: cleanup");
-
-       if (rdataset != NULL)
-               query_putrdataset(client, &rdataset);
-       if (sigrdataset != NULL)
-               query_putrdataset(client, &sigrdataset);
-       while  ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) {
-               ISC_LIST_UNLINK(cfname.list, crdataset, link);
-               query_putrdataset(client, &crdataset);
-       }
-       if (fname != NULL)
-               query_releasename(client, &fname);
-       if (node != NULL)
-               dns_db_detachnode(db, &node);
-       if (db != NULL)
-               dns_db_detach(&db);
-       if (zone != NULL)
-               dns_zone_detach(&zone);
-
-       CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: done");
-       return (eresult);
-}
-
 static inline void
 query_addrdataset(ns_client_t *client, dns_name_t *fname,
                  dns_rdataset_t *rdataset)
 {
-       client_additionalctx_t additionalctx;
-
        /*
         * Add 'rdataset' and any pertinent additional data to
         * 'fname', a name in the response message for 'client'.
@@ -2566,15 +2034,44 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
        if (NOADDITIONAL(client))
                return;
 
+       /*
+        * Try to process glue directly.
+        */
+       if ((client->view->minimalresponses == dns_minimal_yes) &&
+           (rdataset->type == dns_rdatatype_ns) &&
+           (client->query.gluedb != NULL) &&
+           dns_db_iszone(client->query.gluedb))
+       {
+               isc_result_t result;
+               ns_dbversion_t *dbversion;
+               unsigned int options = 0;
+
+               dbversion = query_findversion(client, client->query.gluedb);
+               if (dbversion == NULL)
+                       goto regular;
+
+#ifdef ALLOW_FILTER_AAAA
+               if (client->filter_aaaa == dns_aaaa_filter ||
+                   client->filter_aaaa == dns_aaaa_break_dnssec)
+               {
+                       options |= DNS_RDATASETADDGLUE_FILTERAAAA;
+               }
+#endif
+
+               result = dns_rdataset_addglue(rdataset, dbversion->version,
+                                             options, client->message);
+               if (result == ISC_R_SUCCESS)
+                       return;
+       }
+
+regular:
        /*
         * Add additional data.
         *
         * We don't care if dns_rdataset_additionaldata() fails.
         */
-       additionalctx.client = client;
-       additionalctx.rdataset = rdataset;
-       (void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
-                                         &additionalctx);
+       (void)dns_rdataset_additionaldata(rdataset, query_addadditional,
+                                         client);
        CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
 }
 
@@ -9894,8 +9391,7 @@ ns_query_start(ns_client_t *client) {
                break;
        }
 
-       if (client->view->cachedb == NULL || !client->view->additionalfromcache)
-       {
+       if (client->view->cachedb == NULL || !client->view->recursion) {
                /*
                 * We don't have a cache.  Turn off cache support and
                 * recursion.
index d9f779a3d1c452c3ba991f9697ff11d1ba4c5173..e7cebcdcc3c03945be25ae622539275253f0fbb6 100644 (file)
@@ -52,7 +52,6 @@
 
 #include <bind9/check.h>
 
-#include <dns/acache.h>
 #include <dns/adb.h>
 #include <dns/badcache.h>
 #include <dns/cache.h>
@@ -1279,12 +1278,14 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
 #if DNS_RDATASET_FIXED
                mode = DNS_RDATASETATTR_FIXEDORDER;
 #else
-               mode = 0;
+               mode = DNS_RDATASETATTR_CYCLIC;
 #endif /* DNS_RDATASET_FIXED */
        else if (!strcasecmp(str, "random"))
                mode = DNS_RDATASETATTR_RANDOMIZE;
        else if (!strcasecmp(str, "cyclic"))
-               mode = 0;
+               mode = DNS_RDATASETATTR_CYCLIC;
+       else if (!strcasecmp(str, "none"))
+               mode = DNS_RDATASETATTR_NONE;
        else
                INSIST(0);
 
@@ -2517,8 +2518,6 @@ configure_catz_zone(dns_view_t *view, const cfg_obj_t *config,
                        RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
 
                        dns_zone_setview(dnszone, view);
-                       if (view->acache != NULL)
-                               dns_zone_setacache(dnszone, view->acache);
                        dns_view_addzone(view, dnszone);
                }
 
@@ -3310,7 +3309,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
        unsigned int cleaning_interval;
        size_t max_cache_size;
        isc_uint32_t max_cache_size_percent = 0;
-       size_t max_acache_size;
        size_t max_adb_size;
        isc_uint32_t lame_ttl, fail_ttl;
        dns_tsig_keyring_t *ring = NULL;
@@ -3377,53 +3375,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
        CHECKM(ns_config_getport(config, &port), "port");
        dns_view_setdstport(view, port);
 
-       /*
-        * Create additional cache for this view and zones under the view
-        * if explicitly enabled.
-        * XXX950 default to on.
-        */
-       obj = NULL;
-       (void)ns_config_get(maps, "acache-enable", &obj);
-       if (obj != NULL && cfg_obj_asboolean(obj)) {
-               cmctx = NULL;
-               CHECK(isc_mem_create(0, 0, &cmctx));
-               CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr,
-                                       ns_g_timermgr));
-               isc_mem_setname(cmctx, "acache", NULL);
-               isc_mem_detach(&cmctx);
-       }
-       if (view->acache != NULL) {
-               obj = NULL;
-               result = ns_config_get(maps, "acache-cleaning-interval", &obj);
-               INSIST(result == ISC_R_SUCCESS);
-               dns_acache_setcleaninginterval(view->acache,
-                                              cfg_obj_asuint32(obj) * 60);
-
-               obj = NULL;
-               result = ns_config_get(maps, "max-acache-size", &obj);
-               INSIST(result == ISC_R_SUCCESS);
-               if (cfg_obj_isstring(obj)) {
-                       str = cfg_obj_asstring(obj);
-                       INSIST(strcasecmp(str, "unlimited") == 0);
-                       max_acache_size = 0;
-               } else {
-                       isc_resourcevalue_t value;
-                       value = cfg_obj_asuint64(obj);
-                       if (value > SIZE_MAX) {
-                               cfg_obj_log(obj, ns_g_lctx,
-                                           ISC_LOG_WARNING,
-                                           "'max-acache-size "
-                                           "%" ISC_PRINT_QUADFORMAT "u' "
-                                           "is too large for this "
-                                           "system; reducing to %lu",
-                                           value, (unsigned long)SIZE_MAX);
-                               value = SIZE_MAX;
-                       }
-                       max_acache_size = (size_t) value;
-               }
-               dns_acache_setcachesize(view->acache, max_acache_size);
-       }
-
        CHECK(configure_view_acl(vconfig, config, "allow-query", NULL, actx,
                                 ns_g_mctx, &view->queryacl));
        if (view->queryacl == NULL) {
@@ -4305,32 +4256,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
        INSIST(result == ISC_R_SUCCESS);
        view->trust_anchor_telemetry = cfg_obj_asboolean(obj);
 
-       /*
-        * Set sources where additional data and CNAME/DNAME
-        * targets for authoritative answers may be found.
-        */
-       obj = NULL;
-       result = ns_config_get(maps, "additional-from-auth", &obj);
-       INSIST(result == ISC_R_SUCCESS);
-       view->additionalfromauth = cfg_obj_asboolean(obj);
-       if (view->recursion && ! view->additionalfromauth) {
-               cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING,
-                           "'additional-from-auth no' is only supported "
-                           "with 'recursion no'");
-               view->additionalfromauth = ISC_TRUE;
-       }
-
-       obj = NULL;
-       result = ns_config_get(maps, "additional-from-cache", &obj);
-       INSIST(result == ISC_R_SUCCESS);
-       view->additionalfromcache = cfg_obj_asboolean(obj);
-       if (view->recursion && ! view->additionalfromcache) {
-               cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING,
-                           "'additional-from-cache no' is only supported "
-                           "with 'recursion no'");
-               view->additionalfromcache = ISC_TRUE;
-       }
-
        /*
         * Set "allow-query-cache", "allow-query-cache-on",
         * "allow-recursion", and "allow-recursion-on" acls if
@@ -5600,8 +5525,6 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                 * new view.
                 */
                dns_zone_setview(zone, view);
-               if (view->acache != NULL)
-                       dns_zone_setacache(zone, view->acache);
        } else {
                /*
                 * We cannot reuse an existing zone, we have
@@ -5610,8 +5533,6 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
                CHECK(dns_zone_setorigin(zone, origin));
                dns_zone_setview(zone, view);
-               if (view->acache != NULL)
-                       dns_zone_setacache(zone, view->acache);
                CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
                dns_zone_setstats(zone, ns_g_server->zonestats);
        }
@@ -5670,8 +5591,6 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                        CHECK(dns_zone_create(&raw, mctx));
                        CHECK(dns_zone_setorigin(raw, origin));
                        dns_zone_setview(raw, view);
-                       if (view->acache != NULL)
-                               dns_zone_setacache(raw, view->acache);
                        dns_zone_setstats(raw, ns_g_server->zonestats);
                        CHECK(dns_zone_link(zone, raw));
                }
@@ -5768,9 +5687,6 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
 
        CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
 
-       if (view->acache != NULL)
-               dns_zone_setacache(zone, view->acache);
-
        CHECK(dns_acl_none(mctx, &none));
        dns_zone_setqueryacl(zone, none);
        dns_zone_setqueryonacl(zone, none);
index 4defa26fc5c3fb2cc42756d59b3c79c0bde2f9a8..526896fdefe5f0aa3043118f3f5fe33ad52f0ada 100644 (file)
@@ -13,7 +13,6 @@ options {
        notify-source 10.53.0.1;
        transfer-source 10.53.0.1;
        recursion no;
-       additional-from-auth no;
        port 5300;
        pid-file "named.pid";
        listen-on { 10.53.0.1; };
index c509807b84697eca03ef01007979372b5588f9bf..d24d05f736b1c76210ebede157065e39b94b93f7 100644 (file)
@@ -13,7 +13,6 @@ options {
        notify-source 10.53.0.1;
        transfer-source 10.53.0.1;
        recursion no;
-       additional-from-auth no;
        port 5300;
        pid-file "named.pid";
        listen-on { 10.53.0.1; };
index 43b3bcaab13430e2854b2006518e77e13829f28f..b18a7e016e99b65b1c3a3104f51da5fdf0c4c58b 100644 (file)
@@ -11,7 +11,6 @@ options {
        notify-source 10.53.0.1;
        transfer-source 10.53.0.1;
        recursion no;
-       additional-from-auth no;
        port 5300;
        pid-file "named.pid";
        listen-on { 10.53.0.1; };
index 234225c57ce44e7ebe53522460cd8e304d6a3b59..1c98d82bf21e46999c5af42813426c585143cef4 100644 (file)
@@ -11,7 +11,6 @@ options {
        notify-source 10.53.0.1;
        transfer-source 10.53.0.1;
        recursion no;
-       additional-from-auth no;
        port 5300;
        pid-file "named.pid";
        listen-on { 10.53.0.1; };
index 45d7c4115fcad4a5bfed1e719b5e0732f60ab421..c3c7183d128f52b61dfbc93217fb4a0515048cae 100644 (file)
@@ -6,7 +6,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-rm -f */K* */dsset-* */*.signed */trusted.conf */tmp* */*.jnl */*.bk
+rm -f */K* */dsset-* */*.signed */tmp* */*.jnl */*.bk
+rm -f */trusted.conf */private.conf
 rm -f */core
 rm -f */example.bk
 rm -f */named.memstats
index 5acb99a3153b86c3dc38da2f78a7b16a1e6ac81e..8a7617a7724932ad38d8fd0f23d4bb288b0aaacd 100644 (file)
@@ -31,9 +31,19 @@ $DSFROMKEY $kskname.key > dsset-${zone}$TP
 zone=private.secure.example
 zonefile="${zone}.db"
 infile="${zonefile}.in"
-cp $infile $zonefile
-$KEYGEN -3 -q -r $RANDFILE -fk $zone > /dev/null
+ksk=`$KEYGEN -3 -q -r $RANDFILE -fk $zone`
 $KEYGEN -3 -q -r $RANDFILE $zone > /dev/null
+cat $ksk.key | grep -v '^; ' | $PERL -n -e '
+local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
+local $key = join("", @rest);
+print <<EOF
+trusted-keys {
+    "$dn" $flags $proto $alg "$key";
+};
+EOF
+' > private.conf
+cp private.conf ../ns4/private.conf
+$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile > /dev/null 2>&1
 
 # Extract saved keys for the revoke-to-duplicate-key test
 zone=bar
index d4884ea42ae68691142a63f7c52cb7e563bd82b0..adde75600cde5294ae8fdf86fd156aded9f1f70a 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.3 2009/11/30 23:48:02 tbox Exp $ */
-
 // NS4
 
 controls { /* empty */ };
@@ -21,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation yes;
        dnssec-must-be-secure mustbesecure.example yes;
@@ -33,3 +30,4 @@ zone "." {
 };
 
 include "trusted.conf";
+include "private.conf";
index 0655efe3c1e29539d8c3a7d8a4a9d896b55e2e43..5e342475fb60aad83cf8bfc591b7f5f442f5aa5a 100644 (file)
@@ -21,7 +21,6 @@ options {
        listen-on { 10.53.0.5; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation yes;
 };
index e22523d1e491faab6884306b79717b1b6d74f088..df13fdd8a0562afb74ac66409fd10823345ffdc7 100644 (file)
@@ -692,8 +692,7 @@ $DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.4 \
        > dig.out.ns4.test$n || ret=1
 $PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
-# Note - this is looking for failure, hence the &&
-grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
 n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
@@ -714,13 +713,9 @@ status=`expr $status + $ret`
 
 echo "I:checking privately secure to nxdomain works ($n)"
 ret=0
-$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.2 \
-       > dig.out.ns2.test$n || ret=1
-$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 \
-       > dig.out.ns4.test$n || ret=1
-$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
-# Note - this is looking for failure, hence the &&
-grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
+$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
 n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
index c14cf1090859ca4cbc5dc20df82fdecd84ff08ba..d8721f330633b4063d284d937c7603c5a9236421 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.11 2011/08/02 23:47:52 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -21,6 +19,7 @@ options {
        recursion no;
        notify yes;
        check-integrity no;
+       minimal-responses no;
 };
 
 zone "." {
index c6c2c781b049f17ff82a7b227f36cf5c059293bb..4828e85e357aaccfe801a5253dcfaa7491b4fa75 100644 (file)
@@ -20,6 +20,7 @@ options {
        notify yes;
        ixfr-from-differences yes;
        check-integrity no;
+       minimal-responses no;
 };
 
 zone "example" {
index c00fff8c40b13b36d1bf93232f88b02ab34af350..6c64816786d4c0deade1b82488eded5ba8b0a84f 100644 (file)
@@ -21,6 +21,7 @@ options {
        ixfr-from-differences yes;
        check-integrity no;
        no-case-compress { 10.53.0.2; };
+       minimal-responses no;
 };
 
 zone "example" {
index ab31b71b9afa0499bbc7c4c624e91b109c92af3a..d4c82b93ad52869b50a39e0304ab8b69e6164574 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        check-names response warn;
        notify yes;
 };
index 952d3640c59d1afaf9a9dbf216159e3c239227f5..03f98410c8f015f56a84a3bee9926340010b6920 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        check-names response fail;
        notify yes;
 };
index 96505936e2534456749cf2dc0f4f960a5ddc549b..b89e383f13ac80a6b18d411cda95236982b38f22 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        check-names master ignore;
        notify yes;
 };
index e667155710c67dff5d4c2374fdc9a8d261dacd5a..c80634dd57f44303549d65beebbd3b91e251e3f5 100644 (file)
@@ -24,7 +24,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
                 except-from { "example.org"; };
        deny-answer-aliases { "example.org"; }
index 58fe79655bfbc033eb8714f55238729e4e31faae..c734c1d7346a617cf99705ad7e2b0e81e39dcd2d 100644 (file)
@@ -17,7 +17,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion no;
-       acache-enable yes;
        send-cookie yes;
        nocookie-udp-size 512;
 };
index 220dd3e4b6ea3bd44dd7d75c319fa1e1975d02f6..904130ae94bb84a56868a2f8437560f0c7f92b7e 100644 (file)
@@ -24,7 +24,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
                 except-from { "example.org"; };
        deny-answer-aliases { "example.org"; }
index fcd2abc6dda7264a3b3fc51fdb0bb27072d714fd..8f20f222dec7cd8eb053784944e1c77e7901feb6 100644 (file)
@@ -15,7 +15,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { fd92:7065:b8e:ffff::3; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable no;
        dnssec-validation no;
        server-id "ns3";
index 49b192f3bccde1a1afee1a8f84dc759491db2f0b..261f29d7583e3f3aa79f4e8093a05b107243ea39 100644 (file)
@@ -49,7 +49,6 @@ options {
        listen-on { 10.53.0.5; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
        dnssec-enable yes;
        dnssec-validation yes;
index fa13a4d70cf607838c113b3f77c1be899b2cca4d..ca3ce877b57d123d8e42141173a1af97ee4ca1f6 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.36 2011/03/21 23:47:21 tbox Exp $ */
-
 // NS2
 
 controls { /* empty */ };
@@ -25,6 +23,7 @@ options {
        dnssec-enable yes;
        dnssec-validation yes;
        notify-delay 1;
+       minimal-responses no;
 };
 
 zone "." {
index 5eb6913200b8447618f1fe426ee861a216f0b688..4ed21a5638e9334b97753f9a9ada2d94ee917721 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.49 2011/10/28 06:20:05 each Exp $ */
-
 // NS3
 
 controls { /* empty */ };
@@ -25,6 +23,7 @@ options {
        dnssec-enable yes;
        dnssec-validation yes;
        session-keyfile "session.key";
+       minimal-responses no;
 };
 
 key rndc_key {
index b350389b6b55777436ddcee7e96304a6135a236b..755db4708517f4eb44255dd5f222835c14101a24 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named1.conf,v 1.3 2011/01/04 23:47:13 tbox Exp $ */
-
 // NS4
 
 controls { /* empty */ };
@@ -21,10 +19,10 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation yes;
        dnssec-must-be-secure mustbesecure.example yes;
+       minimal-responses no;
 
        nta-lifetime 10s;
        nta-recheck 7s;
index 511a243c86b8c23df78277e4b733ab68f710b4ac..6fa51f6acb46661e6d521c5a152423d6d8536355 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named2.conf,v 1.3 2011/01/04 23:47:13 tbox Exp $ */
-
 // NS4
 
 controls { /* empty */ };
@@ -22,10 +20,10 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation auto;
        bindkeys-file "managed.conf";
+       minimal-responses no;
 };
 
 key rndc_key {
index 57648ae9662d1f382edf161a083f53327a08dada..b54465f19293ba9509412afb3be8989673107132 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named2.conf,v 1.3 2011/01/04 23:47:13 tbox Exp $ */
-
 // NS4
 
 controls { /* empty */ };
@@ -21,11 +19,11 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation auto;
        bindkeys-file "managed.conf";
        dnssec-accept-expired yes;
+       minimal-responses no;
 };
 
 key rndc_key {
index 98f52f49d14128c4236b6a4794fb7ca2e50adebb..d63f37676e4211231027bd71bfb1419d4f88ee3a 100644 (file)
@@ -38,4 +38,48 @@ controls {
 zone "." {
        type hint;
        file "../../common/root.hint";
+}
+
+key auth {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+include "trusted.conf";
+
+view rec {
+       match-recursive-only yes;
+       recursion yes;
+       dnssec-validation yes;
+       dnssec-accept-expired yes;
+
+       zone "." {
+               type hint;
+               file "../../common/root.hint";
+       };
+
+       zone secure.example {
+               type static-stub;
+               server-addresses { 10.53.0.4; };
+       };
+
+       zone insecure.secure.example {
+               type static-stub;
+               server-addresses { 10.53.0.4; };
+       };
+};
+
+view auth {
+       recursion no;
+       allow-recursion { none; };
+
+       zone secure.example {
+               type slave;
+               masters { 10.53.0.3; };
+       };
+
+       zone insecure.secure.example {
+               type slave;
+               masters { 10.53.0.2; };
+       };
 };
index 9d03236a864e83ec2b7059f64528a69bb80bc527..4bac1daa2508ab9f1a9e8fba014c77f42f1b008a 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.5; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation yes;
 };
index 1153abc90c13d358cff4c9059841ba8907ad3e7a..b071e80e31bf18015b6817096d97c59bac37dd68 100644 (file)
@@ -21,7 +21,6 @@ options {
        listen-on { 10.53.0.6; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
        disable-algorithms . { DSA; };
        dnssec-enable yes;
index 9f6d6703bef7ec434d340bfbc379a95af9dfe35e..f365a91b2475d3abf510cfef103efdcedbbb68ff 100644 (file)
@@ -1187,11 +1187,9 @@ status=`expr $status + $ret`
 
 echo "I:checking privately secure to nxdomain works ($n)"
 ret=0
-$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.2 \
-       > dig.out.ns2.test$n || ret=1
 $DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 \
        > dig.out.ns4.test$n || ret=1
-$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
+grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
 # Note - this is looking for failure, hence the &&
 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
 n=`expr $n + 1`
@@ -1200,11 +1198,9 @@ status=`expr $status + $ret`
 
 echo "I:checking privately secure wildcard to nxdomain works ($n)"
 ret=0
-$DIG $DIGOPTS +noauth a.wild.private.secure.example. SOA @10.53.0.2 \
-       > dig.out.ns2.test$n || ret=1
 $DIG $DIGOPTS +noauth a.wild.private.secure.example. SOA @10.53.0.4 \
        > dig.out.ns4.test$n || ret=1
-$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
+grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
 # Note - this is looking for failure, hence the &&
 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
 n=`expr $n + 1`
index a409356e6594e171717fc3b074d7cf042d33cd3e..088bfd73c70561cf0edd76bfc1327d5cde6403ef 100644 (file)
@@ -26,7 +26,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
                 except-from { "example.org"; };
        deny-answer-aliases { "example.org"; }
index 9989a680203fcee4fcd3dfe198a65dffb219fabe..109eba2f7bea301752ec80162e3ea54ff8d1e5a4 100644 (file)
@@ -26,7 +26,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
                 except-from { "example.org"; };
        deny-answer-aliases { "example.org"; }
index 2d2c2fe87e7d9e8d6f56842fec486cdcab591fff..4c6f8f982544a4c3e6abd9f69820bfa8809aa70f 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v4 yes;
        filter-aaaa { 10.53.0.1; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 6feb6c3dd4efb688f0a660e15ce523883585a970..a97a41265a4909196defab8cd55e2f1e55c7cd0e 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v6 yes;
        filter-aaaa { fd92:7065:b8e:ffff::1; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 6610f2743f542b22fa97f28b5de2281085a685ac..654e8fc72f481205c821814c2d76c307142b2f50 100644 (file)
@@ -4,13 +4,17 @@
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-; $Id: root.db,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
 $TTL   120
 @              SOA     ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 )
 @              NS      ns.utld
 ns.utld                A       10.53.0.1
 ns.utld                AAAA    fd92:7065:b8e:ffff::1
 ;
-signed         NS      ns.utld
-unsigned       NS      ns.utld
+
+signed         NS      ns.signed
+ns.signed      A       10.53.0.1
+ns.signed      AAAA    fd92:7065:b8e:ffff::1
+
+unsigned       NS      ns.unsigned
+ns.unsigned    A       10.53.0.1
+ns.unsigned    AAAA    fd92:7065:b8e:ffff::1
index 19ca8144b690aefe49f03fa2648794b59775c8b4..48ced0c20e1eead79653995a1296657bf3d5af62 100644 (file)
@@ -4,12 +4,14 @@
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-; $Id: signed.db.in,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
 $TTL   120
-@              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
-@              NS      ns.utld.
+@              SOA     ns.signed.  hostmaster.ns.signed. ( 1 3600 1200 604800 60 )
+@              NS      ns
 @               MX      10 mx
+
+ns             A       10.53.0.1
+               AAAA    fd92:7065:b8e:ffff::1
+
 a-only         NS      1.0.0.1
 aaaa-only      AAAA    2001:db8::2
 dual           A       1.0.0.3
index 69816a86b79fc90a3fed8bc458c1df3761b55d59..b2ffea9c83c70a5b51be0b604cd4014bd67b9e9d 100644 (file)
@@ -4,12 +4,14 @@
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-; $Id: unsigned.db,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
 $TTL   120
-@              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
-@              NS      ns.utld.
+@              SOA     ns.unsigned.  hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 )
+@              NS      ns
 @               MX      10 mx
+
+ns             A       10.53.0.1
+               AAAA    fd92:7065:b8e:ffff::1
+
 a-only         NS      1.0.0.4
 aaaa-only      AAAA    2001:db8::5
 dual           A       1.0.0.6
index 96355eba11ecbc045befd45d6c7906a8b276cff6..44c9afb1065a519f5ea1f4a735eaca228082b847 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v4 yes;
        filter-aaaa { 10.53.0.2; };
+       minimal-responses no;
 };
 
 key rndc_key {
index be0c566cca9fc34a8b9aad4af4287fd3abcbb45c..bd4880e165295b0ed3ff6cd44767890d56779f1b 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v6 yes;
        filter-aaaa { fd92:7065:b8e:ffff::2; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 5b451187e6dfb37506776465589692e246a7886d..7f76f0ddc4ce400a70cb694816c41d7ccf9860a2 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v4 break-dnssec;
        filter-aaaa { 10.53.0.3; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 4284fb36008067d69b8148adfbe325ef9682d953..239b6768f062379f95f13551eb20d00f46351fd5 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v6 break-dnssec;
        filter-aaaa { fd92:7065:b8e:ffff::3; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 6666f04f035cfe1d7f50e208a179f7da70f0993f..2b4cb8b5502ea3c633dc6e9d32b62a56e993c96d 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v4 break-dnssec;
        filter-aaaa { 10.53.0.4; };
+       minimal-responses no;
 };
 
 key rndc_key {
index c85ba5a5ac1df91521836132f10aca64af02ea7d..5abefc0b9de8582791fee332d04792ddc3a680c0 100644 (file)
@@ -22,6 +22,7 @@ options {
        notify yes;
        filter-aaaa-on-v6 break-dnssec;
        filter-aaaa { fd92:7065:b8e:ffff::4; };
+       minimal-responses no;
 };
 
 key rndc_key {
index 6610f2743f542b22fa97f28b5de2281085a685ac..ba2a5d55c633a61579ef5d44e81dea1a8665118e 100644 (file)
@@ -5,12 +5,16 @@
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ; $Id: root.db,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
-$TTL   120
 @              SOA     ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 )
 @              NS      ns.utld
-ns.utld                A       10.53.0.1
-ns.utld                AAAA    fd92:7065:b8e:ffff::1
+ns.utld                A       10.53.0.4
+ns.utld                AAAA    fd92:7065:b8e:ffff::4
 ;
-signed         NS      ns.utld
-unsigned       NS      ns.utld
+
+signed         NS      ns.signed
+ns.signed      A       10.53.0.4
+ns.signed      AAAA    fd92:7065:b8e:ffff::4
+
+unsigned       NS      ns.unsigned
+ns.unsigned    A       10.53.0.4
+ns.unsigned    AAAA    fd92:7065:b8e:ffff::4
index 19ca8144b690aefe49f03fa2648794b59775c8b4..c17b82849f5711eb42046d3e09df0500b2a8b76f 100644 (file)
@@ -4,12 +4,14 @@
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-; $Id: signed.db.in,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
 $TTL   120
-@              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
-@              NS      ns.utld.
+@              SOA     ns.signed.  hostmaster.ns.signed. ( 1 3600 1200 604800 60 )
+@              NS      ns
 @               MX      10 mx
+
+ns             A       10.53.0.4
+               AAAA    fd92:7065:b8e:ffff::4
+
 a-only         NS      1.0.0.1
 aaaa-only      AAAA    2001:db8::2
 dual           A       1.0.0.3
index 69816a86b79fc90a3fed8bc458c1df3761b55d59..8c660bb53a35e49595aeff621516978767996e7c 100644 (file)
@@ -4,12 +4,14 @@
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-; $Id: unsigned.db,v 1.4 2012/01/31 23:47:32 tbox Exp $
-
 $TTL   120
-@              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
-@              NS      ns.utld.
+@              SOA     ns.unsigned.  hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 )
+@              NS      ns
 @               MX      10 mx
+
+ns             A       10.53.0.4
+               AAAA    fd92:7065:b8e:ffff::4
+
 a-only         NS      1.0.0.4
 aaaa-only      AAAA    2001:db8::5
 dual           A       1.0.0.6
index b90b43d2d1aa215eee9922a12d41bcd0e1134f55..5353d3131d291946319f3451b85ff9855730365c 100644 (file)
@@ -55,13 +55,3 @@ NISC.JVNC.NET.          172800  IN      A       128.121.50.7
 NS.EU.NET.              172800  IN      A       192.16.202.11
 SPARKY.ARL.MIL.         172800  IN      A       128.63.58.18
 SUNIC.SUNET.SE.         172800  IN      A       192.36.125.2
-
-;
-; A hypothetical ccTLD where we are authoritative for the NS glue.
-;
-xx.                    172800  IN      NS      b.root-servers.nil.
-
-;
-; A hypothetical ccTLD where we have cached NS glue.
-;
-yy.                    172800  IN      NS      ns.zz.
index 1d357867f39a6d2b78b9f5a8c4f380f5fe38793f..98a41b22b3355ac27af744c12af3bddc47e234a3 100644 (file)
@@ -21,14 +21,6 @@ echo "I:testing that a ccTLD referral gets a full glue set from the root zone"
 $DIG +norec @10.53.0.1 -p 5300 foo.bar.fi. A >dig.out || status=1
 $PERL ../digcomp.pl --lc fi.good dig.out || status=1
 
-echo "I:testing that we find glue A RRs we are authoritative for"
-$DIG +norec @10.53.0.1 -p 5300 foo.bar.xx. a >dig.out || status=1
-$PERL ../digcomp.pl xx.good dig.out || status=1
-
-echo "I:testing that we find glue A/AAAA RRs in the cache"
-$DIG +norec @10.53.0.1 -p 5300 foo.bar.yy. a >dig.out || status=1
-$PERL ../digcomp.pl yy.good dig.out || status=1
-
 echo "I:testing that we don't find out-of-zone glue"
 $DIG +norec @10.53.0.1 -p 5300 example.net. a > dig.out || status=1
 $PERL ../digcomp.pl noglue.good dig.out || status=1
index 2c62c84dc27572a36c76d9c9ff5435dba4b7d5bc..7fb72a8fb57903d0dfc0e1ce87a3314e52379761 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.14 2007/06/19 23:47:03 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -20,6 +18,7 @@ options {
        listen-on-v6 { none; };
        recursion no;
        notify yes;
+       minimal-responses no;
 };
 
 zone "." {
index abb5e390f10b3d8b37d79a7c1afe9c5b4ef263cd..3a8ad09d238d46442f7f5ca59d66995340aaf7f2 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index f279a65ce120a1901c7899b85d2dda372535a6bb..fe7d6f94e2940a33a8a3d50637fa876d354730d5 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 24232903ba75280395af187b3b83a5f0afe3bf32..989e709b06cab75041c6462aac563b61dc521cd1 100644 (file)
@@ -34,7 +34,6 @@ options {
        listen-on { 10.53.0.5; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 350792837e0ab2fedd41ef535c8580105d938064..78d1cbfb66b6a95e1a1ac048e8545cb0791c8d41 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.22 2011/07/01 02:25:47 marka Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -21,6 +19,7 @@ options {
        listen-on-v6 { none; };
        recursion no;
        notify yes;
+       minimal-responses no;
 };
 
 key rndc_key {
index a14af0e2d9ea6afde9958afde36a21e1ff0f90f8..4a6ea2c28fcd599db1501997108047df6574fed3 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index d775c365ae3b7ac29ff6586390d7ddbc5c5b9b13..2b370d1bfc4d2c6635c27541b8202a8824c055a0 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
                 except-from { "example.org"; };
        deny-answer-aliases { "example.org"; }
index d0aeb8351220d7955cd05eb0ec16ad15dd778de0..d64d150c2779306a4af659a6e473d3a607ab573f 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
 
 controls { /* empty */ };
 
@@ -21,6 +19,7 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        notify no;
+       minimal-responses no;
 };
 
 zone "." {type master; file "root.db";};
index bbb6a0d6e4408a84d27baa73719f965335f5a179..7c4dab4c0a672bbc2499fc779ef53026e3d14e6c 100644 (file)
@@ -6,9 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
-
 
 controls { /* empty */ };
 
@@ -22,6 +19,7 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        notify no;
+       minimal-responses no;
 };
 
 key rndc_key {
index d935845ee986d586d79c60853ae6de48928333a0..5bb696b7c17fe9f9c1d8afa984dfd05ed73e5511 100644 (file)
@@ -6,9 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
-
 
 /*
  * Main rpz test DNS server.
@@ -25,6 +22,7 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        notify no;
+       minimal-responses no;
 
        response-policy {
            zone "bl"                                   max-policy-ttl 100;
index 097e34f2a52b9ffa48fd36b42d45efae0658523d..61cbf01d752fb11417b4b15f36644f7f9229d726 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
 
 controls { /* empty */ };
 
@@ -21,6 +19,7 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        notify no;
+       minimal-responses no;
 };
 
 include "../trusted.conf";
index 80aaa5713f5b63ba37ea5c9b98c632006df8c872..1535f29bfb3b64494464a38d3aef3ed15c338c5f 100644 (file)
@@ -6,9 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
-
 
 /*
  * Test rpz performance.
@@ -27,6 +24,7 @@ options {
        ixfr-from-differences yes;
        notify-delay 1;
        notify yes;
+       minimal-responses no;
 
        # turn rpz on or off
        include "rpz-switch";
index 30d7638c35a6c05b318fdba302210a0a70419203..e7015e7f1faf5970999162df6c48e1674f6aeb77 100644 (file)
@@ -18,6 +18,7 @@ options {
        listen-on-v6 { none; };
        forward only;
        forwarders { 10.53.0.3; };
+       minimal-responses no;
 
        response-policy { zone "policy1" min-update-interval 0; };
 };
index df84a1f939552e9a82d2da2211bf026b04bff491..54627736b8e6692e6de26b9f19349179e38c42c3 100644 (file)
@@ -16,6 +16,7 @@ options {
        session-keyfile "session.key";
        listen-on { 10.53.0.7; };
        listen-on-v6 { none; };
+       minimal-responses no;
 
        response-policy { zone "policy2"; }
                qname-wait-recurse no
index 648f788ec5d10df48664017909d460369b410532..a5b3b2c6ae5e075a4930bd3a6731e6ded3be6704 100644 (file)
@@ -30,8 +30,6 @@ options {
            min-table-size 0;
            max-table-size 0;
        };
-
-       additional-from-cache no;
 };
 
 key rndc_key {
index 0ef65f50520a37065246a68844873cc38d96a620..292bae5000a55142d28efb6894ee3213ce2cb1a9 100644 (file)
@@ -30,8 +30,6 @@ options {
            // small enough to force a table expansion
            min-table-size 75;
        };
-
-       additional-from-cache no;
 };
 
 key rndc_key {
index 0cd12584744d488a7818132d86ac565d8f446d65..9f6a310a66d6266f4908e86f90860da9ca6570cf 100644 (file)
@@ -31,8 +31,6 @@ options {
            // small enough to force a table expansion
            min-table-size 75;
        };
-
-       additional-from-cache no;
 };
 
 key rndc_key {
index 9bc608afacf164569bad84c12699e7464d81160a..0fe762c2c7767c1e80ee2b3054af0cece448e18c 100644 (file)
@@ -6,10 +6,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# $Id: clean.sh,v 1.10 2011/12/23 23:47:13 tbox Exp $
-
 rm -f dig.out.test*
-rm -f dig.out.cyclic dig.out.fixed dig.out.random
+rm -f dig.out.cyclic dig.out.fixed dig.out.random dig.out.nomatch
 rm -f dig.out.0 dig.out.1 dig.out.2 dig.out.3
 rm -f dig.out.cyclic2
 rm -f ns2/root.bk
index 70ca5e30498192cedfcbd06c227555ae70742140..806ee2d4d58c44518fa4c4fcda9cd7fbf6051de1 100644 (file)
@@ -36,3 +36,8 @@ cyclic2.example.      A       1.2.3.4
 cyclic2.example.       A       1.2.3.3
 cyclic2.example.       A       1.2.3.2
 cyclic2.example.       A       1.2.3.1
+;
+nomatch.example.       A       1.2.3.1
+nomatch.example.       A       1.2.3.2
+nomatch.example.       A       1.2.3.3
+nomatch.example.       A       1.2.3.4
index 268ec01824e0aaa80e0f535e669c7eaaf1c71182..4e4d16f118f3101cd99348ccc85f19a54355eae8 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
        rrset-order {
                name "fixed.example" order fixed;
index 9eca63d87d4d5de0eb08e0fec84c61075408726e..1839c77f81be03f31aac3d805dabfe7533a0b0dc 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
        rrset-order {
                class IN type A name "host.example.com" order random;
index b2b5db3a8d9bfc8f1deded383032bd64dd135a55..445764d57c590b2ad0582ef3566e7cb07955ffc6 100644 (file)
@@ -438,7 +438,7 @@ echo "I: Random selection return $match of 24 possible orders in 36 samples"
 if [ $match -lt 8 ]; then echo ret=1; fi
 if [ $ret != 0 ]; then echo "I:failed"; fi
 
-echo "I: Checking default order no match in rrset-order (random)"
+echo "I: Checking default order no match in rrset-order (no shuffling)"
 ret=0
 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 do
@@ -447,11 +447,11 @@ done
 for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 9
 do
 $DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-       -p 5300 @10.53.0.4 random.example > dig.out.random|| ret=1
+       -p 5300 @10.53.0.4 nomatch.example > dig.out.nomatch|| ret=1
        match=0
        for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
        do
-               eval "$DIFF dig.out.random dig.out.random.good$j >/dev/null && match$j=1 match=1"
+               eval "$DIFF dig.out.nomatch dig.out.random.good$j >/dev/null && match$j=1 match=1"
                if [ $match -eq 1 ]; then break; fi
        done
        if [ $match -eq 0 ]; then ret=1; fi
@@ -461,8 +461,8 @@ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 do
 eval "match=\`expr \$match + \$match$i\`"
 done
-echo "I: Random selection return $match of 24 possible orders in 36 samples"
-if [ $match -lt 8 ]; then echo ret=1; fi
+echo "I: Consistent selection return $match of 24 possible orders in 36 samples"
+if [ $match -ne 1 ]; then echo ret=1; fi
 if [ $ret != 0 ]; then echo "I:failed"; fi
 
 status=`expr $status + $ret`
index eda50aecbfddd1b9b1096a8fdd454bf40f80a311..ae1b997a36475bdf2a47e27b3a262f392a59557c 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.5; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        dnssec-enable yes;
        dnssec-validation yes;
        servfail-ttl 30;
index 1798f5fdcec563ffe9f9c75cb35666408fb1ec80..ff7b2c221ffba6d567e07cd6c4b546211e2121fc 100644 (file)
@@ -18,6 +18,7 @@ options {
        listen-on-v6 { none; };
        recursion no;
        notify yes;
+       minimal-responses no;
        version none;  // make statistics independent of the version number
 };
 
index afe85ac2c866613ba75db4e3ceeabafac472ad77..965eae48a29dc2f42ed60f580ac57db32802c3b8 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 72540ab558e23f56505eeb88755b2b585d9a294f..c88bbff978ea9f5d29b5e1ecd58af0c2c2ef966c 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 7b70dd69555796d7ad70d08a88ed824c4fafd39e..da7e82c466a7241c33f32817fbc05d853242dc73 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.14 2007/06/19 23:47:05 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -20,6 +18,7 @@ options {
        listen-on-v6 { none; };
        recursion no;
        notify yes;
+       minimal-responses no;
 };
 
 zone "." {
index 584f620d264b39ea14222c32573a175dd3af01ca..04d4a5113a40700d7165e101340071206a3afb02 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.14 2007/06/19 23:47:05 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -20,6 +18,7 @@ options {
        listen-on-v6 { none; };
        recursion no;
        notify yes;
+       minimal-responses no;
 };
 
 zone "." {
index 36711256e96b3027014f68a0adc97c0c0e218c95..78ce6ab9728e1f04d548015764db472c043e2130 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.16 2007/06/18 23:47:31 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
@@ -19,8 +17,8 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
+       minimal-responses no;
 };
 
 zone "." {
index 50c1de943e031974efb0aa56ddecc3ceef7e01d0..2cec631d36fbfd1ae685e80f095c847e583689eb 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf.in,v 1.10 2011/11/03 23:46:26 tbox Exp $ */
-
 controls { /* empty */ };
 
 options {
index 04d179fe29aca2ec2ab8793b15833be3b0c5fae7..beca196d7ea5779cfb1613f79a18cc49f5b4967d 100644 (file)
@@ -6,8 +6,6 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# $Id: tests.sh,v 1.11 2011/11/03 23:46:26 tbox Exp $
-
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
@@ -41,7 +39,7 @@ do
 
        echo "I:checking the new key"
        ret=0
-       $DIG $DIGOPTS . ns -k $keyname > dig.out.1 || ret=1
+       $DIG $DIGOPTS txt txt.example -k $keyname > dig.out.1 || ret=1
        grep "status: NOERROR" dig.out.1 > /dev/null || ret=1
        grep "TSIG.*hmac-md5.*NOERROR" dig.out.1 > /dev/null || ret=1
        grep "Some TSIG could not be validated" dig.out.1 > /dev/null && ret=1
@@ -60,7 +58,7 @@ do
 
        echo "I:checking that new key has been deleted"
        ret=0
-       $DIG $DIGOPTS . ns -k $keyname > dig.out.2 || ret=1
+       $DIG $DIGOPTS txt txt.example -k $keyname > dig.out.2 || ret=1
        grep "status: NOERROR" dig.out.2 > /dev/null && ret=1
        grep "TSIG.*hmac-md5.*NOERROR" dig.out.2 > /dev/null && ret=1
        grep "Some TSIG could not be validated" dig.out.2 > /dev/null || ret=1
index bc5f97d034b281c04e44d34412f27ca7f34d44c2..ed2f3038e7a031dfa03f57f0a93f7031f9ca5c79 100644 (file)
@@ -24,7 +24,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 77ccb343904bfc476f0edb2cb53a36cbe6e2db9d..c53c1e3e05eddb962873f7ec970b1a6a6440f45c 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 7a0268ed32bbe209c09b4350375e312b6089bf5f..297fe8b3885bc8b035359e3d82fe5f20a99a8240 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 7474de421921d0f573dc5c3cd10cef4f34967a55..b7d0506d5a67373b617bccd2936613c439d1c0ef 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 088c8d7f4224ce495f3f550d9c32d7f8fbf3b4f0..3fbc58ae7a9f5367130f0a4bd665a3a3e48f1815 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
        allow-v6-synthesis { any; };
 };
index 1cb5bb86679e000754910393beadb18f077821da..6e19f9e488c6d8e42e4494b4dafca2375b777bc0 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
        notify yes;
 };
 
index 254bbbbc3b181a30a7156ae5a7c49a8bf4f3ae63..62cd0c44d9bd42ef75f7ffe75689336396dab9f6 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.1; };
        listen-on-v6 { none; };
        recursion no;
-       acache-enable yes;
 };
 
 zone "." {
index 41ff034ba58ff999c27c2d7d2910762ca99c7a0e..13f9d27a14fe22c64d35ddcace87038a636d0630 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.2; };
        listen-on-v6 { none; };
        recursion no;
-       acache-enable yes;
 };
 
 zone "example" {
index 6ed386441fcb6aeecce53bc9121a4f1741579048..698e95336793dfca7a8967da171accdd712cf287 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.3; };
        listen-on-v6 { none; };
        recursion yes;
-       acache-enable yes;
 };
 
 zone "." {
index 9eac45891d926f7655aec2107751264eb6fe8652..8d04d6ebe478cffca24f8d30eda2841188182a70 100644 (file)
@@ -19,7 +19,6 @@ options {
        listen-on { 10.53.0.4; };
        listen-on-v6 { none; };
        recursion no;
-       acache-enable yes;
 };
 
 zone "example" {
index 6d6fa2cf339f412a6af7220933ff3515cb4c4d63..cf0bb519f9bbdeb21dca7a3b1ea23ff1b02a2b12 100644 (file)
        option can be used to limit the amount of memory used by the cache,
        at the expense of reducing cache hit rates and causing more <acronym>DNS</acronym>
        traffic.
-       Additionally, if additional section caching
-       (<xref linkend="acache"/>) is enabled,
-       the <command>max-acache-size</command> option can be used to
-       limit the amount
-       of memory used by the mechanism.
        It is still good practice to have enough memory to load
        all zone and cache data into memory â€” unfortunately, the best
        way
@@ -4626,8 +4621,6 @@ badresp:1,adberr:0,findfail:0,valfail:0]
   [ <command>nta-recheck</command> <replaceable>duration</replaceable> ; ]
   [ <command>port</command> <replaceable>ip_port</replaceable> ; ]
   [ <command>dscp</command> <replaceable>ip_dscp</replaceable> ; ]
-  [ <command>additional-from-auth</command> <replaceable>yes_or_no</replaceable> ; ]
-  [ <command>additional-from-cache</command> <replaceable>yes_or_no</replaceable> ; ]
   [ <command>random-device</command> <replaceable>path_name</replaceable> ; ]
   [ <command>max-cache-size</command> <replaceable>size_or_percent</replaceable> ; ]
   [ <command>match-mapped-addresses</command> <replaceable>yes_or_no</replaceable> ; ]
@@ -4653,9 +4646,6 @@ badresp:1,adberr:0,findfail:0,valfail:0]
   [ <command>querylog</command> <replaceable>yes_or_no</replaceable> ; ]
   [ <command>disable-algorithms</command> <replaceable>domain</replaceable> <command>{</command> <replaceable>algorithm</replaceable> ; ... <command>}</command> ; ]
   [ <command>disable-ds-digests</command> <replaceable>domain</replaceable> <command>{</command> <replaceable>digest_type</replaceable> ; ... <command>}</command> ; ]
-  [ <command>acache-enable</command> <replaceable>yes_or_no</replaceable> ; ]
-  [ <command>acache-cleaning-interval</command> <replaceable>number</replaceable> ; ]
-  [ <command>max-acache-size</command> <replaceable>size_spec</replaceable> ; ]
   [ <command>max-recursion-depth</command> <replaceable>number</replaceable> ; ]
   [ <command>max-recursion-queries</command> <replaceable>number</replaceable> ; ]
   [ <command>masterfile-format</command> ( <option>text</option> | <option>raw</option> | <option>map</option> ) ; ]
@@ -6342,7 +6332,7 @@ options {
                  both authoritative and recursive queries.
                </para>
                <para>
-                 The default is <userinput>no</userinput>.
+                 The default is <userinput>yes</userinput>.
                </para>
              </listitem>
            </varlistentry>
@@ -6733,94 +6723,6 @@ options {
              </listitem>
            </varlistentry>
 
-           <varlistentry>
-             <term><command>additional-from-auth</command></term>
-             <term><command>additional-from-cache</command></term>
-             <listitem>
-
-               <para>
-                 These options control the behavior of an authoritative
-                 server when
-                 answering queries which have additional data, or when
-                 following CNAME
-                 and DNAME chains.
-               </para>
-
-               <para>
-                 When both of these options are set to <userinput>yes</userinput>
-                 (the default) and a
-                 query is being answered from authoritative data (a zone
-                 configured into the server), the additional data section of
-                 the
-                 reply will be filled in using data from other authoritative
-                 zones
-                 and from the cache.  In some situations this is undesirable,
-                 such
-                 as when there is concern over the correctness of the cache,
-                 or
-                 in servers where slave zones may be added and modified by
-                 untrusted third parties.  Also, avoiding
-                 the search for this additional data will speed up server
-                 operations
-                 at the possible expense of additional queries to resolve
-                 what would
-                 otherwise be provided in the additional section.
-               </para>
-
-               <para>
-                 For example, if a query asks for an MX record for host <literal>foo.example.com</literal>,
-                 and the record found is "<literal>MX 10 mail.example.net</literal>", normally the address
-                 records (A and AAAA) for <literal>mail.example.net</literal> will be provided as well,
-                 if known, even though they are not in the example.com zone.
-                 Setting these options to <command>no</command>
-                 disables this behavior and makes
-                 the server only search for additional data in the zone it
-                 answers from.
-               </para>
-
-               <para>
-                 These options are intended for use in authoritative-only
-                 servers, or in authoritative-only views.  Attempts to set
-                 them to <command>no</command> without also
-                 specifying
-                 <command>recursion no</command> will cause the
-                 server to
-                 ignore the options and log a warning message.
-               </para>
-
-               <para>
-                 Specifying <command>additional-from-cache no</command> actually
-                 disables the use of the cache not only for additional data
-                 lookups
-                 but also when looking up the answer.  This is usually the
-                 desired
-                 behavior in an authoritative-only server where the
-                 correctness of
-                 the cached data is an issue.
-               </para>
-
-               <para>
-                 When a name server is non-recursively queried for a name
-                 that is not
-                 below the apex of any served zone, it normally answers with
-                 an
-                 "upwards referral" to the root servers or the servers of
-                 some other
-                 known parent of the query name.  Since the data in an
-                 upwards referral
-                 comes from the cache, the server will not be able to provide
-                 upwards
-                 referrals when <command>additional-from-cache no</command>
-                 has been specified.  Instead, it will respond to such
-                 queries
-                 with REFUSED.  This should not cause any problems since
-                 upwards referrals are not required for the resolution
-                 process.
-               </para>
-
-             </listitem>
-           </varlistentry>
-
            <varlistentry>
              <term><command>match-mapped-addresses</command></term>
              <listitem>
@@ -9055,7 +8957,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
 
          <para>
            The response to a DNS query may consist of multiple resource
-           records (RRs) forming a resource records set (RRset).
+           records (RRs) forming a resource record set (RRset).
            The name server will normally return the
            RRs within the RRset in an indeterminate order
            (but see the <command>rrset-order</command>
@@ -9169,17 +9071,14 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
          <para>
            When multiple records are returned in an answer it may be
            useful to configure the order of the records placed into the
-           response.
-           The <command>rrset-order</command> statement permits
-           configuration
-           of the ordering of the records in a multiple record response.
+           response.  The <command>rrset-order</command> statement permits
+           configuration of the ordering of the records in a
+           multiple-record response.
            See also the <command>sortlist</command> statement,
            <xref linkend="the_sortlist_statement"/>.
          </para>
-
          <para>
-           An <command>order_spec</command> is defined as
-           follows:
+           An <command>order_spec</command> is defined as follows:
          </para>
          <para>
            <optional>class <replaceable>class_name</replaceable></optional>
@@ -9207,7 +9106,10 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
                  <entry colname="2">
                    <para>
                      Records are returned in the order they
-                     are defined in the zone file.
+                     are defined in the zone file. This option
+                     is only available if <acronym>BIND</acronym>
+                     is configured with "--enable-fixed-rrset" at
+                     compile time.
                    </para>
                  </entry>
                </row>
@@ -9227,29 +9129,45 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
                  </entry>
                  <entry colname="2">
                    <para>
-                     Records are returned in a cyclic round-robin order.
+                     Records are returned in a cyclic round-robin order,
+                     rotating by one record per query.
                    </para>
                    <para>
-                     If <acronym>BIND</acronym> is configured with the
-                     "--enable-fixed-rrset" option at compile time, then
+                     If <acronym>BIND</acronym> is configured with
+                     "--enable-fixed-rrset" at compile time, then
                      the initial ordering of the RRset will match the
-                     one specified in the zone file.
+                     one specified in the zone file; otherwise the
+                     initial ordering is indeterminate.
+                   </para>
+                 </entry>
+               </row>
+               <row rowsep="0">
+                 <entry colname="1">
+                   <para><command>none</command></para>
+                 </entry>
+                 <entry colname="2">
+                   <para>
+                     Records are returned in whatever order they were
+                     retrieved from the database.  This order is
+                     indeterminate, but will be consistent as long as the
+                     database is not modified. When no ordering is
+                     specified, this is the default.
                    </para>
                  </entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
+         <para>
+         </para>
          <para>
            For example:
          </para>
-
 <programlisting>rrset-order {
    class IN type A name "host.example.com" order random;
    order cyclic;
 };
 </programlisting>
-
          <para>
            will cause any responses for type A records in class IN that
            have "<literal>host.example.com</literal>" as a
@@ -9261,7 +9179,8 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
            appear, they are not combined â€” the last one applies.
          </para>
          <para>
-           By default, all records are returned in random order.
+           By default, records are returned in indeterminate but
+           consistent order (see <command>none</command> above).
          </para>
 
          <note>
@@ -10020,121 +9939,6 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
          </variablelist>
        </section>
 
-       <section xml:id="acache"><info><title>Additional Section Caching</title></info>
-
-
-         <para>
-           The additional section cache, also called <command>acache</command>,
-           is an internal cache to improve the response performance of BIND 9.
-           When additional section caching is enabled, BIND 9 will
-           cache an internal short-cut to the additional section content for
-           each answer RR.
-           Note that <command>acache</command> is an internal caching
-           mechanism of BIND 9, and is not related to the DNS caching
-           server function.
-         </para>
-
-         <para>
-           Additional section caching does not change the
-           response content (except the RRsets ordering of the additional
-           section, see below), but can improve the response performance
-           significantly.
-           It is particularly effective when BIND 9 acts as an authoritative
-           server for a zone that has many delegations with many glue RRs.
-         </para>
-
-         <para>
-           In order to obtain the maximum performance improvement
-           from additional section caching, setting
-           <command>additional-from-cache</command>
-           to <command>no</command> is recommended, since the current
-           implementation of <command>acache</command>
-           does not short-cut of additional section information from the
-           DNS cache data.
-         </para>
-
-         <para>
-           One obvious disadvantage of <command>acache</command> is
-           that it requires much more
-           memory for the internal cached data.
-           Thus, if the response performance does not matter and memory
-           consumption is much more critical, the
-           <command>acache</command> mechanism can be
-           disabled by setting <command>acache-enable</command> to
-           <command>no</command>.
-           It is also possible to specify the upper limit of memory
-           consumption
-           for acache by using <command>max-acache-size</command>.
-         </para>
-
-         <para>
-           Additional section caching also has a minor effect on the
-           RRset ordering in the additional section.
-           Without <command>acache</command>,
-           <command>cyclic</command> order is effective for the additional
-           section as well as the answer and authority sections.
-           However, additional section caching fixes the ordering when it
-           first caches an RRset for the additional section, and the same
-           ordering will be kept in succeeding responses, regardless of the
-           setting of <command>rrset-order</command>.
-           The effect of this should be minor, however, since an
-           RRset in the additional section
-           typically only contains a small number of RRs (and in many cases
-           it only contains a single RR), in which case the
-           ordering does not matter much.
-         </para>
-
-         <para>
-           The following is a summary of options related to
-           <command>acache</command>.
-         </para>
-
-         <variablelist>
-
-           <varlistentry>
-             <term><command>acache-enable</command></term>
-             <listitem>
-               <para>
-                 If <command>yes</command>, additional section caching is
-                 enabled.  The default value is <command>no</command>.
-               </para>
-             </listitem>
-           </varlistentry>
-
-           <varlistentry>
-             <term><command>acache-cleaning-interval</command></term>
-             <listitem>
-               <para>
-                 The server will remove stale cache entries, based on an LRU
-                 based
-                 algorithm, every <command>acache-cleaning-interval</command> minutes.
-                 The default is 60 minutes.
-                 If set to 0, no periodic cleaning will occur.
-               </para>
-             </listitem>
-           </varlistentry>
-
-           <varlistentry>
-             <term><command>max-acache-size</command></term>
-             <listitem>
-               <para>
-                 The maximum amount of memory in bytes to use for the server's acache.
-                 When the amount of data in the acache reaches this limit,
-                 the server
-                 will clean more aggressively so that the limit is not
-                 exceeded.
-                 In a server with multiple views, the limit applies
-                 separately to the
-                 acache of each view.
-                 The default is <literal>16M</literal>.
-               </para>
-             </listitem>
-           </varlistentry>
-
-         </variablelist>
-
-       </section>
-
        <section xml:id="content_filtering"><info><title>Content Filtering</title></info>
 
          <para>
index a2107304143068c1646e36927f9f87c281d9fa1b..1111b0925210d549dfd11c080cdd831ca223ecfb 100644 (file)
@@ -64,10 +64,10 @@ masters <string> [ port <integer> ] [ dscp
     <integer> ] ) [ key <string> ]; ... }; // may occur multiple times
 
 options {
-        acache-cleaning-interval <integer>;
-        acache-enable <boolean>;
-        additional-from-auth <boolean>;
-        additional-from-cache <boolean>;
+        acache-cleaning-interval <integer>; // obsolete
+        acache-enable <boolean>; // obsolete
+        additional-from-auth <boolean>; // obsolete
+        additional-from-cache <boolean>; // obsolete
         allow-new-zones <boolean>;
         allow-notify { <address_match_element>; ... };
         allow-query { <address_match_element>; ... };
@@ -213,7 +213,7 @@ options {
         masterfile-format ( map | raw | text );
         masterfile-style ( full | relative );
         match-mapped-addresses <boolean>;
-        max-acache-size ( unlimited | <sizeval> );
+        max-acache-size ( unlimited | <sizeval> ); // obsolete
         max-cache-size ( default | unlimited | <sizeval> | <percentage> );
         max-cache-ttl <integer>;
         max-clients-per-query <integer>;
@@ -418,10 +418,10 @@ trusted-keys { <string> <integer> <integer>
     <integer> <quoted_string>; ... }; // may occur multiple times
 
 view <string> [ <class> ] {
-        acache-cleaning-interval <integer>;
-        acache-enable <boolean>;
-        additional-from-auth <boolean>;
-        additional-from-cache <boolean>;
+        acache-cleaning-interval <integer>; // obsolete
+        acache-enable <boolean>; // obsolete
+        additional-from-auth <boolean>; // obsolete
+        additional-from-cache <boolean>; // obsolete
         allow-new-zones <boolean>;
         allow-notify { <address_match_element>; ... };
         allow-query { <address_match_element>; ... };
@@ -535,7 +535,7 @@ view <string> [ <class> ] {
         match-clients { <address_match_element>; ... };
         match-destinations { <address_match_element>; ... };
         match-recursive-only <boolean>;
-        max-acache-size ( unlimited | <sizeval> );
+        max-acache-size ( unlimited | <sizeval> ); // obsolete
         max-cache-size ( default | unlimited | <sizeval> | <percentage> );
         max-cache-ttl <integer>;
         max-clients-per-query <integer>;
index ab5f6ae3d66296172f58316923bcccf5bb803da1..e691d4b07e5c89d827eebdbc2583fe37e200190e 100644 (file)
@@ -133,7 +133,8 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
                            "compilation time");
 #endif
        } else if (strcasecmp(cfg_obj_asstring(obj), "random") != 0 &&
-                  strcasecmp(cfg_obj_asstring(obj), "cyclic") != 0) {
+                  strcasecmp(cfg_obj_asstring(obj), "cyclic") != 0 &&
+                  strcasecmp(cfg_obj_asstring(obj), "none") != 0) {
                cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
                            "rrset-order: invalid order '%s'",
                            cfg_obj_asstring(obj));
index 4346fb1faa77bfaebca96e8837480a29d8f8b042..33bc87f2795b511beca01072db424556e031ff4f 100644 (file)
@@ -55,7 +55,7 @@ GEOIPLINKOBJS = geoip.@O@
 DNSTAPOBJS = dnstap.@O@ dnstap.pb-c.@O@
 
 # Alphabetically
-DNSOBJS =      acache.@O@ acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
+DNSOBJS =      acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
                cache.@O@ callbacks.@O@ catz.@O@ clientinfo.@O@ compress.@O@ \
                db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
                dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ ecs.@O@ \
@@ -95,7 +95,7 @@ GEOIPLINKSRCS = geoip.c
 
 DNSTAPSRCS = dnstap.c dnstap.pb-c.c
 
-DNSSRCS =      acache.c acl.c adb.c badcache. byaddr.c \
+DNSSRCS =      acl.c adb.c badcache. byaddr.c \
                cache.c callbacks.c clientinfo.c compress.c \
                db.c dbiterator.c dbtable.c diff.c dispatch.c \
                dlz.c dns64.c dnssec.c ds.c dyndb.c ecs.c forward.c \
diff --git a/lib/dns/acache.c b/lib/dns/acache.c
deleted file mode 100644 (file)
index 2fc1871..0000000
+++ /dev/null
@@ -1,1790 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2012, 2013, 2015, 2016  Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-/* $Id: acache.c,v 1.22 2008/02/07 23:46:54 tbox Exp $ */
-
-#include <config.h>
-
-#include <isc/atomic.h>
-#include <isc/event.h>
-#include <isc/hash.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/random.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/serial.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/timer.h>
-
-#include <dns/acache.h>
-#include <dns/db.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/name.h>
-#include <dns/rdataset.h>
-#include <dns/result.h>
-#include <dns/zone.h>
-
-#define ACACHE_MAGIC                   ISC_MAGIC('A', 'C', 'H', 'E')
-#define DNS_ACACHE_VALID(acache)       ISC_MAGIC_VALID(acache, ACACHE_MAGIC)
-
-#define ACACHEENTRY_MAGIC              ISC_MAGIC('A', 'C', 'E', 'T')
-#define DNS_ACACHEENTRY_VALID(entry)   ISC_MAGIC_VALID(entry, ACACHEENTRY_MAGIC)
-
-#define DBBUCKETS      67
-
-#if 0
-#define ATRACE(m)       isc_log_write(dns_lctx, \
-                                     DNS_LOGCATEGORY_DATABASE, \
-                                     DNS_LOGMODULE_ACACHE, \
-                                     ISC_LOG_DEBUG(3), \
-                                     "acache %p: %s", acache, (m))
-#define AATRACE(a,m)    isc_log_write(dns_lctx, \
-                                     DNS_LOGCATEGORY_DATABASE, \
-                                     DNS_LOGMODULE_ACACHE, \
-                                     ISC_LOG_DEBUG(3), \
-                                     "acache %p: %s", (a), (m))
-#else
-#define ATRACE(m)
-#define AATRACE(a, m)
-#endif
-
-/*
- * The following variables control incremental cleaning.
- * MINSIZE is how many bytes is the floor for dns_acache_setcachesize().
- * CLEANERINCREMENT is how many entries are examined in one pass.
- * (XXX simply derived from definitions in cache.c  There may be better
- *  constants here.)
- */
-#define DNS_ACACHE_MINSIZE             2097152U /* Bytes.  2097152 = 2 MB */
-#define DNS_ACACHE_CLEANERINCREMENT    1000     /* Number of entries. */
-
-#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT        1009     /*%< Should be prime. */
-
-#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE)
-#define ACACHE_USE_RWLOCK 1
-#endif
-
-#ifdef ACACHE_USE_RWLOCK
-#define ACACHE_INITLOCK(l)     isc_rwlock_init((l), 0, 0)
-#define ACACHE_DESTROYLOCK(l)  isc_rwlock_destroy(l)
-#define ACACHE_LOCK(l, t)      RWLOCK((l), (t))
-#define ACACHE_UNLOCK(l, t)    RWUNLOCK((l), (t))
-
-#define acache_storetime(entry, t) \
-       (isc_atomic_store((isc_int32_t *)&(entry)->lastused, (t)))
-#else
-#define ACACHE_INITLOCK(l)     isc_mutex_init(l)
-#define ACACHE_DESTROYLOCK(l)  DESTROYLOCK(l)
-#define ACACHE_LOCK(l, t)      LOCK(l)
-#define ACACHE_UNLOCK(l, t)    UNLOCK(l)
-
-#define acache_storetime(entry, t) ((entry)->lastused = (t))
-#endif
-
-/* Locked by acache lock */
-typedef struct dbentry {
-       ISC_LINK(struct dbentry)        link;
-
-       dns_db_t                        *db;
-       ISC_LIST(dns_acacheentry_t)     originlist;
-       ISC_LIST(dns_acacheentry_t)     referlist;
-} dbentry_t;
-
-typedef ISC_LIST(dbentry_t) dbentrylist_t;
-
-typedef struct acache_cleaner acache_cleaner_t;
-
-typedef enum {
-       cleaner_s_idle, /* Waiting for cleaning-interval to expire. */
-       cleaner_s_busy, /* Currently cleaning. */
-       cleaner_s_done  /* Freed enough memory after being overmem. */
-} cleaner_state_t;
-
-/*
- * Convenience macros for comprehensive assertion checking.
- */
-#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \
-                        (c)->resched_event != NULL)
-#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \
-                        (c)->resched_event == NULL)
-
-struct acache_cleaner {
-       isc_mutex_t             lock;
-       /*
-        * Locks overmem_event, overmem.  (See cache.c)
-        */
-
-       dns_acache_t            *acache;
-       unsigned int            cleaning_interval; /* The cleaning-interval
-                                                     from named.conf,
-                                                     in seconds. */
-
-       isc_stdtime_t           last_cleanup_time; /* The time when the last
-                                                     cleanup task completed */
-
-       isc_timer_t             *cleaning_timer;
-       isc_event_t             *resched_event; /* Sent by cleaner task to
-                                                  itself to reschedule */
-       isc_event_t             *overmem_event;
-
-       dns_acacheentry_t       *current_entry; /* The bookmark entry to
-                                                  restart the cleaning.
-                                                  Locked by acache lock. */
-       int                     increment;      /* Number of entries to
-                                                  clean in one increment */
-
-       unsigned long           ncleaned;       /* Number of entries cleaned
-                                                  up (for logging purposes) */
-       cleaner_state_t         state;          /* Idle/Busy/Done. */
-       isc_boolean_t           overmem;        /* The acache is in an overmem
-                                                  state. */
-};
-
-struct dns_acachestats {
-       unsigned int                    hits;
-       unsigned int                    queries;
-       unsigned int                    misses;
-       unsigned int                    adds;
-       unsigned int                    deleted;
-       unsigned int                    cleaned;
-       unsigned int                    cleaner_runs;
-       unsigned int                    overmem;
-       unsigned int                    overmem_nocreates;
-       unsigned int                    nomem;
-};
-
-/*
- * The actual acache object.
- */
-
-struct dns_acache {
-       unsigned int                    magic;
-
-       isc_mem_t                       *mctx;
-       isc_refcount_t                  refs;
-
-#ifdef ACACHE_USE_RWLOCK
-       isc_rwlock_t                    *entrylocks;
-#else
-       isc_mutex_t                     *entrylocks;
-#endif
-
-       isc_mutex_t                     lock;
-
-       int                             live_cleaners;
-       acache_cleaner_t                cleaner;
-       ISC_LIST(dns_acacheentry_t)     entries;
-       unsigned int                    dbentries;
-       dbentrylist_t                   dbbucket[DBBUCKETS];
-
-       isc_boolean_t                   shutting_down;
-
-       isc_task_t                      *task;
-       isc_event_t                     cevent;
-       isc_boolean_t                   cevent_sent;
-
-       dns_acachestats_t               stats;
-};
-
-struct dns_acacheentry {
-       unsigned int            magic;
-
-       unsigned int            locknum;
-       isc_refcount_t          references;
-
-       dns_acache_t            *acache;
-
-       /* Data for Management of cache entries */
-       ISC_LINK(dns_acacheentry_t) link;
-       ISC_LINK(dns_acacheentry_t) olink;
-       ISC_LINK(dns_acacheentry_t) rlink;
-
-       dns_db_t                *origdb; /* reference to the DB
-                                           holding this entry */
-
-       /* Cache data */
-       dns_zone_t              *zone;          /* zone this entry
-                                                  belongs to */
-       dns_db_t                *db;            /* DB this entry belongs to */
-       dns_dbversion_t         *version;       /* the version of the DB */
-       dns_dbnode_t            *node;          /* node this entry
-                                                  belongs to */
-       dns_name_t              *foundname;     /* corresponding DNS name
-                                                  and rdataset */
-
-       /* Callback function and its argument */
-       void                    (*callback)(dns_acacheentry_t *, void **);
-       void                    *cbarg;
-
-       /* Timestamp of the last time this entry is referred to */
-       isc_stdtime32_t         lastused;
-};
-
-/*
- *     Internal functions (and prototypes).
- */
-static inline isc_boolean_t check_noentry(dns_acache_t *acache);
-static void destroy(dns_acache_t *acache);
-static void shutdown_entries(dns_acache_t *acache);
-static void shutdown_buckets(dns_acache_t *acache);
-static void destroy_entry(dns_acacheentry_t *ent);
-static inline void unlink_dbentries(dns_acache_t *acache,
-                                   dns_acacheentry_t *ent);
-static inline isc_result_t finddbent(dns_acache_t *acache,
-                                    dns_db_t *db, dbentry_t **dbentryp);
-static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry);
-static isc_result_t acache_cleaner_init(dns_acache_t *acache,
-                                       isc_timermgr_t *timermgr,
-                                       acache_cleaner_t *cleaner);
-static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event);
-static void acache_incremental_cleaning_action(isc_task_t *task,
-                                              isc_event_t *event);
-static void acache_overmem_cleaning_action(isc_task_t *task,
-                                          isc_event_t *event);
-static void acache_cleaner_shutdown_action(isc_task_t *task,
-                                          isc_event_t *event);
-
-/*
- * acache should be locked.  If it is not, the stats can get out of whack,
- * which is not a big deal for us since this is for debugging / stats
- */
-static void
-reset_stats(dns_acache_t *acache) {
-       acache->stats.hits = 0;
-       acache->stats.queries = 0;
-       acache->stats.misses = 0;
-       acache->stats.adds = 0;
-       acache->stats.deleted = 0;
-       acache->stats.cleaned = 0;
-       acache->stats.overmem = 0;
-       acache->stats.overmem_nocreates = 0;
-       acache->stats.nomem = 0;
-}
-
-/*
- * The acache must be locked before calling.
- */
-static inline isc_boolean_t
-check_noentry(dns_acache_t *acache) {
-       if (ISC_LIST_EMPTY(acache->entries) && acache->dbentries == 0) {
-               return (ISC_TRUE);
-       }
-
-       return (ISC_FALSE);
-}
-
-/*
- * The acache must be locked before calling.
- */
-static void
-shutdown_entries(dns_acache_t *acache) {
-       dns_acacheentry_t *entry, *entry_next;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       INSIST(acache->shutting_down);
-
-       /*
-        * Release the dependency of all entries, and detach them.
-        */
-       for (entry = ISC_LIST_HEAD(acache->entries);
-            entry != NULL;
-            entry = entry_next) {
-               entry_next = ISC_LIST_NEXT(entry, link);
-
-               ACACHE_LOCK(&acache->entrylocks[entry->locknum],
-                           isc_rwlocktype_write);
-
-               /*
-                * If the cleaner holds this entry, it will be unlinked and
-                * freed in the cleaner later.
-                */
-               if (acache->cleaner.current_entry != entry)
-                       ISC_LIST_UNLINK(acache->entries, entry, link);
-               unlink_dbentries(acache, entry);
-               if (entry->callback != NULL) {
-                       (entry->callback)(entry, &entry->cbarg);
-                       entry->callback = NULL;
-               }
-
-               ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                             isc_rwlocktype_write);
-
-               if (acache->cleaner.current_entry != entry)
-                       dns_acache_detachentry(&entry);
-       }
-}
-
-/*
- * The acache must be locked before calling.
- */
-static void
-shutdown_buckets(dns_acache_t *acache) {
-       int i;
-       dbentry_t *dbent;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       INSIST(acache->shutting_down);
-
-       for (i = 0; i < DBBUCKETS; i++) {
-               while ((dbent = ISC_LIST_HEAD(acache->dbbucket[i])) != NULL) {
-                       INSIST(ISC_LIST_EMPTY(dbent->originlist) &&
-                              ISC_LIST_EMPTY(dbent->referlist));
-                       ISC_LIST_UNLINK(acache->dbbucket[i], dbent, link);
-
-                       dns_db_detach(&dbent->db);
-
-                       isc_mem_put(acache->mctx, dbent, sizeof(*dbent));
-
-                       acache->dbentries--;
-               }
-       }
-
-       INSIST(acache->dbentries == 0);
-}
-
-static void
-shutdown_task(isc_task_t *task, isc_event_t *ev) {
-       dns_acache_t *acache;
-
-       UNUSED(task);
-
-       acache = ev->ev_arg;
-       INSIST(DNS_ACACHE_VALID(acache));
-
-       isc_event_free(&ev);
-
-       LOCK(&acache->lock);
-
-       shutdown_entries(acache);
-       shutdown_buckets(acache);
-
-       UNLOCK(&acache->lock);
-
-       dns_acache_detach(&acache);
-}
-
-/* The acache and the entry must be locked before calling. */
-static inline void
-unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent) {
-       isc_result_t result;
-       dbentry_t *dbent;
-
-       if (ISC_LINK_LINKED(ent, olink)) {
-               INSIST(ent->origdb != NULL);
-               dbent = NULL;
-               result = finddbent(acache, ent->origdb, &dbent);
-               INSIST(result == ISC_R_SUCCESS);
-
-               ISC_LIST_UNLINK(dbent->originlist, ent, olink);
-       }
-       if (ISC_LINK_LINKED(ent, rlink)) {
-               INSIST(ent->db != NULL);
-               dbent = NULL;
-               result = finddbent(acache, ent->db, &dbent);
-               INSIST(result == ISC_R_SUCCESS);
-
-               ISC_LIST_UNLINK(dbent->referlist, ent, rlink);
-       }
-}
-
-/* There must not be a reference to this entry. */
-static void
-destroy_entry(dns_acacheentry_t *entry) {
-       dns_acache_t *acache;
-
-       REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
-       acache = entry->acache;
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       /*
-        * Since there is no reference to this entry, it is safe to call
-        * clear_entry() here.
-        */
-       clear_entry(acache, entry);
-
-       isc_mem_put(acache->mctx, entry, sizeof(*entry));
-
-       dns_acache_detach(&acache);
-}
-
-static void
-destroy(dns_acache_t *acache) {
-       int i;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       ATRACE("destroy");
-
-       isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0);
-
-       if (acache->cleaner.overmem_event != NULL)
-               isc_event_free(&acache->cleaner.overmem_event);
-
-       if (acache->cleaner.resched_event != NULL)
-               isc_event_free(&acache->cleaner.resched_event);
-
-       if (acache->task != NULL)
-               isc_task_detach(&acache->task);
-
-       for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++)
-               ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
-       isc_mem_put(acache->mctx, acache->entrylocks,
-                   sizeof(*acache->entrylocks) *
-                   DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
-
-       DESTROYLOCK(&acache->cleaner.lock);
-
-       DESTROYLOCK(&acache->lock);
-       acache->magic = 0;
-
-       isc_mem_putanddetach(&acache->mctx, acache, sizeof(*acache));
-}
-
-static inline isc_result_t
-finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp) {
-       int bucket;
-       dbentry_t *dbentry;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(db != NULL);
-       REQUIRE(dbentryp != NULL && *dbentryp == NULL);
-
-       /*
-        * The caller must be holding the acache lock.
-        */
-
-       bucket = isc_hash_function(&db, sizeof(db), ISC_TRUE, NULL) % DBBUCKETS;
-
-       for (dbentry = ISC_LIST_HEAD(acache->dbbucket[bucket]);
-            dbentry != NULL;
-            dbentry = ISC_LIST_NEXT(dbentry, link)) {
-               if (dbentry->db == db)
-                       break;
-       }
-
-       *dbentryp = dbentry;
-
-       if (dbentry == NULL)
-               return (ISC_R_NOTFOUND);
-       else
-               return (ISC_R_SUCCESS);
-}
-
-static inline void
-clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry) {
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
-       /*
-        * The caller must be holing the entry lock.
-        */
-
-       if (entry->foundname) {
-               dns_rdataset_t *rdataset, *rdataset_next;
-
-               for (rdataset = ISC_LIST_HEAD(entry->foundname->list);
-                    rdataset != NULL;
-                    rdataset = rdataset_next) {
-                       rdataset_next = ISC_LIST_NEXT(rdataset, link);
-                       ISC_LIST_UNLINK(entry->foundname->list,
-                                       rdataset, link);
-                       dns_rdataset_disassociate(rdataset);
-                       isc_mem_put(acache->mctx, rdataset, sizeof(*rdataset));
-               }
-               if (dns_name_dynamic(entry->foundname))
-                       dns_name_free(entry->foundname, acache->mctx);
-               isc_mem_put(acache->mctx, entry->foundname,
-                           sizeof(*entry->foundname));
-               entry->foundname = NULL;
-       }
-
-       if (entry->node != NULL) {
-               INSIST(entry->db != NULL);
-               dns_db_detachnode(entry->db, &entry->node);
-       }
-       if (entry->version != NULL) {
-               INSIST(entry->db != NULL);
-               dns_db_closeversion(entry->db, &entry->version, ISC_FALSE);
-       }
-       if (entry->db != NULL)
-               dns_db_detach(&entry->db);
-       if (entry->zone != NULL)
-               dns_zone_detach(&entry->zone);
-
-       if (entry->origdb != NULL)
-               dns_db_detach(&entry->origdb);
-}
-
-static isc_result_t
-acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr,
-                   acache_cleaner_t *cleaner)
-{
-       int result;
-
-       ATRACE("acache cleaner init");
-
-       result = isc_mutex_init(&cleaner->lock);
-       if (result != ISC_R_SUCCESS)
-               goto fail;
-
-       cleaner->increment = DNS_ACACHE_CLEANERINCREMENT;
-       cleaner->state = cleaner_s_idle;
-       cleaner->acache = acache;
-       cleaner->overmem = ISC_FALSE;
-
-       cleaner->cleaning_timer = NULL;
-       cleaner->resched_event = NULL;
-       cleaner->overmem_event = NULL;
-       cleaner->current_entry = NULL;
-
-       if (timermgr != NULL) {
-               cleaner->acache->live_cleaners++;
-
-               result = isc_task_onshutdown(acache->task,
-                                            acache_cleaner_shutdown_action,
-                                            acache);
-               if (result != ISC_R_SUCCESS) {
-                       UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                        "acache cleaner: "
-                                        "isc_task_onshutdown() failed: %s",
-                                        dns_result_totext(result));
-                       goto cleanup;
-               }
-
-               cleaner->cleaning_interval = 0; /* Initially turned off. */
-               isc_stdtime_get(&cleaner->last_cleanup_time);
-               result = isc_timer_create(timermgr, isc_timertype_inactive,
-                                         NULL, NULL,
-                                         acache->task,
-                                         acache_cleaning_timer_action,
-                                         cleaner, &cleaner->cleaning_timer);
-               if (result != ISC_R_SUCCESS) {
-                       UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                        "isc_timer_create() failed: %s",
-                                        dns_result_totext(result));
-                       result = ISC_R_UNEXPECTED;
-                       goto cleanup;
-               }
-
-               cleaner->resched_event =
-                       isc_event_allocate(acache->mctx, cleaner,
-                                          DNS_EVENT_ACACHECLEAN,
-                                          acache_incremental_cleaning_action,
-                                          cleaner, sizeof(isc_event_t));
-               if (cleaner->resched_event == NULL) {
-                       result = ISC_R_NOMEMORY;
-                       goto cleanup;
-               }
-
-               cleaner->overmem_event =
-                       isc_event_allocate(acache->mctx, cleaner,
-                                          DNS_EVENT_ACACHEOVERMEM,
-                                          acache_overmem_cleaning_action,
-                                          cleaner, sizeof(isc_event_t));
-               if (cleaner->overmem_event == NULL) {
-                       result = ISC_R_NOMEMORY;
-                       goto cleanup;
-               }
-       }
-
-       return (ISC_R_SUCCESS);
-
- cleanup:
-       if (cleaner->overmem_event != NULL)
-               isc_event_free(&cleaner->overmem_event);
-       if (cleaner->resched_event != NULL)
-               isc_event_free(&cleaner->resched_event);
-       if (cleaner->cleaning_timer != NULL)
-               isc_timer_detach(&cleaner->cleaning_timer);
-       cleaner->acache->live_cleaners--;
-       DESTROYLOCK(&cleaner->lock);
- fail:
-       return (result);
-}
-
-static void
-begin_cleaning(acache_cleaner_t *cleaner) {
-       dns_acacheentry_t *head;
-       dns_acache_t *acache = cleaner->acache;
-
-       /*
-        * This function does not have to lock the cleaner, since critical
-        * parameters (except current_entry, which is locked by acache lock,)
-        * are only used in a single task context.
-        */
-
-       REQUIRE(CLEANER_IDLE(cleaner));
-       INSIST(DNS_ACACHE_VALID(acache));
-       INSIST(cleaner->current_entry == NULL);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                     DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1),
-                     "begin acache cleaning, mem inuse %lu",
-                     (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
-       LOCK(&acache->lock);
-
-       head = ISC_LIST_HEAD(acache->entries);
-       if (head != NULL)
-               dns_acache_attachentry(head, &cleaner->current_entry);
-
-       UNLOCK(&acache->lock);
-
-       if (cleaner->current_entry != NULL) {
-               cleaner->ncleaned = 0;
-               cleaner->state = cleaner_s_busy;
-               isc_task_send(acache->task, &cleaner->resched_event);
-       }
-
-       return;
-}
-
-static void
-end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) {
-       dns_acache_t *acache = cleaner->acache;
-
-       REQUIRE(CLEANER_BUSY(cleaner));
-       REQUIRE(event != NULL);
-       REQUIRE(DNS_ACACHEENTRY_VALID(cleaner->current_entry));
-
-       /* No need to lock the cleaner (see begin_cleaning()). */
-
-       LOCK(&acache->lock);
-
-       /*
-        * Even if the cleaner has the last reference to the entry, which means
-        * the entry has been unused, it may still be linked if unlinking the
-        * entry has been delayed due to the reference.
-        */
-       if (isc_refcount_current(&cleaner->current_entry->references) == 1) {
-               INSIST(cleaner->current_entry->callback == NULL);
-
-               if (ISC_LINK_LINKED(cleaner->current_entry, link)) {
-                       ISC_LIST_UNLINK(acache->entries,
-                                       cleaner->current_entry, link);
-               }
-       }
-       dns_acache_detachentry(&cleaner->current_entry);
-
-       if (cleaner->overmem)
-               acache->stats.overmem++;
-       acache->stats.cleaned += cleaner->ncleaned;
-       acache->stats.cleaner_runs++;
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
-                     ISC_LOG_NOTICE,
-                     "acache %p stats: hits=%d misses=%d queries=%d "
-                     "adds=%d deleted=%d "
-                     "cleaned=%d cleaner_runs=%d overmem=%d "
-                     "overmem_nocreates=%d nomem=%d",
-                     acache,
-                     acache->stats.hits, acache->stats.misses,
-                     acache->stats.queries,
-                     acache->stats.adds, acache->stats.deleted,
-                     acache->stats.cleaned, acache->stats.cleaner_runs,
-                     acache->stats.overmem, acache->stats.overmem_nocreates,
-                     acache->stats.nomem);
-       reset_stats(acache);
-
-       isc_stdtime_get(&cleaner->last_cleanup_time);
-
-       UNLOCK(&acache->lock);
-
-       dns_acache_setcleaninginterval(cleaner->acache,
-                                      cleaner->cleaning_interval);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
-                     ISC_LOG_DEBUG(1), "end acache cleaning, "
-                     "%lu entries cleaned, mem inuse %lu",
-                     cleaner->ncleaned,
-                     (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
-       if (cleaner->overmem) {
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE,
-                             "acache is still in overmem state "
-                             "after cleaning");
-       }
-
-       cleaner->ncleaned = 0;
-       cleaner->state = cleaner_s_idle;
-       cleaner->resched_event = event;
-}
-
-/*
- * This is run once for every acache-cleaning-interval as defined
- * in named.conf.
- */
-static void
-acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event) {
-       acache_cleaner_t *cleaner = event->ev_arg;
-
-       UNUSED(task);
-
-       INSIST(event->ev_type == ISC_TIMEREVENT_TICK);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
-                     ISC_LOG_DEBUG(1), "acache cleaning timer fired, "
-                     "cleaner state = %d", cleaner->state);
-
-       if (cleaner->state == cleaner_s_idle)
-               begin_cleaning(cleaner);
-
-       isc_event_free(&event);
-}
-
-/* The caller must hold entry lock. */
-static inline isc_boolean_t
-entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry,
-           isc_stdtime32_t now32, unsigned int interval)
-{
-       /*
-        * If the callback has been canceled, we definitely do not need the
-        * entry.
-        */
-       if (entry->callback == NULL)
-               return (ISC_TRUE);
-
-       if (interval > cleaner->cleaning_interval)
-               interval = cleaner->cleaning_interval;
-
-       if (entry->lastused + interval < now32)
-               return (ISC_TRUE);
-
-       /*
-        * If the acache is in the overmem state, probabilistically decide if
-        * the entry should be purged, based on the time passed from its last
-        * use and the cleaning interval.
-        */
-       if (cleaner->overmem) {
-               unsigned int passed;
-               isc_uint32_t val;
-
-               if (isc_serial_ge(now32, entry->lastused))
-                       passed = now32 - entry->lastused; /* <= interval */
-               else
-                       passed = 0;
-
-               if (passed > interval / 2)
-                       return (ISC_TRUE);
-               isc_random_get(&val);
-               if (passed > interval / 4)
-                       return (ISC_TF(val % 4 == 0));
-               return (ISC_TF(val % 8 == 0));
-       }
-
-       return (ISC_FALSE);
-}
-
-/*
- * Do incremental cleaning.
- */
-static void
-acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
-       acache_cleaner_t *cleaner = event->ev_arg;
-       dns_acache_t *acache = cleaner->acache;
-       dns_acacheentry_t *entry, *next = NULL;
-       int n_entries;
-       isc_stdtime32_t now32, last32;
-       isc_stdtime_t now;
-       unsigned int interval;
-
-       INSIST(DNS_ACACHE_VALID(acache));
-       INSIST(task == acache->task);
-       INSIST(event->ev_type == DNS_EVENT_ACACHECLEAN);
-
-       if (cleaner->state == cleaner_s_done) {
-               cleaner->state = cleaner_s_busy;
-               end_cleaning(cleaner, event);
-               return;
-       }
-
-       INSIST(CLEANER_BUSY(cleaner));
-
-       n_entries = cleaner->increment;
-
-       isc_stdtime_get(&now);
-       isc_stdtime_convert32(now, &now32);
-
-       LOCK(&acache->lock);
-
-       entry = cleaner->current_entry;
-       isc_stdtime_convert32(cleaner->last_cleanup_time, &last32);
-       if (isc_serial_ge(now32, last32))
-               interval = now32 - last32;
-       else
-               interval = 0;
-
-       while (n_entries-- > 0) {
-               isc_boolean_t is_stale = ISC_FALSE;
-
-               INSIST(entry != NULL);
-
-               next = ISC_LIST_NEXT(entry, link);
-
-               ACACHE_LOCK(&acache->entrylocks[entry->locknum],
-                           isc_rwlocktype_write);
-
-               is_stale = entry_stale(cleaner, entry, now32, interval);
-               if (is_stale) {
-                       ISC_LIST_UNLINK(acache->entries, entry, link);
-                       unlink_dbentries(acache, entry);
-                       if (entry->callback != NULL)
-                               (entry->callback)(entry, &entry->cbarg);
-                       entry->callback = NULL;
-
-                       cleaner->ncleaned++;
-               }
-
-               ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                             isc_rwlocktype_write);
-
-               if (is_stale)
-                       dns_acache_detachentry(&entry);
-
-               if (next == NULL) {
-                       if (cleaner->overmem) {
-                               entry = ISC_LIST_HEAD(acache->entries);
-                               if (entry != NULL) {
-                                       /*
-                                        * If we are still in the overmem
-                                        * state, keep cleaning.  In case we
-                                        * exit from the loop immediately after
-                                        * this, reset next to the head entry
-                                        * as we'll expect it will be never
-                                        * NULL.
-                                        */
-                                       isc_log_write(dns_lctx,
-                                                     DNS_LOGCATEGORY_DATABASE,
-                                                     DNS_LOGMODULE_ACACHE,
-                                                     ISC_LOG_DEBUG(1),
-                                                     "acache cleaner: "
-                                                     "still overmem, "
-                                                     "reset and try again");
-                                       next = entry;
-                                       continue;
-                               }
-                       }
-
-                       UNLOCK(&acache->lock);
-                       end_cleaning(cleaner, event);
-                       return;
-               }
-
-               entry = next;
-       }
-
-       /*
-        * We have successfully performed a cleaning increment but have
-        * not gone through the entire cache.  Remember the entry that will
-        * be the starting point in the next clean-up, and reschedule another
-        * batch.  If it fails, just try to continue anyway.
-        */
-       INSIST(next != NULL);
-       dns_acache_detachentry(&cleaner->current_entry);
-       dns_acache_attachentry(next, &cleaner->current_entry);
-
-       UNLOCK(&acache->lock);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
-                     ISC_LOG_DEBUG(1), "acache cleaner: checked %d entries, "
-                     "mem inuse %lu, sleeping", cleaner->increment,
-                     (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
-       isc_task_send(task, &event);
-       INSIST(CLEANER_BUSY(cleaner));
-
-       return;
-}
-
-/*
- * This is called when the acache either surpasses its upper limit
- * or shrinks beyond its lower limit.
- */
-static void
-acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event) {
-       acache_cleaner_t *cleaner = event->ev_arg;
-       isc_boolean_t want_cleaning = ISC_FALSE;
-
-       UNUSED(task);
-
-       INSIST(event->ev_type == DNS_EVENT_ACACHEOVERMEM);
-       INSIST(cleaner->overmem_event == NULL);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
-                     ISC_LOG_DEBUG(1), "overmem_cleaning_action called, "
-                     "overmem = %d, state = %d", cleaner->overmem,
-                     cleaner->state);
-
-       LOCK(&cleaner->lock);
-
-       if (cleaner->overmem) {
-               if (cleaner->state == cleaner_s_idle)
-                       want_cleaning = ISC_TRUE;
-       } else {
-               if (cleaner->state == cleaner_s_busy)
-                       /*
-                        * end_cleaning() can't be called here because
-                        * then both cleaner->overmem_event and
-                        * cleaner->resched_event will point to this
-                        * event.  Set the state to done, and then
-                        * when the acache_incremental_cleaning_action() event
-                        * is posted, it will handle the end_cleaning.
-                        */
-                       cleaner->state = cleaner_s_done;
-       }
-
-       cleaner->overmem_event = event;
-
-       UNLOCK(&cleaner->lock);
-
-       if (want_cleaning)
-               begin_cleaning(cleaner);
-}
-
-static void
-water(void *arg, int mark) {
-       dns_acache_t *acache = arg;
-       isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                     DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1),
-                     "acache memory reaches %s watermark, mem inuse %lu",
-                     overmem ? "high" : "low",
-                     (unsigned long)isc_mem_inuse(acache->mctx));
-
-       LOCK(&acache->cleaner.lock);
-
-       if (acache->cleaner.overmem != overmem) {
-               acache->cleaner.overmem = overmem;
-
-               if (acache->cleaner.overmem_event != NULL)
-                       isc_task_send(acache->task,
-                                     &acache->cleaner.overmem_event);
-               isc_mem_waterack(acache->mctx, mark);
-       }
-
-       UNLOCK(&acache->cleaner.lock);
-}
-
-/*
- * The cleaner task is shutting down; do the necessary cleanup.
- */
-static void
-acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
-       dns_acache_t *acache = event->ev_arg;
-       isc_boolean_t should_free = ISC_FALSE;
-
-       INSIST(task == acache->task);
-       INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
-       INSIST(DNS_ACACHE_VALID(acache));
-
-       ATRACE("acache cleaner shutdown");
-
-       if (CLEANER_BUSY(&acache->cleaner))
-               end_cleaning(&acache->cleaner, event);
-       else
-               isc_event_free(&event);
-
-       LOCK(&acache->lock);
-
-       acache->live_cleaners--;
-       INSIST(acache->live_cleaners == 0);
-
-       if (isc_refcount_current(&acache->refs) == 0) {
-               INSIST(check_noentry(acache) == ISC_TRUE);
-               should_free = ISC_TRUE;
-       }
-
-       /*
-        * By detaching the timer in the context of its task,
-        * we are guaranteed that there will be no further timer
-        * events.
-        */
-       if (acache->cleaner.cleaning_timer != NULL)
-               isc_timer_detach(&acache->cleaner.cleaning_timer);
-
-       /* Make sure we don't reschedule anymore. */
-       (void)isc_task_purge(task, NULL, DNS_EVENT_ACACHECLEAN, NULL);
-
-       UNLOCK(&acache->lock);
-
-       if (should_free)
-               destroy(acache);
-}
-
-/*
- *     Public functions.
- */
-
-isc_result_t
-dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
-                 isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr)
-{
-       int i;
-       isc_result_t result;
-       dns_acache_t *acache;
-
-       REQUIRE(acachep != NULL && *acachep == NULL);
-       REQUIRE(mctx != NULL);
-       REQUIRE(taskmgr != NULL);
-
-       acache = isc_mem_get(mctx, sizeof(*acache));
-       if (acache == NULL)
-               return (ISC_R_NOMEMORY);
-
-       ATRACE("create");
-
-       result = isc_refcount_init(&acache->refs, 1);
-       if (result != ISC_R_SUCCESS) {
-               isc_mem_put(mctx, acache, sizeof(*acache));
-               return (result);
-       }
-
-       result = isc_mutex_init(&acache->lock);
-       if (result != ISC_R_SUCCESS) {
-               isc_refcount_decrement(&acache->refs, NULL);
-               isc_refcount_destroy(&acache->refs);
-               isc_mem_put(mctx, acache, sizeof(*acache));
-               return (result);
-       }
-
-       acache->mctx = NULL;
-       isc_mem_attach(mctx, &acache->mctx);
-       ISC_LIST_INIT(acache->entries);
-
-       acache->shutting_down = ISC_FALSE;
-
-       acache->task = NULL;
-       acache->entrylocks = NULL;
-
-       result = isc_task_create(taskmgr, 1, &acache->task);
-       if (result != ISC_R_SUCCESS) {
-               UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                "isc_task_create() failed(): %s",
-                                dns_result_totext(result));
-               result = ISC_R_UNEXPECTED;
-               goto cleanup;
-       }
-       isc_task_setname(acache->task, "acachetask", acache);
-       ISC_EVENT_INIT(&acache->cevent, sizeof(acache->cevent), 0, NULL,
-                      DNS_EVENT_ACACHECONTROL, shutdown_task, NULL,
-                      NULL, NULL, NULL);
-       acache->cevent_sent = ISC_FALSE;
-
-       acache->dbentries = 0;
-       for (i = 0; i < DBBUCKETS; i++)
-               ISC_LIST_INIT(acache->dbbucket[i]);
-
-       acache->entrylocks = isc_mem_get(mctx, sizeof(*acache->entrylocks) *
-                                        DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
-       if (acache->entrylocks == NULL) {
-               result = ISC_R_NOMEMORY;
-               goto cleanup;
-       }
-       for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) {
-               result = ACACHE_INITLOCK(&acache->entrylocks[i]);
-               if (result != ISC_R_SUCCESS) {
-                       while (i-- > 0)
-                               ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
-                       isc_mem_put(mctx, acache->entrylocks,
-                                   sizeof(*acache->entrylocks) *
-                                   DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
-                       acache->entrylocks = NULL;
-                       goto cleanup;
-               }
-       }
-
-       acache->live_cleaners = 0;
-       result = acache_cleaner_init(acache, timermgr, &acache->cleaner);
-       if (result != ISC_R_SUCCESS)
-               goto cleanup;
-
-       acache->stats.cleaner_runs = 0;
-       reset_stats(acache);
-
-       acache->magic = ACACHE_MAGIC;
-
-       *acachep = acache;
-       return (ISC_R_SUCCESS);
-
- cleanup:
-       if (acache->task != NULL)
-               isc_task_detach(&acache->task);
-       DESTROYLOCK(&acache->lock);
-       isc_refcount_decrement(&acache->refs, NULL);
-       isc_refcount_destroy(&acache->refs);
-       if (acache->entrylocks != NULL) {
-               for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++)
-                       ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
-               isc_mem_put(mctx, acache->entrylocks,
-                           sizeof(*acache->entrylocks) *
-                           DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
-       }
-       isc_mem_put(mctx, acache, sizeof(*acache));
-       isc_mem_detach(&mctx);
-
-       return (result);
-}
-
-void
-dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) {
-       REQUIRE(DNS_ACACHE_VALID(source));
-       REQUIRE(targetp != NULL && *targetp == NULL);
-
-       AATRACE(source, "attach");
-
-       isc_refcount_increment(&source->refs, NULL);
-
-       *targetp = source;
-}
-
-void
-dns_acache_countquerymiss(dns_acache_t *acache) {
-       acache->stats.misses++;         /* XXXSK danger: unlocked! */
-       acache->stats.queries++;        /* XXXSK danger: unlocked! */
-}
-
-void
-dns_acache_detach(dns_acache_t **acachep) {
-       dns_acache_t *acache;
-       unsigned int refs;
-       isc_boolean_t should_free = ISC_FALSE;
-
-       REQUIRE(acachep != NULL && DNS_ACACHE_VALID(*acachep));
-       acache = *acachep;
-
-       ATRACE("detach");
-
-       isc_refcount_decrement(&acache->refs, &refs);
-       if (refs == 0) {
-               INSIST(check_noentry(acache) == ISC_TRUE);
-               should_free = ISC_TRUE;
-       }
-
-       *acachep = NULL;
-
-       /*
-        * If we're exiting and the cleaner task exists, let it free the cache.
-        */
-       if (should_free && acache->live_cleaners > 0) {
-               isc_task_shutdown(acache->task);
-               should_free = ISC_FALSE;
-       }
-
-       if (should_free)
-               destroy(acache);
-}
-
-void
-dns_acache_shutdown(dns_acache_t *acache) {
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       LOCK(&acache->lock);
-
-       ATRACE("shutdown");
-
-       if (!acache->shutting_down) {
-               isc_event_t *event;
-               dns_acache_t *acache_evarg = NULL;
-
-               INSIST(!acache->cevent_sent);
-
-               acache->shutting_down = ISC_TRUE;
-
-               isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0);
-
-               /*
-                * Self attach the object in order to prevent it from being
-                * destroyed while waiting for the event.
-                */
-               dns_acache_attach(acache, &acache_evarg);
-               event = &acache->cevent;
-               event->ev_arg = acache_evarg;
-               isc_task_send(acache->task, &event);
-               acache->cevent_sent = ISC_TRUE;
-       }
-
-       UNLOCK(&acache->lock);
-}
-
-isc_result_t
-dns_acache_setdb(dns_acache_t *acache, dns_db_t *db) {
-       int bucket;
-       dbentry_t *dbentry;
-       isc_result_t result = ISC_R_SUCCESS;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(db != NULL);
-
-       ATRACE("setdb");
-
-       LOCK(&acache->lock);
-
-       dbentry = NULL;
-       result = finddbent(acache, db, &dbentry);
-       if (result == ISC_R_SUCCESS) {
-               result = ISC_R_EXISTS;
-               goto end;
-       }
-       result = ISC_R_SUCCESS;
-
-       dbentry = isc_mem_get(acache->mctx, sizeof(*dbentry));
-       if (dbentry == NULL) {
-               result = ISC_R_NOMEMORY;
-               goto end;
-       }
-
-       ISC_LINK_INIT(dbentry, link);
-       ISC_LIST_INIT(dbentry->originlist);
-       ISC_LIST_INIT(dbentry->referlist);
-
-       dbentry->db = NULL;
-       dns_db_attach(db, &dbentry->db);
-
-       bucket = isc_hash_function(&db, sizeof(db), ISC_TRUE, NULL) % DBBUCKETS;
-
-       ISC_LIST_APPEND(acache->dbbucket[bucket], dbentry, link);
-
-       acache->dbentries++;
-
- end:
-       UNLOCK(&acache->lock);
-
-       return (result);
-}
-
-isc_result_t
-dns_acache_putdb(dns_acache_t *acache, dns_db_t *db) {
-       int bucket;
-       isc_result_t result;
-       dbentry_t *dbentry;
-       dns_acacheentry_t *entry;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(db != NULL);
-
-       ATRACE("putdb");
-
-       LOCK(&acache->lock);
-
-       dbentry = NULL;
-       result = finddbent(acache, db, &dbentry);
-       if (result != ISC_R_SUCCESS) {
-               /*
-                * The entry may have not been created due to memory shortage.
-                */
-               UNLOCK(&acache->lock);
-               return (ISC_R_NOTFOUND);
-       }
-
-       /*
-        * Release corresponding cache entries: for each entry, release all
-        * links the entry has, and then callback to the entry holder (if any).
-        * If no other external references exist (this can happen if the
-        * original holder has canceled callback,) destroy it here.
-        */
-       while ((entry = ISC_LIST_HEAD(dbentry->originlist)) != NULL) {
-               ACACHE_LOCK(&acache->entrylocks[entry->locknum],
-                           isc_rwlocktype_write);
-
-               /*
-                * Releasing olink first would avoid finddbent() in
-                * unlink_dbentries().
-                */
-               ISC_LIST_UNLINK(dbentry->originlist, entry, olink);
-               if (acache->cleaner.current_entry != entry)
-                       ISC_LIST_UNLINK(acache->entries, entry, link);
-               unlink_dbentries(acache, entry);
-
-               if (entry->callback != NULL)
-                       (entry->callback)(entry, &entry->cbarg);
-               entry->callback = NULL;
-
-               ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                             isc_rwlocktype_write);
-
-               if (acache->cleaner.current_entry != entry)
-                       dns_acache_detachentry(&entry);
-       }
-       while ((entry = ISC_LIST_HEAD(dbentry->referlist)) != NULL) {
-               ACACHE_LOCK(&acache->entrylocks[entry->locknum],
-                           isc_rwlocktype_write);
-
-               ISC_LIST_UNLINK(dbentry->referlist, entry, rlink);
-               if (acache->cleaner.current_entry != entry)
-                       ISC_LIST_UNLINK(acache->entries, entry, link);
-               unlink_dbentries(acache, entry);
-
-               if (entry->callback != NULL)
-                       (entry->callback)(entry, &entry->cbarg);
-               entry->callback = NULL;
-
-               ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                             isc_rwlocktype_write);
-
-               if (acache->cleaner.current_entry != entry)
-                       dns_acache_detachentry(&entry);
-       }
-
-       INSIST(ISC_LIST_EMPTY(dbentry->originlist) &&
-              ISC_LIST_EMPTY(dbentry->referlist));
-
-       bucket = isc_hash_function(&db, sizeof(db), ISC_TRUE, NULL) % DBBUCKETS;
-
-       ISC_LIST_UNLINK(acache->dbbucket[bucket], dbentry, link);
-       dns_db_detach(&dbentry->db);
-
-       isc_mem_put(acache->mctx, dbentry, sizeof(*dbentry));
-
-       acache->dbentries--;
-
-       acache->stats.deleted++;
-
-       UNLOCK(&acache->lock);
-
-       return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
-                      void (*callback)(dns_acacheentry_t *, void **),
-                      void *cbarg, dns_acacheentry_t **entryp)
-{
-       dns_acacheentry_t *newentry;
-       isc_result_t result;
-       isc_uint32_t r;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(entryp != NULL && *entryp == NULL);
-       REQUIRE(origdb != NULL);
-
-       /*
-        * Should we exceed our memory limit for some reason (for
-        * example, if the cleaner does not run aggressively enough),
-        * then we will not create additional entries.
-        *
-        * XXXSK: It might be better to lock the acache->cleaner->lock,
-        * but locking may be an expensive bottleneck. If we misread
-        * the value, we will occasionally refuse to create a few
-        * cache entries, or create a few that we should not. I do not
-        * expect this to happen often, and it will not have very bad
-        * effects when it does. So no lock for now.
-        */
-       if (acache->cleaner.overmem) {
-               acache->stats.overmem_nocreates++; /* XXXSK danger: unlocked! */
-               return (ISC_R_NORESOURCES);
-       }
-
-       newentry = isc_mem_get(acache->mctx, sizeof(*newentry));
-       if (newentry == NULL) {
-               acache->stats.nomem++;  /* XXXMLG danger: unlocked! */
-               return (ISC_R_NOMEMORY);
-       }
-
-       isc_random_get(&r);
-       newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT;
-
-       result = isc_refcount_init(&newentry->references, 1);
-       if (result != ISC_R_SUCCESS) {
-               isc_mem_put(acache->mctx, newentry, sizeof(*newentry));
-               return (result);
-       };
-
-       ISC_LINK_INIT(newentry, link);
-       ISC_LINK_INIT(newentry, olink);
-       ISC_LINK_INIT(newentry, rlink);
-
-       newentry->acache = NULL;
-       dns_acache_attach(acache, &newentry->acache);
-
-       newentry->zone = NULL;
-       newentry->db = NULL;
-       newentry->version = NULL;
-       newentry->node = NULL;
-       newentry->foundname = NULL;
-
-       newentry->callback = callback;
-       newentry->cbarg = cbarg;
-       newentry->origdb = NULL;
-       dns_db_attach(origdb, &newentry->origdb);
-
-       isc_stdtime_get(&newentry->lastused);
-
-       newentry->magic = ACACHEENTRY_MAGIC;
-
-       *entryp = newentry;
-
-       return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
-                   dns_db_t **dbp, dns_dbversion_t **versionp,
-                   dns_dbnode_t **nodep, dns_name_t *fname,
-                   dns_message_t *msg, isc_stdtime_t now)
-{
-       isc_result_t result = ISC_R_SUCCESS;
-       dns_rdataset_t *erdataset;
-       isc_stdtime32_t now32;
-       dns_acache_t *acache;
-       int locknum;
-
-       REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-       REQUIRE(zonep == NULL || *zonep == NULL);
-       REQUIRE(dbp != NULL && *dbp == NULL);
-       REQUIRE(versionp != NULL && *versionp == NULL);
-       REQUIRE(nodep != NULL && *nodep == NULL);
-       REQUIRE(fname != NULL);
-       REQUIRE(msg != NULL);
-       acache = entry->acache;
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       locknum = entry->locknum;
-       ACACHE_LOCK(&acache->entrylocks[locknum], isc_rwlocktype_read);
-
-       isc_stdtime_convert32(now, &now32);
-       acache_storetime(entry, now32);
-
-       if (entry->zone != NULL && zonep != NULL)
-               dns_zone_attach(entry->zone, zonep);
-
-       if (entry->db == NULL) {
-               *dbp = NULL;
-               *versionp = NULL;
-       } else {
-               dns_db_attach(entry->db, dbp);
-               dns_db_attachversion(entry->db, entry->version, versionp);
-       }
-       if (entry->node == NULL)
-               *nodep = NULL;
-       else {
-               dns_db_attachnode(entry->db, entry->node, nodep);
-
-               INSIST(entry->foundname != NULL);
-               dns_name_copy(entry->foundname, fname, NULL);
-               for (erdataset = ISC_LIST_HEAD(entry->foundname->list);
-                    erdataset != NULL;
-                    erdataset = ISC_LIST_NEXT(erdataset, link)) {
-                       dns_rdataset_t *ardataset;
-
-                       ardataset = NULL;
-                       result = dns_message_gettemprdataset(msg, &ardataset);
-                       if (result != ISC_R_SUCCESS) {
-                               ACACHE_UNLOCK(&acache->entrylocks[locknum],
-                                             isc_rwlocktype_read);
-                               goto fail;
-                       }
-
-                       /*
-                        * XXXJT: if we simply clone the rdataset, we'll get
-                        * lost wrt cyclic ordering.  We'll need an additional
-                        * trick to get the latest counter from the original
-                        * header.
-                        */
-                       dns_rdataset_clone(erdataset, ardataset);
-                       ISC_LIST_APPEND(fname->list, ardataset, link);
-               }
-       }
-
-       entry->acache->stats.hits++; /* XXXMLG danger: unlocked! */
-       entry->acache->stats.queries++;
-
-       ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read);
-
-       return (result);
-
-  fail:
-       while ((erdataset = ISC_LIST_HEAD(fname->list)) != NULL) {
-               ISC_LIST_UNLINK(fname->list, erdataset, link);
-               dns_rdataset_disassociate(erdataset);
-               dns_message_puttemprdataset(msg, &erdataset);
-       }
-       if (*nodep != NULL)
-               dns_db_detachnode(*dbp, nodep);
-       if (*versionp != NULL)
-               dns_db_closeversion(*dbp, versionp, ISC_FALSE);
-       if (*dbp != NULL)
-               dns_db_detach(dbp);
-       if (zonep != NULL && *zonep != NULL)
-               dns_zone_detach(zonep);
-
-       return (result);
-}
-
-isc_result_t
-dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
-                   dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
-                   dns_dbnode_t *node, dns_name_t *fname)
-{
-       isc_result_t result;
-       dbentry_t *odbent;
-       dbentry_t *rdbent = NULL;
-       isc_boolean_t close_version = ISC_FALSE;
-       dns_acacheentry_t *dummy_entry = NULL;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-       REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
-       LOCK(&acache->lock);    /* XXX: need to lock it here for ordering */
-       ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
-
-       /* Set zone */
-       if (zone != NULL)
-               dns_zone_attach(zone, &entry->zone);
-       /* Set DB */
-       if (db != NULL)
-               dns_db_attach(db, &entry->db);
-       /*
-        * Set DB version.  If the version is not given by the caller,
-        * which is the case for glue or cache DBs, use the current version.
-        */
-       if (version == NULL) {
-               if (db != NULL) {
-                       dns_db_currentversion(db, &version);
-                       close_version = ISC_TRUE;
-               }
-       }
-       if (version != NULL) {
-               INSIST(db != NULL);
-               dns_db_attachversion(db, version, &entry->version);
-       }
-       if (close_version)
-               dns_db_closeversion(db, &version, ISC_FALSE);
-       /* Set DB node. */
-       if (node != NULL) {
-               INSIST(db != NULL);
-               dns_db_attachnode(db, node, &entry->node);
-       }
-
-       /*
-        * Set list of the corresponding rdatasets, if given.
-        * To minimize the overhead and memory consumption, we'll do this for
-        * positive cache only, in which case the DB node is non NULL.
-        * We do not want to cache incomplete information, so give up the
-        * entire entry when a memory shortage happen during the process.
-        */
-       if (node != NULL) {
-               dns_rdataset_t *ardataset, *crdataset;
-
-               entry->foundname = isc_mem_get(acache->mctx,
-                                              sizeof(*entry->foundname));
-
-               if (entry->foundname == NULL) {
-                       result = ISC_R_NOMEMORY;
-                       goto fail;
-               }
-               dns_name_init(entry->foundname, NULL);
-               result = dns_name_dup(fname, acache->mctx,
-                                     entry->foundname);
-               if (result != ISC_R_SUCCESS)
-                       goto fail;
-
-               for (ardataset = ISC_LIST_HEAD(fname->list);
-                    ardataset != NULL;
-                    ardataset = ISC_LIST_NEXT(ardataset, link)) {
-                       crdataset = isc_mem_get(acache->mctx,
-                                               sizeof(*crdataset));
-                       if (crdataset == NULL) {
-                               result = ISC_R_NOMEMORY;
-                               goto fail;
-                       }
-
-                       dns_rdataset_init(crdataset);
-                       dns_rdataset_clone(ardataset, crdataset);
-                       ISC_LIST_APPEND(entry->foundname->list, crdataset,
-                                       link);
-               }
-       }
-
-       odbent = NULL;
-       result = finddbent(acache, entry->origdb, &odbent);
-       if (result != ISC_R_SUCCESS)
-               goto fail;
-       if (db != NULL) {
-               rdbent = NULL;
-               result = finddbent(acache, db, &rdbent);
-               if (result != ISC_R_SUCCESS)
-                       goto fail;
-       }
-
-       ISC_LIST_APPEND(acache->entries, entry, link);
-       ISC_LIST_APPEND(odbent->originlist, entry, olink);
-       if (rdbent != NULL)
-               ISC_LIST_APPEND(rdbent->referlist, entry, rlink);
-
-       /*
-        * The additional cache needs an implicit reference to entries in its
-        * link.
-        */
-       dns_acache_attachentry(entry, &dummy_entry);
-
-       ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                     isc_rwlocktype_write);
-
-       acache->stats.adds++;
-       UNLOCK(&acache->lock);
-
-       return (ISC_R_SUCCESS);
-
- fail:
-       clear_entry(acache, entry);
-
-       ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                     isc_rwlocktype_write);
-       UNLOCK(&acache->lock);
-
-       return (result);
-}
-
-isc_boolean_t
-dns_acache_cancelentry(dns_acacheentry_t *entry) {
-       dns_acache_t *acache;
-       isc_boolean_t callback_active;
-
-       REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
-       acache = entry->acache;
-
-       INSIST(DNS_ACACHE_VALID(entry->acache));
-
-       LOCK(&acache->lock);
-       ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
-
-       callback_active = ISC_TF(entry->cbarg != NULL);
-
-       /*
-        * Release dependencies stored in this entry as much as possible.
-        * The main link cannot be released, since the acache object has
-        * a reference to this entry; the empty entry will be released in
-        * the next cleaning action.
-        */
-       unlink_dbentries(acache, entry);
-       clear_entry(entry->acache, entry);
-
-       entry->callback = NULL;
-       entry->cbarg = NULL;
-
-       ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
-                     isc_rwlocktype_write);
-       UNLOCK(&acache->lock);
-
-       return (callback_active);
-}
-
-void
-dns_acache_attachentry(dns_acacheentry_t *source,
-                      dns_acacheentry_t **targetp)
-{
-       REQUIRE(DNS_ACACHEENTRY_VALID(source));
-       REQUIRE(targetp != NULL && *targetp == NULL);
-
-       isc_refcount_increment(&source->references, NULL);
-
-       *targetp = source;
-}
-
-void
-dns_acache_detachentry(dns_acacheentry_t **entryp) {
-       dns_acacheentry_t *entry;
-       unsigned int refs;
-
-       REQUIRE(entryp != NULL && DNS_ACACHEENTRY_VALID(*entryp));
-       entry = *entryp;
-
-       isc_refcount_decrement(&entry->references, &refs);
-
-       /*
-        * If there are no references to the entry, the entry must have been
-        * unlinked and can be destroyed safely.
-        */
-       if (refs == 0) {
-               INSIST(!ISC_LINK_LINKED(entry, link));
-               (*entryp)->acache->stats.deleted++;
-               destroy_entry(entry);
-       }
-
-       *entryp = NULL;
-}
-
-void
-dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t) {
-       isc_interval_t interval;
-       isc_result_t result;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       ATRACE("dns_acache_setcleaninginterval");
-
-       LOCK(&acache->lock);
-
-       /*
-        * It may be the case that the acache has already shut down.
-        * If so, it has no timer.  (Not sure if this can really happen.)
-        */
-       if (acache->cleaner.cleaning_timer == NULL)
-               goto unlock;
-
-       acache->cleaner.cleaning_interval = t;
-
-       if (t == 0) {
-               result = isc_timer_reset(acache->cleaner.cleaning_timer,
-                                        isc_timertype_inactive,
-                                        NULL, NULL, ISC_TRUE);
-       } else {
-               isc_interval_set(&interval, acache->cleaner.cleaning_interval,
-                                0);
-               result = isc_timer_reset(acache->cleaner.cleaning_timer,
-                                        isc_timertype_ticker,
-                                        NULL, &interval, ISC_FALSE);
-       }
-       if (result != ISC_R_SUCCESS)
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_ACACHE, ISC_LOG_WARNING,
-                             "could not set acache cleaning interval: %s",
-                             isc_result_totext(result));
-       else
-               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
-                             DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE,
-                             "acache %p cleaning interval set to %d.",
-                             acache, t);
-
- unlock:
-       UNLOCK(&acache->lock);
-}
-
-/*
- * This function was derived from cache.c:dns_cache_setcachesize().  See the
- * function for more details about the logic.
- */
-void
-dns_acache_setcachesize(dns_acache_t *acache, size_t size) {
-       size_t hiwater, lowater;
-
-       REQUIRE(DNS_ACACHE_VALID(acache));
-
-       if (size != 0U && size < DNS_ACACHE_MINSIZE)
-               size = DNS_ACACHE_MINSIZE;
-
-       hiwater = size - (size >> 3);
-       lowater = size - (size >> 2);
-
-       if (size == 0U || hiwater == 0U || lowater == 0U)
-               isc_mem_setwater(acache->mctx, water, acache, 0, 0);
-       else
-               isc_mem_setwater(acache->mctx, water, acache,
-                                hiwater, lowater);
-}
index c876fa155eb1e5f89f0398b16de42d51687fa641..32342436262404f3de6d7ea5452ed110d9468764 100644 (file)
 #define DCTX_MAGIC     ISC_MAGIC('D', 'C', 'T', 'X')
 #define VALID_DCTX(x)  ISC_MAGIC_VALID(x, DCTX_MAGIC)
 
-#define TABLE_READY                                                    \
-       do {                                                            \
-               unsigned int i;                                         \
-                                                                       \
-               if ((cctx->allowed & DNS_COMPRESS_READY) == 0) {        \
-                       cctx->allowed |= DNS_COMPRESS_READY;            \
-                       for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++)    \
-                               cctx->table[i] = NULL;                  \
-               }                                                       \
-       } while (0)
+static unsigned char maptolower[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+       0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+       0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+       0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+       0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+       0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+       0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+       0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+       0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+       0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+       0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+       0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+       0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+       0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+       0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+       0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+/*
+ * The tableindex array below is of size 256, one entry for each
+ * unsigned char value. The tableindex array elements are dependent on
+ * DNS_COMPRESS_TABLESIZE. The table was created using the following
+ * function.
+ *
+ * static void
+ * gentable(unsigned char *table) {
+ *         unsigned int i;
+ *         const unsigned int left = DNS_COMPRESS_TABLESIZE - 38;
+ *         long r;
+ *
+ *         for (i = 0; i < 26; i++) {
+ *                 table['A' + i] = i;
+ *                 table['a' + i] = i;
+ *         }
+ *
+ *         for (i = 0; i <= 9; i++)
+ *                 table['0' + i] = i + 26;
+ *
+ *         table['-'] = 36;
+ *         table['_'] = 37;
+ *
+ *         for (i = 0; i < 256; i++) {
+ *                 if ((i >= 'a' && i <= 'z') ||
+ *                     (i >= 'A' && i <= 'Z') ||
+ *                     (i >= '0' && i <= '9') ||
+ *                     (i == '-') ||
+ *                     (i == '_'))
+ *                         continue;
+ *                 r = random() % left;
+ *                 table[i] = 38 + r;
+ *         }
+ * }
+ */
+static unsigned char tableindex[256] = {
+       0x3e, 0x3e, 0x33, 0x2d, 0x30, 0x38, 0x31, 0x3c,
+       0x2b, 0x33, 0x30, 0x3f, 0x2d, 0x3c, 0x36, 0x3a,
+       0x28, 0x2c, 0x2a, 0x37, 0x3d, 0x34, 0x35, 0x2d,
+       0x39, 0x2b, 0x2f, 0x2c, 0x3b, 0x32, 0x2b, 0x39,
+       0x30, 0x38, 0x28, 0x3c, 0x32, 0x33, 0x39, 0x38,
+       0x27, 0x2b, 0x39, 0x30, 0x27, 0x24, 0x2f, 0x2b,
+       0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
+       0x22, 0x3a, 0x29, 0x36, 0x31, 0x3c, 0x35, 0x26,
+       0x31, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+       0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+       0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+       0x17, 0x18, 0x19, 0x3e, 0x3b, 0x39, 0x2f, 0x25,
+       0x27, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+       0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+       0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+       0x17, 0x18, 0x19, 0x36, 0x3b, 0x2f, 0x2f, 0x2e,
+       0x29, 0x33, 0x2a, 0x36, 0x28, 0x3f, 0x2e, 0x29,
+       0x2c, 0x29, 0x36, 0x2d, 0x32, 0x3d, 0x33, 0x2a,
+       0x2e, 0x2f, 0x3b, 0x30, 0x3d, 0x39, 0x2b, 0x36,
+       0x2a, 0x2f, 0x2c, 0x26, 0x3a, 0x37, 0x30, 0x3d,
+       0x2a, 0x36, 0x33, 0x2c, 0x38, 0x3d, 0x32, 0x3e,
+       0x26, 0x2a, 0x2c, 0x35, 0x27, 0x39, 0x3b, 0x31,
+       0x2a, 0x37, 0x3c, 0x27, 0x32, 0x29, 0x39, 0x37,
+       0x34, 0x3f, 0x39, 0x2e, 0x38, 0x2b, 0x2c, 0x3e,
+       0x3b, 0x3b, 0x2d, 0x33, 0x3b, 0x3b, 0x32, 0x3d,
+       0x3f, 0x3a, 0x34, 0x26, 0x35, 0x30, 0x31, 0x39,
+       0x27, 0x2f, 0x3d, 0x35, 0x35, 0x36, 0x2e, 0x29,
+       0x38, 0x27, 0x34, 0x32, 0x2c, 0x3c, 0x31, 0x28,
+       0x37, 0x38, 0x37, 0x34, 0x33, 0x29, 0x32, 0x34,
+       0x3f, 0x26, 0x34, 0x34, 0x32, 0x27, 0x30, 0x33,
+       0x33, 0x2d, 0x2b, 0x28, 0x3f, 0x33, 0x2b, 0x39,
+       0x37, 0x39, 0x2c, 0x3d, 0x35, 0x39, 0x27, 0x2f
+};
 
 /***
  ***   Compression
@@ -51,7 +145,11 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) {
        cctx->mctx = mctx;
        cctx->count = 0;
        cctx->allowed = DNS_COMPRESS_ENABLED;
+
+       memset(&cctx->table[0], 0, sizeof(cctx->table));
+
        cctx->magic = CCTX_MAGIC;
+
        return (ISC_R_SUCCESS);
 }
 
@@ -62,20 +160,19 @@ dns_compress_invalidate(dns_compress_t *cctx) {
 
        REQUIRE(VALID_CCTX(cctx));
 
-       if ((cctx->allowed & DNS_COMPRESS_READY) != 0) {
-               for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
-                       while (cctx->table[i] != NULL) {
-                               node = cctx->table[i];
-                               cctx->table[i] = cctx->table[i]->next;
-                               if ((node->offset & 0x8000) != 0)
-                                       isc_mem_put(cctx->mctx, node->r.base,
-                                                   node->r.length);
-                               if (node->count < DNS_COMPRESS_INITIALNODES)
-                                       continue;
-                               isc_mem_put(cctx->mctx, node, sizeof(*node));
-                       }
+       for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
+               while (cctx->table[i] != NULL) {
+                       node = cctx->table[i];
+                       cctx->table[i] = cctx->table[i]->next;
+                       if ((node->offset & 0x8000) != 0)
+                               isc_mem_put(cctx->mctx, node->r.base,
+                                           node->r.length);
+                       if (node->count < DNS_COMPRESS_INITIALNODES)
+                               continue;
+                       isc_mem_put(cctx->mctx, node, sizeof(*node));
                }
        }
+
        cctx->magic = 0;
        cctx->allowed = 0;
        cctx->edns = -1;
@@ -124,14 +221,6 @@ dns_compress_getedns(dns_compress_t *cctx) {
        return (cctx->edns);
 }
 
-#define NODENAME(node, name) \
-do { \
-       (name)->length = (node)->r.length; \
-       (name)->labels = (node)->labels; \
-       (name)->ndata = (node)->r.base; \
-       (name)->attributes = DNS_NAMEATTR_ABSOLUTE; \
-} while (0)
-
 /*
  * Find the longest match of name in the table.
  * If match is found return ISC_TRUE. prefix, suffix and offset are updated.
@@ -141,19 +230,19 @@ isc_boolean_t
 dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
                        dns_name_t *prefix, isc_uint16_t *offset)
 {
-       dns_name_t tname, nname;
+       dns_name_t tname;
        dns_compressnode_t *node = NULL;
-       unsigned int labels, hash, n;
+       unsigned int labels, index, n;
+       unsigned int numlabels;
+       unsigned char *p;
 
        REQUIRE(VALID_CCTX(cctx));
        REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
        REQUIRE(offset != NULL);
 
-       if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)
+       if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
                return (ISC_FALSE);
 
-       TABLE_READY;
-
        if (cctx->count == 0)
                return (ISC_FALSE);
 
@@ -161,27 +250,101 @@ dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
        INSIST(labels > 0);
 
        dns_name_init(&tname, NULL);
-       dns_name_init(&nname, NULL);
 
-       for (n = 0; n < labels - 1; n++) {
-               dns_name_getlabelsequence(name, n, labels - n, &tname);
-               hash = dns_name_hash(&tname, ISC_FALSE) %
-                      DNS_COMPRESS_TABLESIZE;
-               for (node = cctx->table[hash]; node != NULL; node = node->next)
+       numlabels = labels > 3U ? 3U : labels;
+       p = name->ndata;
+
+       for (n = 0; n < numlabels - 1; n++) {
+               unsigned char ch, llen;
+               unsigned int firstoffset, length;
+
+               firstoffset = p - name->ndata;
+               length = name->length - firstoffset;
+
+               /*
+                * We calculate the table index using the first
+                * character in the first label of the suffix name.
+                */
+               ch = p[1];
+               index = tableindex[ch];
+               if (ISC_LIKELY((cctx->allowed &
+                               DNS_COMPRESS_CASESENSITIVE) != 0))
                {
-                       NODENAME(node, &nname);
-                       if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) {
-                               if (dns_name_caseequal(&nname, &tname))
-                                       break;
-                       } else {
-                               if (dns_name_equal(&nname, &tname))
-                                       break;
+                       for (node = cctx->table[index];
+                            node != NULL;
+                            node = node->next)
+                       {
+                               if (ISC_UNLIKELY(node->name.length != length))
+                                       continue;
+
+                               if (ISC_LIKELY(memcmp(node->name.ndata,
+                                                     p, length) == 0))
+                                       goto found;
+                       }
+               } else {
+                       for (node = cctx->table[index];
+                            node != NULL;
+                            node = node->next)
+                       {
+                               unsigned int l, count;
+                               unsigned char c;
+                               unsigned char *label1, *label2;
+
+                               if (ISC_UNLIKELY(node->name.length != length))
+                                       continue;
+
+                               l = labels - n;
+                               if (ISC_UNLIKELY(node->name.labels != l))
+                                       continue;
+
+                               label1 = node->name.ndata;
+                               label2 = p;
+                               while (ISC_LIKELY(l-- > 0)) {
+                                       count = *label1++;
+                                       if (count != *label2++)
+                                               goto cont1;
+
+                                       /* no bitstring support */
+                                       INSIST(count <= 63);
+
+                                       /* Loop unrolled for performance */
+                                       while (ISC_LIKELY(count > 3)) {
+                                               c = maptolower[label1[0]];
+                                               if (c != maptolower[label2[0]])
+                                                       goto cont1;
+                                               c = maptolower[label1[1]];
+                                               if (c != maptolower[label2[1]])
+                                                       goto cont1;
+                                               c = maptolower[label1[2]];
+                                               if (c != maptolower[label2[2]])
+                                                       goto cont1;
+                                               c = maptolower[label1[3]];
+                                               if (c != maptolower[label2[3]])
+                                                       goto cont1;
+                                               count -= 4;
+                                               label1 += 4;
+                                               label2 += 4;
+                                       }
+                                       while (ISC_LIKELY(count-- > 0)) {
+                                               c = maptolower[*label1++];
+                                               if (c != maptolower[*label2++])
+                                                       goto cont1;
+                                       }
+                               }
+                               break;
+ cont1:
+                               continue;
                        }
                }
+
                if (node != NULL)
                        break;
+
+               llen = *p;
+               p += llen + 1;
        }
 
+ found:
        /*
         * If node == NULL, we found no match at all.
         */
@@ -212,7 +375,7 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        unsigned int start;
        unsigned int n;
        unsigned int count;
-       unsigned int hash;
+       unsigned int index;
        dns_compressnode_t *node;
        unsigned int length;
        unsigned int tlength;
@@ -223,11 +386,9 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        REQUIRE(VALID_CCTX(cctx));
        REQUIRE(dns_name_isabsolute(name));
 
-       if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)
+       if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
                return;
 
-       TABLE_READY;
-
        if (offset >= 0x4000)
                return;
        dns_name_init(&tname, NULL);
@@ -252,10 +413,19 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        r.base = tmp;
        dns_name_fromregion(&xname, &r);
 
+       if (count > 2U)
+               count = 2U;
+
        while (count > 0) {
+               unsigned char ch;
+
                dns_name_getlabelsequence(&xname, start, n, &tname);
-               hash = dns_name_hash(&tname, ISC_FALSE) %
-                      DNS_COMPRESS_TABLESIZE;
+               /*
+                * We calculate the table index using the first
+                * character in the first label of tname.
+                */
+               ch = tname.ndata[1];
+               index = tableindex[ch];
                tlength = name_length(&tname);
                toffset = (isc_uint16_t)(offset + (length - tlength));
                if (toffset >= 0x4000)
@@ -280,9 +450,13 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
                        toffset |= 0x8000;
                node->offset = toffset;
                dns_name_toregion(&tname, &node->r);
-               node->labels = (isc_uint8_t)dns_name_countlabels(&tname);
-               node->next = cctx->table[hash];
-               cctx->table[hash] = node;
+               dns_name_init(&node->name, NULL);
+               node->name.length = node->r.length;
+               node->name.ndata = node->r.base;
+               node->name.labels = tname.labels;
+               node->name.attributes = DNS_NAMEATTR_ABSOLUTE;
+               node->next = cctx->table[index];
+               cctx->table[index] = node;
                start++;
                n--;
                count--;
@@ -299,10 +473,7 @@ dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) {
 
        REQUIRE(VALID_CCTX(cctx));
 
-       if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)
-               return;
-
-       if ((cctx->allowed & DNS_COMPRESS_READY) == 0)
+       if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
                return;
 
        for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
index 163441b33b9fb34c94d445accdceb426d77f73c4..3e1c8d3dbbc32897ae656b71043b203be70f7d2f 100644 (file)
@@ -101,14 +101,12 @@ static dns_rdatasetmethods_t rdataset_methods = {
        NULL,                   /* getnoqname */
        NULL,                   /* addclosest */
        NULL,                   /* getclosest */
-       NULL,                   /* getadditional */
-       NULL,                   /* setadditional */
-       NULL,                   /* putadditional */
        rdataset_settrust,      /* settrust */
        NULL,                   /* expire */
        NULL,                   /* clearprefetch */
        NULL,                   /* setownercase */
-       NULL                    /* getownercase */
+       NULL,                   /* getownercase */
+       NULL                    /* addglue */
 };
 
 typedef struct ecdb_rdatasetiter {
index c7ae21dff66d6effc59c935dfa8d4e53768ca62e..0f13808f91ca2e096ad3ea481babe79cdd7be709 100644 (file)
@@ -10,7 +10,7 @@ top_srcdir =  @top_srcdir@
 
 VERSION=@BIND9_VERSION@
 
-HEADERS =      acache.h acl.h adb.h badcache.h bit.h byaddr.h \
+HEADERS =      acl.h adb.h badcache.h bit.h byaddr.h \
                cache.h callbacks.h catz.h cert.h \
                client.h clientinfo.h compress.h \
                db.h dbiterator.h dbtable.h diff.h dispatch.h \
diff --git a/lib/dns/include/dns/acache.h b/lib/dns/include/dns/acache.h
deleted file mode 100644 (file)
index 1f05c30..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2007, 2013, 2016  Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-/* $Id: acache.h,v 1.8 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_ACACHE_H
-#define DNS_ACACHE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*
- * Acache
- *
- * The Additional Cache Object
- *
- *     This module manages internal caching entries that correspond to
- *     the additional section data of a DNS DB node (an RRset header, more
- *     accurately).  An additional cache entry is expected to be (somehow)
- *     attached to a particular RR in a particular DB node, and contains a set
- *     of information of an additional data for the DB node.
- *
- *     An additional cache object is intended to be created as a per-view
- *     object, and manages all cache entries within the view.
- *
- *     The intended usage of the additional caching is to provide a short cut
- *     to additional glue RRs of an NS RR.  For each NS RR, it is often
- *     necessary to look for glue RRs to make a proper response.  Once the
- *     glue RRs are known, the additional caching allows the client to
- *     associate the information to the original NS RR so that further
- *     expensive lookups can be avoided for the NS RR.
- *
- *     Each additional cache entry contains information to identify a
- *     particular DB node and (optionally) an associated RRset.  The
- *     information consists of its zone, database, the version of the
- *     database, database node, and RRset.
- *
- *     A "negative" information can also be cached.  For example, if a glue
- *     RR does not exist as an authoritative data in the same zone as that
- *     of the NS RR, this fact can be cached by specifying a NULL pointer
- *     for the database, version, and node.  (See the description for
- *     dns_acache_getentry() below for more details.)
- *
- *     Since each member stored in an additional cache entry holds a reference
- *     to a corresponding object, a stale cache entry may cause unnecessary
- *     memory consumption.  For instance, when a zone is reloaded, additional
- *     cache entries that have a reference to the zone (and its DB and/or
- *     DB nodes) can delay the cleanup of the referred objects.  In order to
- *     minimize such a bad effect, this module provides several cleanup
- *     mechanisms.
- *
- *     The first one is a shutdown procedure called when the associated view
- *     is shut down.  In this case, dns_acache_shutdown() will be called and
- *     all cache entries will be purged.  This mechanism will help the
- *     situation when the configuration is reloaded or the main server is
- *     stopped.
- *
- *     Per-DB cleanup mechanism is also provided.  Each additional cache entry
- *     is associated with related DB, which is expected to have been
- *     registered when the DB was created by dns_acache_setdb().  If a
- *     particular DB is going to be destroyed, the primary holder of the DB,
- *     a typical example of which is a zone, will call dns_acache_putdb().
- *     Then this module will clean-up all cache entries associated with the
- *     DB.  This mechanism is effective when a secondary zone DB is going to
- *     be stale after a zone transfer.
- *
- *     Finally, this module supports for periodic clean-up of stale entries.
- *     Each cache entry has a timestamp field, which is updated every time
- *     the entry is referred.  A periodically invoked cleaner checks the
- *     timestamp of each entry, and purge entries that have not been referred
- *     for a certain period.  The cleaner interval can be specified by
- *     dns_acache_setcleaninginterval().  If the periodic clean-up is not
- *     enough, it is also possible to specify the upper limit of entries
- *     in terms of the memory consumption.  If the maximum value is
- *     specified, the cleaner is invoked when the memory consumption reaches
- *     the high watermark inferred from the maximum value.  In this case,
- *     the cleaner will use more aggressive algorithm to decide the "victim"
- *     entries.  The maximum value can be specified by
- *     dns_acache_setcachesize().
- *
- *     When a cache entry is going to be purged within this module, the
- *     callback function specified at the creation time will be called.
- *     The callback function is expected to release all internal resources
- *     related to the entry, which will typically be specific to DB
- *     implementation, and to call dns_acache_detachentry().  The callback
- *     mechanism is very important, since the holder of an additional cache
- *     entry may not be able to initiate the clean-up of the entry, due to
- *     the reference ordering.  For example, as long as an additional cache
- *     entry has a reference to a DB object, the DB cannot be freed, in which
- *     a DB node may have a reference to the cache entry.
- *
- *     Credits:
- *     The basic idea of this kind of short-cut for frequently used
- *     information is similar to the "pre-compiled answer" approach adopted
- *     in nsd by NLnet LABS with RIPE NCC.  Our work here is an independent
- *     effort, but the success of nsd encouraged us to pursue this path.
- *
- *     The design and implementation of the periodic memory management and
- *     the upper limitation of memory consumption was derived from the cache
- *     DB implementation of BIND9.
- *
- * MP:
- *     There are two main locks in this module.  One is for each entry, and
- *     the other is for the additional cache object.
- *
- * Reliability:
- *     The callback function for a cache entry is called with holding the
- *     entry lock.  Thus, it implicitly assumes the callback function does not
- *     call a function that can require the lock.  Typically, the only
- *     function that can be called from the callback function safely is
- *     dns_acache_detachentry().  The breakage of this implicit assumption
- *     may cause a deadlock.
- *
- * Resources:
- *     In a 32-bit architecture (such as i386), the following additional
- *     memory is required comparing to the case that disables this module.
- *     - 76 bytes for each additional cache entry
- *     - if the entry has a DNS name and associated RRset,
- *       * 44 bytes + size of the name (1-255 bytes)
- *       * 52 bytes x number_of_RRs
- *     - 28 bytes for each DB related to this module
- *
- *     Using the additional cache also requires extra memory consumption in
- *     the DB implementation.  In the current implementation for rbtdb, we
- *     need:
- *     - two additional pointers for each DB node (8 bytes for a 32-bit
- *       architecture
- *     - for each RR associated to an RR in a DB node, we also need
- *       a pointer and management objects to support the additional cache
- *       function.  These are allocated on-demand.  The total size is
- *       32 bytes for a 32-bit architecture.
- *
- * Security:
- *     Since this module does not handle any low-level data directly,
- *     no security issue specific to this module is anticipated.
- *
- * Standards:
- *     None.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/mutex.h>
-#include <isc/lang.h>
-#include <isc/refcount.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-/***
- *** Functions
- ***/
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
-                 isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr);
-/*
- * Create a new DNS additional cache object.
- *
- * Requires:
- *
- *     'mctx' is a valid memory context
- *
- *     'taskmgr' is a valid task manager
- *
- *     'timermgr' is a valid timer or NULL.  If NULL, no periodic cleaning of
- *     the cache will take place.
- *
- *     'acachep' is a valid pointer, and *acachep == NULL
- *
- * Ensures:
- *
- *     '*acachep' is attached to the newly created cache
- *
- * Returns:
- *
- *     ISC_R_SUCCESS
- *     ISC_R_NOMEMORY
- *     ISC_R_UNEXPECTED
- */
-
-void
-dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp);
-/*
- * Attach *targetp to cache.
- *
- * Requires:
- *
- *     'acache' is a valid additional cache.
- *
- *     'targetp' points to a NULL dns_acache_t *.
- *
- * Ensures:
- *
- *     *targetp is attached to the 'source' additional cache.
- */
-
-void
-dns_acache_detach(dns_acache_t **acachep);
-/*
- * Detach *acachep from its cache.
- *
- * Requires:
- *
- *     '*acachep' points to a valid additional cache.
- *
- * Ensures:
- *
- *     *acachep is NULL.
- *
- *     If '*acachep' is the last reference to the cache and the additional
- *     cache does not have an outstanding task, all resources used by the
- *     cache will be freed.
- */
-
-void
-dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t);
-/*
- * Set the periodic cleaning interval of an additional cache to 'interval'
- * seconds.
- */
-
-void
-dns_acache_setcachesize(dns_acache_t *acache, size_t size);
-/*
- * Set the maximum additional cache size.  0 means unlimited.
- */
-
-isc_result_t
-dns_acache_setdb(dns_acache_t *acache, dns_db_t *db);
-/*
- * Set 'db' in 'acache' when the db can be referred from acache, in order
- * to provide a hint for resolving the back reference.
- *
- * Requires:
- *     'acache' is a valid acache pointer.
- *     'db' is a valid DNS DB pointer.
- *
- * Ensures:
- *     'acache' will have a reference to 'db'.
- *
- * Returns:
- *     ISC_R_SUCCESS
- *     ISC_R_EXISTS    (which means the specified 'db' is already set)
- *     ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_putdb(dns_acache_t *acache, dns_db_t *db);
-/*
- * Release 'db' from 'acache' if it has been set by dns_acache_setdb().
- *
- * Requires:
- *     'acache' is a valid acache pointer.
- *     'db' is a valid DNS DB pointer.
- *
- * Ensures:
- *     'acache' will release the reference to 'db'.  Additionally, the content
- *     of each cache entry that is related to the 'db' will be released via
- *     the callback function.
- *
- * Returns:
- *     ISC_R_SUCCESS
- *     ISC_R_NOTFOUND  (which means the specified 'db' is not set in 'acache')
- *     ISC_R_NOMEMORY
- */
-
-void
-dns_acache_shutdown(dns_acache_t *acache);
-/*
- * Shutdown 'acache'.
- *
- * Requires:
- *
- *     '*acache' is a valid additional cache.
- */
-
-isc_result_t
-dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
-                      void (*callback)(dns_acacheentry_t *, void **),
-                      void *cbarg, dns_acacheentry_t **entryp);
-/*
- * Create an additional cache entry.  A new entry is created and attached to
- * the given additional cache object.  A callback function is also associated
- * with the created entry, which will be called when the cache entry is purged
- * for some reason.
- *
- * Requires:
- *
- *     'acache' is a valid additional cache.
- *     'entryp' is a valid pointer, and *entryp == NULL
- *     'origdb' is a valid DNS DB pointer.
- *     'callback' and 'cbarg' can be NULL.  In this case, however, the entry
- *     is meaningless (and will be cleaned-up in the next periodical
- *     cleaning).
- *
- * Ensures:
- *     '*entryp' will point to a new additional cache entry.
- *
- * Returns:
- *     ISC_R_SUCCESS
- *     ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
-                   dns_db_t **dbp, dns_dbversion_t **versionp,
-                   dns_dbnode_t **nodep, dns_name_t *fname,
-                   dns_message_t *msg, isc_stdtime_t now);
-/*
- * Get content from a particular additional cache entry.
- *
- * Requires:
- *
- *     'entry' is a valid additional cache entry.
- *     'zonep' is a NULL pointer or '*zonep' == NULL (this is the only
- *     optional parameter.)
- *     'dbp' is a valid pointer, and '*dbp' == NULL
- *     'versionp' is a valid pointer, and '*versionp' == NULL
- *     'nodep' is a valid pointer, and '*nodep' == NULL
- *     'fname' is a valid DNS name.
- *     'msg' is a valid DNS message.
- *
- * Ensures:
- *     Several possible cases can happen according to the content.
- *     1. For a positive cache entry,
- *     '*zonep' will point to the corresponding zone (if zonep is a valid
- *     pointer),
- *     '*dbp' will point to a DB for the zone,
- *     '*versionp' will point to its version, and
- *     '*nodep' will point to the corresponding DB node.
- *     'fname' will have the DNS name of the DB node and contain a list of
- *     rdataset for the node (which can be an empty list).
- *
- *     2. For a negative cache entry that means no corresponding zone exists,
- *     '*zonep' == NULL (if zonep is a valid pointer)
- *     '*dbp', '*versionp', and '*nodep' will be NULL.
- *
- *     3. For a negative cache entry that means no corresponding DB node
- *     exists, '*zonep' will point to the corresponding zone (if zonep is a
- *     valid pointer),
- *     '*dbp' will point to a corresponding DB for zone,
- *     '*versionp' will point to its version.
- *     '*nodep' will be kept as NULL.
- *     'fname' will not change.
- *
- *     On failure, no new references will be created.
- *
- * Returns:
- *     ISC_R_SUCCESS
- *     ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
-                   dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
-                   dns_dbnode_t *node, dns_name_t *fname);
-/*
- * Set content to a particular additional cache entry.
- *
- * Requires:
- *     'acache' is a valid additional cache.
- *     'entry' is a valid additional cache entry.
- *     All the others pointers are NULL or a valid pointer of the
- *     corresponding type.
- *
- * Returns:
- *     ISC_R_SUCCESS
- *     ISC_R_NOMEMORY
- *     ISC_R_NOTFOUND
- */
-
-isc_boolean_t
-dns_acache_cancelentry(dns_acacheentry_t *entry);
-/*
- * Cancel the use of the cache entry 'entry'.  This function is supposed to
- * be called when the node that holds the entry finds the content is not
- * correct any more.  This function will try to release as much dependency as
- * possible, and will be ready to be cleaned-up.  The registered callback
- * function will be canceled and will never called.
- *
- * Requires:
- *     'entry' is a valid additional cache entry.
- *
- * Returns:
- *     ISC_TRUE if the entry was active when canceled
- */
-
-void
-dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp);
-/*
- * Attach *targetp to the cache entry 'source'.
- *
- * Requires:
- *
- *     'source' is a valid additional cache entry.
- *
- *     'targetp' points to a NULL dns_acacheentry_t *.
- *
- * Ensures:
- *
- *     *targetp is attached to 'source'.
- */
-
-void
-dns_acache_detachentry(dns_acacheentry_t **entryp);
-/*
- * Detach *entryp from its cache.
- *
- * Requires:
- *
- *     '*entryp' points to a valid additional cache entry.
- *
- * Ensures:
- *
- *     *entryp is NULL.
- *
- *     If '*entryp' is the last reference to the entry,
- *     cache does not have an outstanding task, all resources used by the
- *     entry (including the entry object itself) will be freed.
- */
-
-void
-dns_acache_countquerymiss(dns_acache_t *acache);
-/*
- * Count up a missed acache query.  XXXMLG need more docs.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ACACHE_H */
index d72d7db5bcffb0a41839f3ba4b07d00cbbda2b80..adfb73121b5eb951390148115143adc7ee326e42 100644 (file)
@@ -13,6 +13,7 @@
 #include <isc/region.h>
 
 #include <dns/types.h>
+#include <dns/name.h>
 
 ISC_LANG_BEGINDECLS
 
@@ -37,19 +38,23 @@ ISC_LANG_BEGINDECLS
 #define DNS_COMPRESS_CASESENSITIVE     0x02    /*%< case sensitive compression. */
 #define DNS_COMPRESS_ENABLED           0x04
 
-#define DNS_COMPRESS_READY             0x80000000
-
-#define DNS_COMPRESS_TABLESIZE 64
+/*
+ * DNS_COMPRESS_TABLESIZE must be a power of 2. The compress code
+ * utilizes this assumption.
+ */
+#define DNS_COMPRESS_TABLEBITS 6
+#define DNS_COMPRESS_TABLESIZE (1U << DNS_COMPRESS_TABLEBITS)
+#define DNS_COMPRESS_TABLEMASK (DNS_COMPRESS_TABLESIZE - 1)
 #define DNS_COMPRESS_INITIALNODES 16
 
 typedef struct dns_compressnode dns_compressnode_t;
 
 struct dns_compressnode {
-       isc_region_t            r;
+       dns_compressnode_t      *next;
        isc_uint16_t            offset;
        isc_uint16_t            count;
-       isc_uint8_t             labels;
-       dns_compressnode_t      *next;
+       isc_region_t            r;
+       dns_name_t              name;
 };
 
 struct dns_compress {
index 118d59fc30b77a1db56d226fc040a6f8cf087dfa..223e83f4b6f660dd8f8489d47f68586d8ab6675a 100644 (file)
@@ -65,7 +65,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
 #define DNS_LOGMODULE_SDB              (&dns_modules[22])
 #define DNS_LOGMODULE_DIFF             (&dns_modules[23])
 #define DNS_LOGMODULE_HINTS            (&dns_modules[24])
-#define DNS_LOGMODULE_ACACHE           (&dns_modules[25])
+#define DNS_LOGMODULE_UNUSED1          (&dns_modules[25])
 #define DNS_LOGMODULE_DLZ              (&dns_modules[26])
 #define DNS_LOGMODULE_DNSSEC           (&dns_modules[27])
 #define DNS_LOGMODULE_CRYPTO           (&dns_modules[28])
index fa6ce450b498e30cc1ca35c3c5041369b6be82e6..abf72eb20c57f8a48ffe5a6ff1541d312f28bb01 100644 (file)
@@ -76,37 +76,18 @@ typedef struct dns_rdatasetmethods {
                                              dns_name_t *name,
                                              dns_rdataset_t *neg,
                                              dns_rdataset_t *negsig);
-       isc_result_t            (*getadditional)(dns_rdataset_t *rdataset,
-                                                dns_rdatasetadditional_t type,
-                                                dns_rdatatype_t qtype,
-                                                dns_acache_t *acache,
-                                                dns_zone_t **zonep,
-                                                dns_db_t **dbp,
-                                                dns_dbversion_t **versionp,
-                                                dns_dbnode_t **nodep,
-                                                dns_name_t *fname,
-                                                dns_message_t *msg,
-                                                isc_stdtime_t now);
-       isc_result_t            (*setadditional)(dns_rdataset_t *rdataset,
-                                                dns_rdatasetadditional_t type,
-                                                dns_rdatatype_t qtype,
-                                                dns_acache_t *acache,
-                                                dns_zone_t *zone,
-                                                dns_db_t *db,
-                                                dns_dbversion_t *version,
-                                                dns_dbnode_t *node,
-                                                dns_name_t *fname);
-       isc_result_t            (*putadditional)(dns_acache_t *acache,
-                                                dns_rdataset_t *rdataset,
-                                                dns_rdatasetadditional_t type,
-                                                dns_rdatatype_t qtype);
        void                    (*settrust)(dns_rdataset_t *rdataset,
                                            dns_trust_t trust);
        void                    (*expire)(dns_rdataset_t *rdataset);
        void                    (*clearprefetch)(dns_rdataset_t *rdataset);
        void                    (*setownercase)(dns_rdataset_t *rdataset,
                                                const dns_name_t *name);
-       void                    (*getownercase)(const dns_rdataset_t *rdataset,                                                 dns_name_t *name);
+       void                    (*getownercase)(const dns_rdataset_t *rdataset,
+                                               dns_name_t *name);
+       isc_result_t            (*addglue)(dns_rdataset_t *rdataset,
+                                          dns_dbversion_t *version,
+                                          unsigned int options,
+                                          dns_message_t *msg);
 } dns_rdatasetmethods_t;
 
 #define DNS_RDATASET_MAGIC            ISC_MAGIC('D','N','S','R')
@@ -176,6 +157,7 @@ struct dns_rdataset {
  *     Output the RRset in load order.
  */
 
+#define DNS_RDATASETATTR_NONE          0x00000000      /*%< No ordering. */
 #define DNS_RDATASETATTR_QUESTION      0x00000001
 #define DNS_RDATASETATTR_RENDERED      0x00000002      /*%< Used by message.c */
 #define DNS_RDATASETATTR_ANSWERED      0x00000004      /*%< Used by server. */
@@ -186,8 +168,8 @@ struct dns_rdataset {
 #define DNS_RDATASETATTR_NCACHE                0x00000080      /*%< Used by resolver. */
 #define DNS_RDATASETATTR_CHAINING      0x00000100      /*%< Used by resolver. */
 #define DNS_RDATASETATTR_TTLADJUSTED   0x00000200      /*%< Used by message.c */
-#define DNS_RDATASETATTR_FIXEDORDER    0x00000400
-#define DNS_RDATASETATTR_RANDOMIZE     0x00000800
+#define DNS_RDATASETATTR_FIXEDORDER    0x00000400      /*%< Fixed ordering. */
+#define DNS_RDATASETATTR_RANDOMIZE     0x00000800      /*%< Random ordering. */
 #define DNS_RDATASETATTR_CHASE         0x00001000      /*%< Used by resolver. */
 #define DNS_RDATASETATTR_NXDOMAIN      0x00002000
 #define DNS_RDATASETATTR_NOQNAME       0x00004000
@@ -200,6 +182,7 @@ struct dns_rdataset {
 #define DNS_RDATASETATTR_OPTOUT                0x00100000      /*%< OPTOUT proof */
 #define DNS_RDATASETATTR_NEGATIVE      0x00200000
 #define DNS_RDATASETATTR_PREFETCH      0x00400000
+#define DNS_RDATASETATTR_CYCLIC                0x00800000      /*%< Cyclic ordering. */
 
 /*%
  * _OMITDNSSEC:
@@ -207,6 +190,13 @@ struct dns_rdataset {
  */
 #define DNS_RDATASETTOWIRE_OMITDNSSEC  0x0001
 
+/*%
+ * _FILTERAAAA
+ *     If A records are present, omit AAAA records when adding
+ *     glue
+ */
+#define DNS_RDATASETADDGLUE_FILTERAAAA 0x0001
+
 void
 dns_rdataset_init(dns_rdataset_t *rdataset);
 /*%<
@@ -542,98 +532,6 @@ dns_rdataset_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name);
  *\li  'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets.
  */
 
-isc_result_t
-dns_rdataset_getadditional(dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype,
-                          dns_acache_t *acache,
-                          dns_zone_t **zonep,
-                          dns_db_t **dbp,
-                          dns_dbversion_t **versionp,
-                          dns_dbnode_t **nodep,
-                          dns_name_t *fname,
-                          dns_message_t *msg,
-                          isc_stdtime_t now);
-/*%<
- * Get cached additional information from the DB node for a particular
- * 'rdataset.'  'type' is one of dns_rdatasetadditional_fromauth,
- * dns_rdatasetadditional_fromcache, and dns_rdatasetadditional_fromglue,
- * which specifies the origin of the information.  'qtype' is intended to
- * be used for specifying a particular rdata type in the cached information.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- *     ISC_R_FAILURE.
- * \li For the other pointers, see dns_acache_getentry().
- *
- * Ensures:
- * \li See dns_acache_getentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE  - additional information caching is not supported.
- * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional
- *                       information for 'rdataset.'
- * \li Any error that dns_acache_getentry() can return.
- */
-
-isc_result_t
-dns_rdataset_setadditional(dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype,
-                          dns_acache_t *acache,
-                          dns_zone_t *zone,
-                          dns_db_t *db,
-                          dns_dbversion_t *version,
-                          dns_dbnode_t *node,
-                          dns_name_t *fname);
-/*%<
- * Set cached additional information to the DB node for a particular
- * 'rdataset.'  See dns_rdataset_getadditional for the semantics of 'type'
- * and 'qtype'.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- *     ISC_R_FAILURE.
- * \li For the other pointers, see dns_acache_setentry().
- *
- * Ensures:
- * \li See dns_acache_setentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE  - additional information caching is not supported.
- * \li #ISC_R_NOMEMORY
- * \li Any error that dns_acache_setentry() can return.
- */
-
-isc_result_t
-dns_rdataset_putadditional(dns_acache_t *acache,
-                          dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype);
-/*%<
- * Discard cached additional information stored in the DB node for a particular
- * 'rdataset.'  See dns_rdataset_getadditional for the semantics of 'type'
- * and 'qtype'.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- *     ISC_R_FAILURE.
- *
- * Ensures:
- * \li See dns_acache_cancelentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE  - additional information caching is not supported.
- * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional
- *                       information for 'rdataset.'
- */
-
 void
 dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
 /*%<
@@ -674,6 +572,32 @@ dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
  * according to it. If CASESET is not set, do nothing.
  */
 
+isc_result_t
+dns_rdataset_addglue(dns_rdataset_t *rdataset,
+                    dns_dbversion_t *version,
+                    unsigned int options,
+                    dns_message_t *msg);
+/*%<
+ * Add glue records for rdataset to the additional section of message in
+ * 'msg'. 'rdataset' must be of type NS. If DNS_RDATASETADDGLUE_FILTERAAAA
+ * is set in 'options' there is type A glue, type AAAA glue is not added.
+ *
+ * In case a successful result is not returned, the caller should try to
+ * add glue directly to the message by iterating for additional data.
+ *
+ * Requires:
+ * \li 'rdataset' is a valid NS rdataset.
+ * \li 'version' is the DB version.
+ * \li  'options' is options; currently only _FILTERAAAA is defined.
+ * \li 'msg' is the DNS message to which the glue should be added.
+ *
+ * Returns:
+ *\li  #ISC_R_SUCCESS
+ *\li  #ISC_R_NOTIMPLEMENTED
+ *\li  #ISC_R_FAILURE
+ *\li  Any error that dns_rdata_additionaldata() can return.
+ */
+
 void
 dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
                     dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
index 0e74817b9e36e132db9e438ffe44ca527004c2bc..3e79760c55037bbb3141d1a1ab61d30d04a5b0ce 100644 (file)
@@ -22,9 +22,6 @@
 
 #include <isc/types.h>
 
-typedef struct dns_acache                      dns_acache_t;
-typedef struct dns_acacheentry                 dns_acacheentry_t;
-typedef struct dns_acachestats                 dns_acachestats_t;
 typedef struct dns_acl                                 dns_acl_t;
 typedef struct dns_aclelement                  dns_aclelement_t;
 typedef struct dns_aclenv                      dns_aclenv_t;
index 2e45f9d214821b0d95087d1babe09868a087ceff..f08c3d853693ff008b572541f99e2f5456294cd9 100644 (file)
@@ -83,7 +83,6 @@ struct dns_view {
        dns_resolver_t *                resolver;
        dns_adb_t *                     adb;
        dns_requestmgr_t *              requestmgr;
-       dns_acache_t *                  acache;
        dns_cache_t *                   cache;
        dns_db_t *                      cachedb;
        dns_db_t *                      hints;
@@ -114,8 +113,6 @@ struct dns_view {
        dns_fwdtable_t *                fwdtable;
        isc_boolean_t                   recursion;
        isc_boolean_t                   auth_nxdomain;
-       isc_boolean_t                   additionalfromcache;
-       isc_boolean_t                   additionalfromauth;
        isc_boolean_t                   minimal_any;
        dns_minimaltype_t               minimalresponses;
        isc_boolean_t                   enablednssec;
index 7eb7c3e8d0e68c0b673a99a95c21488e3071898b..1bf291d49758a077ea9b7d50e991410d8adffc76 100644 (file)
@@ -2040,19 +2040,6 @@ dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
  *     DNS_R_BADNAME           failed rdata checks.
  */
 
-void
-dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache);
-/*%<
- *     Associate the zone with an additional cache.
- *
- * Require:
- *     'zone' to be a valid zone.
- *     'acache' to be a non NULL pointer.
- *
- * Ensures:
- *     'zone' will have a reference to 'acache'
- */
-
 void
 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx);
 /*%<
index 3030de012da4b2969db8e8cf51248a3ec5723abe..b3004d1c978d0f16845175858f249e495ff81c35 100644 (file)
@@ -71,7 +71,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
        { "dns/sdb",            0 },
        { "dns/diff",           0 },
        { "dns/hints",          0 },
-       { "dns/acache",         0 },
+       { "dns/unused1",        0 },
        { "dns/dlz",            0 },
        { "dns/dnssec",         0 },
        { "dns/crypto",         0 },
index f34b994b62e93f640bef644fbd76e2479f458ebf..f2bc44197c578699aef8f7ce257ca89c3132d816 100644 (file)
@@ -96,11 +96,11 @@ hexdump(const char *msg, const char *msg2, void *base, size_t len) {
  * XXXMLG These should come from a config setting.
  */
 #define SCRATCHPAD_SIZE                512
-#define NAME_COUNT               8
+#define NAME_COUNT              64
 #define OFFSET_COUNT             4
 #define RDATA_COUNT              8
 #define RDATALIST_COUNT                  8
-#define RDATASET_COUNT          RDATALIST_COUNT
+#define RDATASET_COUNT          64
 
 /*%
  * Text representation of the different items, for message_totext
@@ -742,6 +742,7 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
        result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
+       isc_mempool_setfillcount(m->namepool, NAME_COUNT);
        isc_mempool_setfreemax(m->namepool, NAME_COUNT);
        isc_mempool_setname(m->namepool, "msg:names");
 
@@ -749,7 +750,8 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
                                    &m->rdspool);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
-       isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
+       isc_mempool_setfillcount(m->rdspool, RDATASET_COUNT);
+       isc_mempool_setfreemax(m->rdspool, RDATASET_COUNT);
        isc_mempool_setname(m->rdspool, "msg:rdataset");
 
        dynbuf = NULL;
index f8c0dcb4e1bf4733c086d073e7a7c6de511ac11a..b5f62399d8119ad2890a6f6599a6f9509e91759e 100644 (file)
@@ -956,9 +956,9 @@ dns_name_getlabelsequence(const dns_name_t *source,
                          unsigned int first, unsigned int n,
                          dns_name_t *target)
 {
-       unsigned char *offsets;
-       dns_offsets_t odata;
+       unsigned char *p, l;
        unsigned int firstoffset, endoffset;
+       unsigned int i;
 
        /*
         * Make 'target' refer to the 'n' labels including and following
@@ -971,17 +971,26 @@ dns_name_getlabelsequence(const dns_name_t *source,
        REQUIRE(n <= source->labels - first); /* note first+n could overflow */
        REQUIRE(BINDABLE(target));
 
-       SETUP_OFFSETS(source, offsets, odata);
-
-       if (first == source->labels)
+       p = source->ndata;
+       if (ISC_UNLIKELY(first == source->labels)) {
                firstoffset = source->length;
-       else
-               firstoffset = offsets[first];
+       } else {
+               for (i = 0; i < first; i++) {
+                       l = *p;
+                       p += l + 1;
+               }
+               firstoffset = p - source->ndata;
+       }
 
-       if (first + n == source->labels)
+       if (ISC_LIKELY(first + n == source->labels))
                endoffset = source->length;
-       else
-               endoffset = offsets[first + n];
+       else {
+               for (i = 0; i < n; i++) {
+                       l = *p;
+                       p += l + 1;
+               }
+               endoffset = p - source->ndata;
+       }
 
        target->ndata = &source->ndata[firstoffset];
        target->length = endoffset - firstoffset;
@@ -1775,16 +1784,15 @@ set_offsets(const dns_name_t *name, unsigned char *offsets,
        offset = 0;
        nlabels = 0;
        absolute = ISC_FALSE;
-       while (offset != length) {
+       while (ISC_LIKELY(offset != length)) {
                INSIST(nlabels < 128);
                offsets[nlabels++] = offset;
-               count = *ndata++;
-               offset++;
+               count = *ndata;
                INSIST(count <= 63);
-               offset += count;
-               ndata += count;
+               offset += count + 1;
+               ndata += count + 1;
                INSIST(offset <= length);
-               if (count == 0) {
+               if (ISC_UNLIKELY(count == 0)) {
                        absolute = ISC_TRUE;
                        break;
                }
index e328778ad859c6eecfe6bbc4eda70cc2e9d07c28..24a123a482d39ee3d75a0bdf75d5b916aebb5e0a 100644 (file)
@@ -484,18 +484,16 @@ static dns_rdatasetmethods_t rdataset_methods = {
        rdataset_current,
        rdataset_clone,
        rdataset_count,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       rdataset_settrust,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL,                   /* addnoqname */
+       NULL,                   /* getnoqname */
+       NULL,                   /* addclosest */
+       NULL,                   /* getclosest */
+       rdataset_settrust,      /* settrust */
+       NULL,                   /* expire */
+       NULL,                   /* clearprefetch */
+       NULL,                   /* setownercase */
+       NULL,                   /* getownercase */
+       NULL                    /* addglue */
 };
 
 isc_result_t
index bda589e7ec913eaae251ee16461af12d767bba7f..0cdf2c855f108ccdbdb06450131f47850f6d19dc 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp $ */
-
 /*! \file */
 
 #include <config.h>
@@ -80,7 +78,7 @@ dns_order_add(dns_order_t *order, const dns_name_t *name,
        REQUIRE(DNS_ORDER_VALID(order));
        REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE ||
                mode == DNS_RDATASETATTR_FIXEDORDER ||
-               mode == 0 /* DNS_RDATASETATTR_CYCLIC */ );
+               mode == DNS_RDATASETATTR_CYCLIC);
 
        ent = isc_mem_get(order->mctx, sizeof(*ent));
        if (ent == NULL)
@@ -123,7 +121,7 @@ dns_order_find(dns_order_t *order, const dns_name_t *name,
                if (match(name, dns_fixedname_name(&ent->name)))
                        return (ent->mode);
        }
-       return (DNS_RDATASETATTR_RANDOMIZE);
+       return (DNS_RDATASETATTR_NONE);
 }
 
 void
index f17a12a3540895056f58ae6259844f262f5c6b4b..42ae89a36707ab06fc9930824bfb7529012bf87b 100644 (file)
@@ -40,8 +40,8 @@
 #include <isc/task.h>
 #include <isc/time.h>
 #include <isc/util.h>
+#include <isc/hash.h>
 
-#include <dns/acache.h>
 #include <dns/callbacks.h>
 #include <dns/db.h>
 #include <dns/dbiterator.h>
@@ -143,8 +143,6 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define slab_methods slab_methods64
 #define zone_methods zone_methods64
 
-#define acache_callback acache_callback64
-#define acache_cancelentry acache_cancelentry64
 #define activeempty activeempty64
 #define activeemtpynode activeemtpynode64
 #define add32 add64
@@ -195,7 +193,8 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define findnodeintree findnodeintree64
 #define findnsec3node findnsec3node64
 #define flush_deletions flush_deletions64
-#define free_acachearray free_acachearray64
+#define free_gluelist free_gluelist64
+#define free_gluetable free_gluetable64
 #define free_noqname free_noqname64
 #define free_rbtdb free_rbtdb64
 #define free_rbtdb_callback free_rbtdb_callback64
@@ -205,6 +204,7 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define getoriginnode getoriginnode64
 #define getrrsetstats getrrsetstats64
 #define getsigningtime getsigningtime64
+#define glue_nsdname_cb glue_nsdname_cb64
 #define hashsize hashsize64
 #define init_file_version init_file_version64
 #define isdnssec isdnssec64
@@ -225,6 +225,7 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define prune_tree prune_tree64
 #define rbt_datafixer rbt_datafixer64
 #define rbt_datawriter rbt_datawriter64
+#define rdataset_addglue rdataset_addglue64
 #define rdataset_clearprefetch rdataset_clearprefetch64
 #define rdataset_clone rdataset_clone64
 #define rdataset_count rdataset_count64
@@ -232,13 +233,10 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define rdataset_disassociate rdataset_disassociate64
 #define rdataset_expire rdataset_expire64
 #define rdataset_first rdataset_first64
-#define rdataset_getadditional rdataset_getadditional64
 #define rdataset_getclosest rdataset_getclosest64
 #define rdataset_getnoqname rdataset_getnoqname64
 #define rdataset_getownercase rdataset_getownercase64
 #define rdataset_next rdataset_next64
-#define rdataset_putadditional rdataset_putadditional64
-#define rdataset_setadditional rdataset_setadditional64
 #define rdataset_setownercase rdataset_setownercase64
 #define rdataset_settrust rdataset_settrust64
 #define rdatasetiter_current rdatasetiter_current64
@@ -391,8 +389,6 @@ struct noqname {
        dns_rdatatype_t type;
 };
 
-typedef struct acachectl acachectl_t;
-
 typedef struct rdatasetheader {
        /*%
         * Locked by the owning node's lock.
@@ -436,9 +432,6 @@ typedef struct rdatasetheader {
         * performance reasons.
         */
 
-       acachectl_t                     *additional_auth;
-       acachectl_t                     *additional_glue;
-
        dns_rbtnode_t                   *node;
        isc_stdtime_t                   last_used;
        ISC_LINK(struct rdatasetheader) link;
@@ -471,19 +464,7 @@ typedef ISC_LIST(dns_rbtnode_t)         rbtnodelist_t;
 #define RDATASET_ATTR_PREFETCH          0x0200
 #define RDATASET_ATTR_CASESET           0x0400
 #define RDATASET_ATTR_ZEROTTL           0x0800
-
-typedef struct acache_cbarg {
-       dns_rdatasetadditional_t        type;
-       unsigned int                    count;
-       dns_db_t                        *db;
-       dns_dbnode_t                    *node;
-       rdatasetheader_t                *header;
-} acache_cbarg_t;
-
-struct acachectl {
-       dns_acacheentry_t               *entry;
-       acache_cbarg_t                  *cbarg;
-};
+#define RDATASET_ATTR_CASEFULLYLOWER    0x1000
 
 /*
  * XXX
@@ -519,12 +500,15 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_CASESET) != 0)
 #define ZEROTTL(header) \
        (((header)->attributes & RDATASET_ATTR_ZEROTTL) != 0)
+#define CASEFULLYLOWER(header) \
+       (((header)->attributes & RDATASET_ATTR_CASEFULLYLOWER) != 0)
 
 #define ACTIVE(header, now) \
        (((header)->rdh_ttl > (now)) || \
         ((header)->rdh_ttl == (now) && ZEROTTL(header)))
 
 #define DEFAULT_NODE_LOCK_COUNT         7       /*%< Should be prime. */
+#define RBTDB_GLUE_TABLE_INIT_SIZE     2U
 
 /*%
  * Number of buckets for cache DB entries (locks, LRU lists, TTL heaps).
@@ -577,6 +561,14 @@ typedef enum {
        expire_flush
 } expire_t;
 
+typedef struct rbtdb_glue rbtdb_glue_t;
+
+typedef struct rbtdb_glue_table_node {
+       struct rbtdb_glue_table_node *next;
+       dns_rbtnode_t                *node;
+       rbtdb_glue_t                 *glue_list;
+} rbtdb_glue_table_node_t;
+
 typedef struct rbtdb_version {
        /* Not locked */
        rbtdb_serial_t                  serial;
@@ -608,6 +600,11 @@ typedef struct rbtdb_version {
        isc_rwlock_t                    rwlock;
        isc_uint64_t                    records;
        isc_uint64_t                    bytes;
+
+       isc_rwlock_t                    glue_rwlock;
+       size_t                          glue_table_size;
+       size_t                          glue_table_nodecount;
+       rbtdb_glue_table_node_t         **glue_table;
 } rbtdb_version_t;
 
 typedef ISC_LIST(rbtdb_version_t)       rbtdb_versionlist_t;
@@ -725,30 +722,6 @@ static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset,
                                        dns_name_t *name,
                                        dns_rdataset_t *neg,
                                        dns_rdataset_t *negsig);
-static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset,
-                                          dns_rdatasetadditional_t type,
-                                          dns_rdatatype_t qtype,
-                                          dns_acache_t *acache,
-                                          dns_zone_t **zonep,
-                                          dns_db_t **dbp,
-                                          dns_dbversion_t **versionp,
-                                          dns_dbnode_t **nodep,
-                                          dns_name_t *fname,
-                                          dns_message_t *msg,
-                                          isc_stdtime_t now);
-static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset,
-                                          dns_rdatasetadditional_t type,
-                                          dns_rdatatype_t qtype,
-                                          dns_acache_t *acache,
-                                          dns_zone_t *zone,
-                                          dns_db_t *db,
-                                          dns_dbversion_t *version,
-                                          dns_dbnode_t *node,
-                                          dns_name_t *fname);
-static isc_result_t rdataset_putadditional(dns_acache_t *acache,
-                                          dns_rdataset_t *rdataset,
-                                          dns_rdatasetadditional_t type,
-                                          dns_rdatatype_t qtype);
 static inline isc_boolean_t need_headerupdate(rdatasetheader_t *header,
                                              isc_stdtime_t now);
 static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
@@ -769,6 +742,11 @@ static void rdataset_setownercase(dns_rdataset_t *rdataset,
                                  const dns_name_t *name);
 static void rdataset_getownercase(const dns_rdataset_t *rdataset,
                                  dns_name_t *name);
+static isc_result_t rdataset_addglue(dns_rdataset_t *rdataset,
+                                    dns_dbversion_t *version,
+                                    unsigned int options,
+                                    dns_message_t *msg);
+static void free_gluetable(rbtdb_version_t *version);
 
 static dns_rdatasetmethods_t rdataset_methods = {
        rdataset_disassociate,
@@ -777,18 +755,16 @@ static dns_rdatasetmethods_t rdataset_methods = {
        rdataset_current,
        rdataset_clone,
        rdataset_count,
-       NULL,
+       NULL, /* addnoqname */
        rdataset_getnoqname,
-       NULL,
+       NULL, /* addclosest */
        rdataset_getclosest,
-       rdataset_getadditional,
-       rdataset_setadditional,
-       rdataset_putadditional,
        rdataset_settrust,
        rdataset_expire,
        rdataset_clearprefetch,
        rdataset_setownercase,
-       rdataset_getownercase
+       rdataset_getownercase,
+       rdataset_addglue
 };
 
 static dns_rdatasetmethods_t slab_methods = {
@@ -798,18 +774,16 @@ static dns_rdatasetmethods_t slab_methods = {
        rdataset_current,
        rdataset_clone,
        rdataset_count,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL, /* addnoqname */
+       NULL, /* getnoqname */
+       NULL, /* addclosest */
+       NULL, /* getclosest */
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
+       NULL, /* setownercase */
+       NULL, /* getownercase */
+       NULL  /* addglue */
 };
 
 static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
@@ -1172,6 +1146,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
                                       &refs);
                INSIST(refs == 0);
                UNLINK(rbtdb->open_versions, rbtdb->current_version, link);
+               isc_rwlock_destroy(&rbtdb->current_version->glue_rwlock);
                isc_refcount_destroy(&rbtdb->current_version->references);
                isc_rwlock_destroy(&rbtdb->current_version->rwlock);
                isc_mem_put(rbtdb->common.mctx, rbtdb->current_version,
@@ -1331,6 +1306,15 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
        if (rbtdb->nsnode != NULL)
                dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode);
 
+       /*
+        * The current version's glue table needs to be freed early
+        * so the nodes are dereferenced before we check the active
+        * node count below.
+        */
+       if (rbtdb->current_version != NULL) {
+               free_gluetable(rbtdb->current_version);
+       }
+
        /*
         * Even though there are no external direct references, there still
         * may be nodes in use.
@@ -1339,8 +1323,8 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
                NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
                rbtdb->node_locks[i].exiting = ISC_TRUE;
                NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
-               if (isc_refcount_current(&rbtdb->node_locks[i].references)
-                   == 0) {
+               if (isc_refcount_current(&rbtdb->node_locks[i].references) == 0)
+               {
                        inactive++;
                }
        }
@@ -1348,16 +1332,18 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
        if (inactive != 0) {
                RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
                rbtdb->active -= inactive;
-               if (rbtdb->active == 0)
+               if (rbtdb->active == 0) {
                        want_free = ISC_TRUE;
+               }
                RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
                if (want_free) {
                        char buf[DNS_NAME_FORMATSIZE];
-                       if (dns_name_dynamic(&rbtdb->common.origin))
+                       if (dns_name_dynamic(&rbtdb->common.origin)) {
                                dns_name_format(&rbtdb->common.origin, buf,
                                                sizeof(buf));
-                       else
+                       } else {
                                strcpy(buf, "<UNKNOWN>");
+                       }
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
                                      DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
                                      "calling free_rbtdb(%s)", buf);
@@ -1403,6 +1389,7 @@ allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial,
 {
        isc_result_t result;
        rbtdb_version_t *version;
+       size_t i;
 
        version = isc_mem_get(mctx, sizeof(*version));
        if (version == NULL)
@@ -1413,12 +1400,34 @@ allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial,
                isc_mem_put(mctx, version, sizeof(*version));
                return (NULL);
        }
+       result = isc_rwlock_init(&version->glue_rwlock, 0, 0);
+       if (result != ISC_R_SUCCESS) {
+               isc_refcount_destroy(&version->references);
+               isc_mem_put(mctx, version, sizeof(*version));
+               return (NULL);
+       }
+
+       version->glue_table_size = RBTDB_GLUE_TABLE_INIT_SIZE;
+       version->glue_table_nodecount = 0U;
+       version->glue_table = (rbtdb_glue_table_node_t **)
+               isc_mem_get(mctx, (version->glue_table_size *
+                                  sizeof(*version->glue_table)));
+       if (version->glue_table == NULL) {
+               isc_rwlock_destroy(&version->glue_rwlock);
+               isc_refcount_destroy(&version->references);
+               isc_mem_put(mctx, version, sizeof(*version));
+               return (NULL);
+       }
+
        version->writer = writer;
        version->commit_ok = ISC_FALSE;
        ISC_LIST_INIT(version->changed_list);
        ISC_LIST_INIT(version->resigned_list);
        ISC_LINK_INIT(version, link);
 
+       for (i = 0; i < version->glue_table_size; i++)
+               version->glue_table[i] = NULL;
+
        return (version);
 }
 
@@ -1459,6 +1468,8 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
                }
                result = isc_rwlock_init(&version->rwlock, 0, 0);
                if (result != ISC_R_SUCCESS) {
+                       free_gluetable(version);
+                       isc_rwlock_destroy(&version->glue_rwlock);
                        isc_refcount_destroy(&version->references);
                        isc_mem_put(rbtdb->common.mctx, version,
                                    sizeof(*version));
@@ -1534,35 +1545,6 @@ add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
        return (changed);
 }
 
-static void
-free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header,
-                acachectl_t *array)
-{
-       unsigned int count;
-       unsigned int i;
-       unsigned char *raw;     /* RDATASLAB */
-
-       /*
-        * The caller must be holding the corresponding node lock.
-        */
-
-       if (array == NULL)
-               return;
-
-       raw = (unsigned char *)header + sizeof(*header);
-       count = raw[0] * 256 + raw[1];
-
-       /*
-        * Sanity check: since an additional cache entry has a reference to
-        * the original DB node (in the callback arg), there should be no
-        * acache entries when the node can be freed.
-        */
-       for (i = 0; i < count; i++)
-               INSIST(array[i].entry == NULL && array[i].cbarg == NULL);
-
-       isc_mem_put(mctx, array, count * sizeof(acachectl_t));
-}
-
 static inline void
 free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
 
@@ -1612,8 +1594,12 @@ update_newheader(rdatasetheader_t *new, rdatasetheader_t *old) {
                new->node = (dns_rbtnode_t *)p;
        }
        if (CASESET(old)) {
+               uint16_t attr;
+
                memmove(new->upper, old->upper, sizeof(old->upper));
-               new->attributes |= RDATASET_ATTR_CASESET;
+               attr = old->attributes & (RDATASET_ATTR_CASESET |
+                                         RDATASET_ATTR_CASEFULLYLOWER);
+               new->attributes |= attr;
        }
 }
 
@@ -1660,9 +1646,6 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) {
        if (rdataset->closest != NULL)
                free_noqname(mctx, &rdataset->closest);
 
-       free_acachearray(mctx, rdataset, rdataset->additional_auth);
-       free_acachearray(mctx, rdataset, rdataset->additional_glue);
-
        if (NONEXISTENT(rdataset))
                size = sizeof(*rdataset);
        else
@@ -2754,6 +2737,8 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
 
        if (cleanup_version != NULL) {
                INSIST(EMPTY(cleanup_version->changed_list));
+               free_gluetable(cleanup_version);
+               isc_rwlock_destroy(&cleanup_version->glue_rwlock);
                isc_rwlock_destroy(&cleanup_version->rwlock);
                isc_mem_put(rbtdb->common.mctx, cleanup_version,
                            sizeof(*cleanup_version));
@@ -2780,7 +2765,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
                                              DNS_LOGCATEGORY_DATABASE,
                                              DNS_LOGMODULE_ZONE, ISC_LOG_ERROR,
                                              "Unable to reinsert header to "
-                                             "re-signing heap: %s\n",
+                                             "re-signing heap: %s",
                                dns_result_totext(result));
                }
                decrement_reference(rbtdb, header->node, least_serial,
@@ -6610,8 +6595,6 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
        newheader->closest = NULL;
        newheader->count = init_count++;
        newheader->trust = rdataset->trust;
-       newheader->additional_auth = NULL;
-       newheader->additional_glue = NULL;
        newheader->last_used = now;
        newheader->node = rbtnode;
        if (rbtversion != NULL) {
@@ -6798,8 +6781,6 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
        newheader->noqname = NULL;
        newheader->closest = NULL;
        newheader->count = init_count++;
-       newheader->additional_auth = NULL;
-       newheader->additional_glue = NULL;
        newheader->last_used = 0;
        newheader->node = rbtnode;
        if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
@@ -6873,8 +6854,6 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                         * to additional info.  We need to clear these fields
                         * to avoid having duplicated references.
                         */
-                       newheader->additional_auth = NULL;
-                       newheader->additional_glue = NULL;
                        rbtversion->records +=
                                dns_rdataslab_count((unsigned char *)newheader,
                                                    sizeof(*newheader));
@@ -6901,8 +6880,6 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                        newheader->noqname = NULL;
                        newheader->closest = NULL;
                        newheader->count = 0;
-                       newheader->additional_auth = NULL;
-                       newheader->additional_glue = NULL;
                        newheader->node = rbtnode;
                        newheader->resign = 0;
                        newheader->resign_lsb = 0;
@@ -6994,8 +6971,6 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
        newheader->trust = 0;
        newheader->noqname = NULL;
        newheader->closest = NULL;
-       newheader->additional_auth = NULL;
-       newheader->additional_glue = NULL;
        if (rbtversion != NULL)
                newheader->serial = rbtversion->serial;
        else
@@ -7192,8 +7167,6 @@ loading_addrdataset(void *arg, const dns_name_t *name,
        newheader->noqname = NULL;
        newheader->closest = NULL;
        newheader->count = init_count++;
-       newheader->additional_auth = NULL;
-       newheader->additional_glue = NULL;
        newheader->last_used = 0;
        newheader->node = node;
        setownercase(newheader, name);
@@ -8429,6 +8402,8 @@ dns_rbtdb_create
               sizeof(rbtdb->current_version->salt));
        result = isc_rwlock_init(&rbtdb->current_version->rwlock, 0, 0);
        if (result != ISC_R_SUCCESS) {
+               free_gluetable(rbtdb->current_version);
+               isc_rwlock_destroy(&rbtdb->current_version->glue_rwlock);
                isc_refcount_destroy(&rbtdb->current_version->references);
                isc_mem_put(mctx, rbtdb->current_version,
                            sizeof(*rbtdb->current_version));
@@ -9450,404 +9425,716 @@ dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
        return (dns_name_copy(origin, name, NULL));
 }
 
-/*%
- * Additional cache routines.
- */
-static isc_result_t
-rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
-                      dns_rdatatype_t qtype, dns_acache_t *acache,
-                      dns_zone_t **zonep, dns_db_t **dbp,
-                      dns_dbversion_t **versionp, dns_dbnode_t **nodep,
-                      dns_name_t *fname, dns_message_t *msg,
-                      isc_stdtime_t now)
-{
-       dns_rbtdb_t *rbtdb = rdataset->private1;
-       dns_rbtnode_t *rbtnode = rdataset->private2;
+static void
+setownercase(rdatasetheader_t *header, const dns_name_t *name) {
+       unsigned int i;
+       isc_boolean_t fully_lower;
+
+       /*
+        * We do not need to worry about label lengths as they are all
+        * less than or equal to 63.
+        */
+       memset(header->upper, 0, sizeof(header->upper));
+       fully_lower = ISC_TRUE;
+       for (i = 0; i < name->length; i++)
+               if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) {
+                       header->upper[i/8] |= 1 << (i%8);
+                       fully_lower = ISC_FALSE;
+               }
+       header->attributes |= RDATASET_ATTR_CASESET;
+       if (ISC_LIKELY(fully_lower))
+               header->attributes |= RDATASET_ATTR_CASEFULLYLOWER;
+}
+
+static void
+rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
        unsigned char *raw = rdataset->private3;        /* RDATASLAB */
-       unsigned int current_count = rdataset->privateuint4;
-       unsigned int count;
        rdatasetheader_t *header;
-       nodelock_t *nodelock;
-       unsigned int total_count;
-       acachectl_t *acarray;
-       dns_acacheentry_t *entry;
-       isc_result_t result;
-
-       UNUSED(qtype); /* we do not use this value at least for now */
-       UNUSED(acache);
 
        header = (struct rdatasetheader *)(raw - sizeof(*header));
+       setownercase(header, name);
+}
+
+static const unsigned char charmask[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
 
-       total_count = raw[0] * 256 + raw[1];
-       INSIST(total_count > current_count);
-       count = total_count - current_count - 1;
+static unsigned char maptolower[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+       0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+       0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+       0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+       0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+       0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+       0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+       0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+       0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+       0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+       0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+       0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+       0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+       0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+       0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+       0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
 
-       acarray = NULL;
+static void
+rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
+       const unsigned char *raw = rdataset->private3;        /* RDATASLAB */
+       const rdatasetheader_t *header;
+       unsigned int i, j;
+       unsigned char bits;
+       unsigned char c, flip;
 
-       nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
-       NODE_LOCK(nodelock, isc_rwlocktype_read);
+       header = (const struct rdatasetheader *)(raw - sizeof(*header));
 
-       switch (type) {
-       case dns_rdatasetadditional_fromauth:
-               acarray = header->additional_auth;
-               break;
-       case dns_rdatasetadditional_fromcache:
-               acarray = NULL;
-               break;
-       case dns_rdatasetadditional_fromglue:
-               acarray = header->additional_glue;
-               break;
-       default:
-               INSIST(0);
-       }
+       if (!CASESET(header))
+               return;
 
-       if (acarray == NULL) {
-               if (type != dns_rdatasetadditional_fromcache)
-                       dns_acache_countquerymiss(acache);
-               NODE_UNLOCK(nodelock, isc_rwlocktype_read);
-               return (ISC_R_NOTFOUND);
+#if 0
+       /*
+        * This was the original code, and is implemented differently in
+        * the #else block that follows.
+        */
+       for (i = 0; i < name->length; i++) {
+               /*
+                * Set the case bit if it does not match the recorded bit.
+                */
+               if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
+                   (header->upper[i/8] & (1 << (i%8))) != 0)
+                       name->ndata[i] &= ~0x20; /* clear the lower case bit */
+               else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
+                        (header->upper[i/8] & (1 << (i%8))) == 0)
+                       name->ndata[i] |= 0x20; /* set the lower case bit */
        }
+#else
 
-       if (acarray[count].entry == NULL) {
-               dns_acache_countquerymiss(acache);
-               NODE_UNLOCK(nodelock, isc_rwlocktype_read);
-               return (ISC_R_NOTFOUND);
+       if (ISC_LIKELY(CASEFULLYLOWER(header))) {
+               unsigned char *bp, *be;
+               bp = name->ndata;
+               be = bp + name->length;
+
+               while (bp <= be - 4) {
+                       c = bp[0];
+                       bp[0] = maptolower[c];
+                       c = bp[1];
+                       bp[1] = maptolower[c];
+                       c = bp[2];
+                       bp[2] = maptolower[c];
+                       c = bp[3];
+                       bp[3] = maptolower[c];
+                       bp += 4;
+               }
+               while (bp < be) {
+                       c = *bp;
+                       *bp++ = maptolower[c];
+               }
+               return;
        }
 
-       entry = NULL;
-       dns_acache_attachentry(acarray[count].entry, &entry);
+       i = 0;
+       for (j = 0; j < (name->length >> 3); j++) {
+               unsigned int k;
 
-       NODE_UNLOCK(nodelock, isc_rwlocktype_read);
+               bits = ~(header->upper[j]);
 
-       result = dns_acache_getentry(entry, zonep, dbp, versionp,
-                                    nodep, fname, msg, now);
+               for (k = 0; k < 8; k++) {
+                       c = name->ndata[i];
+                       flip = (bits & 1) << 5;
+                       flip ^= c;
+                       flip &= charmask[c];
+                       name->ndata[i] ^= flip;
 
-       dns_acache_detachentry(&entry);
+                       i++;
+                       bits >>= 1;
+               }
+       }
 
-       return (result);
-}
+       if (ISC_UNLIKELY(i == name->length))
+               return;
 
-static void
-acache_callback(dns_acacheentry_t *entry, void **arg) {
-       dns_rbtdb_t *rbtdb;
-       dns_rbtnode_t *rbtnode;
-       nodelock_t *nodelock;
-       acachectl_t *acarray = NULL;
-       acache_cbarg_t *cbarg;
-       unsigned int count;
+       bits = ~(header->upper[j]);
 
-       REQUIRE(arg != NULL);
-       cbarg = *arg;
+       for (; i < name->length; i++) {
+               c = name->ndata[i];
+               flip = (bits & 1) << 5;
+               flip ^= c;
+               flip &= charmask[c];
+               name->ndata[i] ^= flip;
 
-       /*
-        * The caller must hold the entry lock.
-        */
+               bits >>= 1;
+       }
+#endif
+}
 
-       rbtdb = (dns_rbtdb_t *)cbarg->db;
-       rbtnode = (dns_rbtnode_t *)cbarg->node;
+struct rbtdb_glue {
+       struct rbtdb_glue *next;
+       dns_fixedname_t fixedname;
+       dns_rdataset_t rdataset_a;
+       dns_rdataset_t sigrdataset_a;
+       dns_rdataset_t rdataset_aaaa;
+       dns_rdataset_t sigrdataset_aaaa;
+};
 
-       nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
-       NODE_LOCK(nodelock, isc_rwlocktype_write);
+typedef struct {
+       rbtdb_glue_t *glue_list;
+       dns_rbtdb_t *rbtdb;
+       rbtdb_version_t *rbtversion;
+} rbtdb_glue_additionaldata_ctx_t;
 
-       switch (cbarg->type) {
-       case dns_rdatasetadditional_fromauth:
-               acarray = cbarg->header->additional_auth;
-               break;
-       case dns_rdatasetadditional_fromglue:
-               acarray = cbarg->header->additional_glue;
-               break;
-       default:
-               INSIST(0);
-       }
+static void
+free_gluelist(rbtdb_glue_t *glue_list, dns_rbtdb_t *rbtdb) {
+       rbtdb_glue_t *cur, *cur_next;
 
-       count = cbarg->count;
-       if (acarray != NULL && acarray[count].entry == entry) {
-               acarray[count].entry = NULL;
-               INSIST(acarray[count].cbarg == cbarg);
-               acarray[count].cbarg = NULL;
-               isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t));
-               dns_acache_detachentry(&entry);
-       }
+       if (glue_list == (void *) -1)
+               return;
+
+       cur = glue_list;
+       while (cur != NULL) {
+               cur_next = cur->next;
+
+               if (dns_rdataset_isassociated(&cur->rdataset_a))
+                       dns_rdataset_disassociate(&cur->rdataset_a);
+               if (dns_rdataset_isassociated(&cur->sigrdataset_a))
+                       dns_rdataset_disassociate(&cur->sigrdataset_a);
 
-       NODE_UNLOCK(nodelock, isc_rwlocktype_write);
+               if (dns_rdataset_isassociated(&cur->rdataset_aaaa))
+                       dns_rdataset_disassociate(&cur->rdataset_aaaa);
+               if (dns_rdataset_isassociated(&cur->sigrdataset_aaaa))
+                       dns_rdataset_disassociate(&cur->sigrdataset_aaaa);
 
-       dns_db_detachnode((dns_db_t *)rbtdb, (dns_dbnode_t **)(void*)&rbtnode);
-       dns_db_detach((dns_db_t **)(void*)&rbtdb);
+               dns_rdataset_invalidate(&cur->rdataset_a);
+               dns_rdataset_invalidate(&cur->sigrdataset_a);
+               dns_rdataset_invalidate(&cur->rdataset_aaaa);
+               dns_rdataset_invalidate(&cur->sigrdataset_aaaa);
 
-       *arg = NULL;
+               isc_mem_put(rbtdb->common.mctx, cur, sizeof(*cur));
+               cur = cur_next;
+       }
 }
 
 static void
-acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
-                     acache_cbarg_t **cbargp)
-{
-       acache_cbarg_t *cbarg;
+free_gluetable(rbtdb_version_t *version) {
+       dns_rbtdb_t *rbtdb;
+       size_t i;
+
+       RWLOCK(&version->glue_rwlock, isc_rwlocktype_write);
 
-       REQUIRE(mctx != NULL);
-       REQUIRE(entry != NULL);
-       REQUIRE(cbargp != NULL && *cbargp != NULL);
+       rbtdb = version->rbtdb;
 
-       cbarg = *cbargp;
+       for (i = 0; i < version->glue_table_size; i++) {
+               rbtdb_glue_table_node_t *cur, *cur_next;
 
-       if (dns_acache_cancelentry(entry)) {
-               dns_db_detachnode(cbarg->db, &cbarg->node);
-               dns_db_detach(&cbarg->db);
+               cur = version->glue_table[i];
+               while (cur != NULL) {
+                       cur_next = cur->next;
+                       /* dns_rbtnode_refdecrement(cur->node, NULL); */
+                       cur->node = NULL;
+                       free_gluelist(cur->glue_list, rbtdb);
+                       cur->glue_list = NULL;
+                       isc_mem_put(rbtdb->common.mctx, cur, sizeof(*cur));
+                       cur = cur_next;
+               }
+               version->glue_table[i] = NULL;
        }
 
-       isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t));
+       isc_mem_put(rbtdb->common.mctx, version->glue_table,
+                   (sizeof(*version->glue_table) *
+                    version->glue_table_size));
 
-       *cbargp = NULL;
+       RWUNLOCK(&version->glue_rwlock, isc_rwlocktype_write);
 }
 
-static isc_result_t
-rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
-                      dns_rdatatype_t qtype, dns_acache_t *acache,
-                      dns_zone_t *zone, dns_db_t *db,
-                      dns_dbversion_t *version, dns_dbnode_t *node,
-                      dns_name_t *fname)
-{
-       dns_rbtdb_t *rbtdb = rdataset->private1;
-       dns_rbtnode_t *rbtnode = rdataset->private2;
-       unsigned char *raw = rdataset->private3;        /* RDATASLAB */
-       unsigned int current_count = rdataset->privateuint4;
-       rdatasetheader_t *header;
-       unsigned int total_count, count;
-       nodelock_t *nodelock;
-       isc_result_t result;
-       acachectl_t *acarray;
-       dns_acacheentry_t *newentry, *oldentry = NULL;
-       acache_cbarg_t *newcbarg, *oldcbarg = NULL;
+static isc_boolean_t
+rehash_gluetable(rbtdb_version_t *version) {
+       size_t oldsize;
+       rbtdb_glue_table_node_t **oldtable;
+       rbtdb_glue_table_node_t *gluenode;
+       rbtdb_glue_table_node_t *nextgluenode;
+       uint32_t hash;
+       size_t i;
+
+       if (ISC_LIKELY(version->glue_table_nodecount <
+                      (version->glue_table_size * 3U)))
+               return (ISC_FALSE);
 
-       UNUSED(qtype);
+       oldsize = version->glue_table_size;
+       oldtable = version->glue_table;
+       do {
+               INSIST((version->glue_table_size * 2 + 1) >
+                      version->glue_table_size);
+               version->glue_table_size = version->glue_table_size * 2 + 1;
+       } while (version->glue_table_nodecount >=
+                (version->glue_table_size * 3U));
+
+       version->glue_table = (rbtdb_glue_table_node_t **)
+               isc_mem_get(version->rbtdb->common.mctx,
+                           (version->glue_table_size *
+                            sizeof(*version->glue_table)));
+       if (ISC_UNLIKELY(version->glue_table == NULL)) {
+               version->glue_table = oldtable;
+               version->glue_table_size = oldsize;
+               return (ISC_FALSE);
+       }
 
-       if (type == dns_rdatasetadditional_fromcache)
-               return (ISC_R_SUCCESS);
+       for (i = 0; i < version->glue_table_size; i++)
+               version->glue_table[i] = NULL;
 
-       header = (struct rdatasetheader *)(raw - sizeof(*header));
+       for (i = 0; i < oldsize; i++) {
+               for (gluenode = oldtable[i];
+                    gluenode != NULL;
+                    gluenode = nextgluenode)
+               {
+                       hash = isc_hash_function(&gluenode->node,
+                                                sizeof(gluenode->node),
+                                                ISC_TRUE, NULL) %
+                               version->glue_table_size;
+                       nextgluenode = gluenode->next;
+                       gluenode->next = version->glue_table[hash];
+                       version->glue_table[hash] = gluenode;
+               }
+       }
 
-       total_count = raw[0] * 256 + raw[1];
-       INSIST(total_count > current_count);
-       count = total_count - current_count - 1; /* should be private data */
+       isc_mem_put(version->rbtdb->common.mctx, oldtable,
+                   oldsize * sizeof(*version->glue_table));
 
-       newcbarg = isc_mem_get(rbtdb->common.mctx, sizeof(*newcbarg));
-       if (newcbarg == NULL)
-               return (ISC_R_NOMEMORY);
-       newcbarg->type = type;
-       newcbarg->count = count;
-       newcbarg->header = header;
-       newcbarg->db = NULL;
-       dns_db_attach((dns_db_t *)rbtdb, &newcbarg->db);
-       newcbarg->node = NULL;
-       dns_db_attachnode((dns_db_t *)rbtdb, (dns_dbnode_t *)rbtnode,
-                         &newcbarg->node);
-       newentry = NULL;
-       result = dns_acache_createentry(acache, (dns_db_t *)rbtdb,
-                                       acache_callback, newcbarg, &newentry);
-       if (result != ISC_R_SUCCESS)
-               goto fail;
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                     DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
+                     "rehash_gluetable(): "
+                     "resized glue table from %"ISC_PRINT_QUADFORMAT"u to "
+                     "%"ISC_PRINT_QUADFORMAT"u",
+                     (isc_uint64_t) oldsize,
+                     (isc_uint64_t) version->glue_table_size);
 
-       /* Set cache data in the new entry. */
-       result = dns_acache_setentry(acache, newentry, zone, db,
-                                    version, node, fname);
-       if (result != ISC_R_SUCCESS)
-               goto fail;
+       return (ISC_TRUE);
+}
 
-       nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
-       NODE_LOCK(nodelock, isc_rwlocktype_write);
+static isc_result_t
+glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
+       rbtdb_glue_additionaldata_ctx_t *ctx;
+       isc_result_t result;
+       dns_fixedname_t fixedname_a;
+       dns_name_t *name_a;
+       dns_rdataset_t rdataset_a, sigrdataset_a;
+       dns_rbtnode_t *node_a;
+       dns_fixedname_t fixedname_aaaa;
+       dns_name_t *name_aaaa;
+       dns_rdataset_t rdataset_aaaa, sigrdataset_aaaa;
+       dns_rbtnode_t *node_aaaa;
+       rbtdb_glue_t *glue;
+       dns_name_t *gluename;
 
-       acarray = NULL;
-       switch (type) {
-       case dns_rdatasetadditional_fromauth:
-               acarray = header->additional_auth;
-               break;
-       case dns_rdatasetadditional_fromglue:
-               acarray = header->additional_glue;
-               break;
-       default:
-               INSIST(0);
+       /*
+        * NS records want addresses in additional records.
+        */
+       INSIST(qtype == dns_rdatatype_a);
+
+       ctx = (rbtdb_glue_additionaldata_ctx_t *) arg;
+       result = ISC_R_FAILURE;
+       glue = NULL;
+       node_a = NULL;
+       node_aaaa = NULL;
+
+       dns_fixedname_init(&fixedname_a);
+        name_a = dns_fixedname_name(&fixedname_a);
+       dns_rdataset_init(&rdataset_a);
+       dns_rdataset_init(&sigrdataset_a);
+
+       dns_fixedname_init(&fixedname_aaaa);
+        name_aaaa = dns_fixedname_name(&fixedname_aaaa);
+       dns_rdataset_init(&rdataset_aaaa);
+       dns_rdataset_init(&sigrdataset_aaaa);
+
+       result = zone_find((dns_db_t *) ctx->rbtdb, name, ctx->rbtversion,
+                          dns_rdatatype_a, DNS_DBFIND_GLUEOK, 0,
+                          (dns_dbnode_t **) &node_a, name_a,
+                          &rdataset_a, &sigrdataset_a);
+       if (result == DNS_R_GLUE) {
+               glue = isc_mem_get(ctx->rbtdb->common.mctx, sizeof(*glue));
+               if (glue == NULL) {
+                       result = ISC_R_NOMEMORY;
+                       goto out;
+               }
+
+               dns_fixedname_init(&glue->fixedname);
+               gluename = dns_fixedname_name(&glue->fixedname);
+               dns_name_copy(name_a, gluename, NULL);
+
+               dns_rdataset_init(&glue->rdataset_a);
+               dns_rdataset_init(&glue->sigrdataset_a);
+               dns_rdataset_init(&glue->rdataset_aaaa);
+               dns_rdataset_init(&glue->sigrdataset_aaaa);
+
+               dns_rdataset_clone(&rdataset_a, &glue->rdataset_a);
+               if (dns_rdataset_isassociated(&sigrdataset_a)) {
+                       dns_rdataset_clone(&sigrdataset_a,
+                                          &glue->sigrdataset_a);
+               }
        }
 
-       if (acarray == NULL) {
-               unsigned int i;
+       result = zone_find((dns_db_t *) ctx->rbtdb, name, ctx->rbtversion,
+                          dns_rdatatype_aaaa, DNS_DBFIND_GLUEOK, 0,
+                          (dns_dbnode_t **) &node_aaaa, name_aaaa,
+                          &rdataset_aaaa, &sigrdataset_aaaa);
+       if (result == DNS_R_GLUE) {
+               if (glue == NULL) {
+                       glue = isc_mem_get(ctx->rbtdb->common.mctx,
+                                          sizeof(*glue));
+                       if (glue == NULL) {
+                               result = ISC_R_NOMEMORY;
+                               goto out;
+                       }
 
-               acarray = isc_mem_get(rbtdb->common.mctx, total_count *
-                                     sizeof(acachectl_t));
+                       dns_fixedname_init(&glue->fixedname);
+                       gluename = dns_fixedname_name(&glue->fixedname);
+                       dns_name_copy(name_aaaa, gluename, NULL);
 
-               if (acarray == NULL) {
-                       NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-                       goto fail;
+                       dns_rdataset_init(&glue->rdataset_a);
+                       dns_rdataset_init(&glue->sigrdataset_a);
+                       dns_rdataset_init(&glue->rdataset_aaaa);
+                       dns_rdataset_init(&glue->sigrdataset_aaaa);
+               } else {
+                       INSIST(node_a == node_aaaa);
+                       INSIST(dns_name_equal(name_a, name_aaaa));
                }
 
-               for (i = 0; i < total_count; i++) {
-                       acarray[i].entry = NULL;
-                       acarray[i].cbarg = NULL;
+               dns_rdataset_clone(&rdataset_aaaa, &glue->rdataset_aaaa);
+               if (dns_rdataset_isassociated(&sigrdataset_aaaa)) {
+                       dns_rdataset_clone(&sigrdataset_aaaa,
+                                          &glue->sigrdataset_aaaa);
                }
        }
-       switch (type) {
-       case dns_rdatasetadditional_fromauth:
-               header->additional_auth = acarray;
-               break;
-       case dns_rdatasetadditional_fromglue:
-               header->additional_glue = acarray;
-               break;
-       default:
-               INSIST(0);
-       }
 
-       if (acarray[count].entry != NULL) {
-               /*
-                * Swap the entry.  Delay cleaning-up the old entry since
-                * it would require a node lock.
-                */
-               oldentry = acarray[count].entry;
-               INSIST(acarray[count].cbarg != NULL);
-               oldcbarg = acarray[count].cbarg;
+       if (glue != NULL) {
+               glue->next = ctx->glue_list;
+               ctx->glue_list = glue;
        }
-       acarray[count].entry = newentry;
-       acarray[count].cbarg = newcbarg;
 
-       NODE_UNLOCK(nodelock, isc_rwlocktype_write);
+       result = ISC_R_SUCCESS;
 
-       if (oldentry != NULL) {
-               acache_cancelentry(rbtdb->common.mctx, oldentry, &oldcbarg);
-               dns_acache_detachentry(&oldentry);
-       }
+out:
+       if (dns_rdataset_isassociated(&rdataset_a))
+               rdataset_disassociate(&rdataset_a);
+       if (dns_rdataset_isassociated(&sigrdataset_a))
+               rdataset_disassociate(&sigrdataset_a);
 
-       return (ISC_R_SUCCESS);
+       if (dns_rdataset_isassociated(&rdataset_aaaa))
+               rdataset_disassociate(&rdataset_aaaa);
+       if (dns_rdataset_isassociated(&sigrdataset_aaaa))
+               rdataset_disassociate(&sigrdataset_aaaa);
 
- fail:
-       if (newcbarg != NULL) {
-               if (newentry != NULL) {
-                       acache_cancelentry(rbtdb->common.mctx, newentry,
-                                          &newcbarg);
-                       dns_acache_detachentry(&newentry);
-               } else {
-                       dns_db_detachnode((dns_db_t *)rbtdb, &newcbarg->node);
-                       dns_db_detach(&newcbarg->db);
-                       isc_mem_put(rbtdb->common.mctx, newcbarg,
-                           sizeof(*newcbarg));
-               }
-       }
+       if (node_a != NULL)
+               detachnode((dns_db_t *) ctx->rbtdb, (dns_dbnode_t *) &node_a);
+       if (node_aaaa != NULL)
+               detachnode((dns_db_t *) ctx->rbtdb,
+                          (dns_dbnode_t *) &node_aaaa);
 
        return (result);
 }
 
 static isc_result_t
-rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
-                      dns_rdatasetadditional_t type, dns_rdatatype_t qtype)
+rdataset_addglue(dns_rdataset_t *rdataset,
+                dns_dbversion_t *version,
+                unsigned int options,
+                dns_message_t *msg)
 {
        dns_rbtdb_t *rbtdb = rdataset->private1;
-       dns_rbtnode_t *rbtnode = rdataset->private2;
-       unsigned char *raw = rdataset->private3;        /* RDATASLAB */
-       unsigned int current_count = rdataset->privateuint4;
-       rdatasetheader_t *header;
-       nodelock_t *nodelock;
-       unsigned int total_count, count;
-       acachectl_t *acarray;
-       dns_acacheentry_t *entry;
-       acache_cbarg_t *cbarg;
-
-       UNUSED(qtype);          /* we do not use this value at least for now */
-       UNUSED(acache);
+       dns_rbtnode_t *node = rdataset->private2;
+       rbtdb_version_t *rbtversion = version;
+       isc_uint32_t index;
+       rbtdb_glue_table_node_t *cur;
+       isc_boolean_t found;
+       isc_boolean_t restarted;
+       rbtdb_glue_t *ge;
+       rbtdb_glue_additionaldata_ctx_t ctx;
+       isc_result_t result;
 
-       if (type == dns_rdatasetadditional_fromcache)
-               return (ISC_R_SUCCESS);
+       INSIST(rdataset->type == dns_rdatatype_ns);
+       INSIST(rbtdb == rbtversion->rbtdb);
+       INSIST(!IS_CACHE(rbtdb) && !IS_STUB(rbtdb));
 
-       header = (struct rdatasetheader *)(raw - sizeof(*header));
+       found = ISC_FALSE;
+       restarted = ISC_FALSE;
+       result = ISC_R_FAILURE;
 
-       total_count = raw[0] * 256 + raw[1];
-       INSIST(total_count > current_count);
-       count = total_count - current_count - 1;
+       /*
+        * The glue table cache that forms a part of the DB version
+        * structure is not explicitly bounded and there's no cache
+        * cleaning. The zone data size itself is an implicit bound.
+        *
+        * The key into the glue hashtable is the node pointer. This is
+        * because the glue hashtable is a property of the DB version,
+        * and the glue is keyed for the ownername/NS tuple. We don't
+        * bother with using an expensive dns_name_t comparison here as
+        * the node pointer is a fixed value that won't change for a DB
+        * version and can be compared directly.
+        */
+       index = isc_hash_function(&node, sizeof(node), ISC_TRUE, NULL) %
+               rbtversion->glue_table_size;
 
-       acarray = NULL;
-       entry = NULL;
+restart:
+       /*
+        * First, check if we have the additional entries already cached
+        * in the glue table.
+        */
+       RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_read);
 
-       nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
-       NODE_LOCK(nodelock, isc_rwlocktype_write);
+       for (cur = rbtversion->glue_table[index]; cur != NULL; cur = cur->next)
+               if (cur->node == node)
+                       break;
 
-       switch (type) {
-       case dns_rdatasetadditional_fromauth:
-               acarray = header->additional_auth;
-               break;
-       case dns_rdatasetadditional_fromglue:
-               acarray = header->additional_glue;
-               break;
-       default:
-               INSIST(0);
+       if (cur == NULL) {
+               goto no_glue;
        }
+       /*
+        * We found a cached result. Add it to the message and
+        * return.
+        */
+       found = ISC_TRUE;
+       ge = cur->glue_list;
 
-       if (acarray == NULL) {
-               NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-               return (ISC_R_NOTFOUND);
-       }
+       /*
+        * (void *) -1 is a special value that means no glue is
+        * present in the zone.
+        */
+       if (ge == (void *) -1)
+               goto no_glue;
+
+       for (; ge != NULL; ge = ge->next) {
+               isc_buffer_t *buffer = NULL;
+               dns_name_t *name = NULL;
+               dns_rdataset_t *rdataset_a = NULL;
+               dns_rdataset_t *sigrdataset_a = NULL;
+               dns_rdataset_t *rdataset_aaaa = NULL;
+               dns_rdataset_t *sigrdataset_aaaa = NULL;
+               dns_name_t *gluename = dns_fixedname_name(&ge->fixedname);
+
+               result = isc_buffer_allocate(msg->mctx, &buffer, 512);
+               if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                       goto no_glue;
+               }
 
-       entry = acarray[count].entry;
-       if (entry == NULL) {
-               NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-               return (ISC_R_NOTFOUND);
-       }
+               result = dns_message_gettempname(msg, &name);
+               if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                       isc_buffer_free(&buffer);
+                       goto no_glue;
+               }
 
-       acarray[count].entry = NULL;
-       cbarg = acarray[count].cbarg;
-       acarray[count].cbarg = NULL;
+               dns_name_copy(gluename, name, buffer);
+               dns_message_takebuffer(msg, &buffer);
 
-       NODE_UNLOCK(nodelock, isc_rwlocktype_write);
+               if (dns_rdataset_isassociated(&ge->rdataset_a)) {
+                       result = dns_message_gettemprdataset(msg, &rdataset_a);
+                       if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                               dns_message_puttempname(msg, &name);
+                               isc_buffer_free(&buffer);
+                               goto no_glue;
+                       }
+               }
 
-       if (entry != NULL) {
-               if (cbarg != NULL)
-                       acache_cancelentry(rbtdb->common.mctx, entry, &cbarg);
-               dns_acache_detachentry(&entry);
+               if (dns_rdataset_isassociated(&ge->sigrdataset_a)) {
+                       result = dns_message_gettemprdataset(msg,
+                                                            &sigrdataset_a);
+                       if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                               if (rdataset_a != NULL) {
+                                       dns_message_puttemprdataset(msg,
+                                                                 &rdataset_a);
+                               }
+                               dns_message_puttempname(msg, &name);
+                               isc_buffer_free(&buffer);
+                               goto no_glue;
+                       }
+               }
+
+               if (ISC_LIKELY((options & DNS_RDATASETADDGLUE_FILTERAAAA) == 0))
+               {
+                       if (dns_rdataset_isassociated(&ge->rdataset_aaaa)) {
+                               result = dns_message_gettemprdataset(msg,
+                                                           &rdataset_aaaa);
+                               if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                                       dns_message_puttempname(msg, &name);
+                                       isc_buffer_free(&buffer);
+                                       if (rdataset_a != NULL) {
+                                               dns_message_puttemprdataset(msg,
+                                                           &rdataset_a);
+                                       }
+                                       if (sigrdataset_a != NULL) {
+                                               dns_message_puttemprdataset(msg,
+                                                           &sigrdataset_a);
+                                       }
+                                       goto no_glue;
+                               }
+                       }
+
+                       if (dns_rdataset_isassociated(&ge->sigrdataset_aaaa)) {
+                               result = dns_message_gettemprdataset(msg,
+                                                           &sigrdataset_aaaa);
+                               if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) {
+                                       dns_message_puttempname(msg, &name);
+                                       isc_buffer_free(&buffer);
+                                       if (rdataset_a != NULL) {
+                                               dns_message_puttemprdataset(msg,
+                                                           &rdataset_a);
+                                       }
+                                       if (sigrdataset_a != NULL)
+                                               dns_message_puttemprdataset(msg,
+                                                           &sigrdataset_a);
+                                       if (rdataset_aaaa != NULL)
+                                               dns_message_puttemprdataset(msg,
+                                                           &rdataset_aaaa);
+                                       goto no_glue;
+                               }
+                       }
+               }
+
+               if (ISC_LIKELY(dns_rdataset_isassociated(&ge->rdataset_a))) {
+                       dns_rdataset_clone(&ge->rdataset_a, rdataset_a);
+                       ISC_LIST_APPEND(name->list, rdataset_a, link);
+               }
+
+               if (dns_rdataset_isassociated(&ge->sigrdataset_a)) {
+                       dns_rdataset_clone(&ge->sigrdataset_a, sigrdataset_a);
+                       ISC_LIST_APPEND(name->list, sigrdataset_a, link);
+               }
+
+               if (ISC_LIKELY((options & DNS_RDATASETADDGLUE_FILTERAAAA) == 0))
+               {
+                       if (dns_rdataset_isassociated(&ge->rdataset_aaaa)) {
+                               dns_rdataset_clone(&ge->rdataset_aaaa,
+                                                  rdataset_aaaa);
+                               ISC_LIST_APPEND(name->list, rdataset_aaaa,
+                                               link);
+                       }
+                       if (dns_rdataset_isassociated(&ge->sigrdataset_aaaa)) {
+                               dns_rdataset_clone(&ge->sigrdataset_aaaa,
+                                                  sigrdataset_aaaa);
+                               ISC_LIST_APPEND(name->list, sigrdataset_aaaa,
+                                               link);
+                       }
+               }
+
+               dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
        }
 
-       return (ISC_R_SUCCESS);
-}
+no_glue:
+       RWUNLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_read);
 
-static void
-setownercase(rdatasetheader_t *header, const dns_name_t *name) {
-       unsigned int i;
+       if (found) {
+               return (ISC_R_SUCCESS);
+       }
+
+       if (restarted) {
+               return (ISC_R_FAILURE);
+       }
 
        /*
-        * We do not need to worry about label lengths as they are all
-        * less than or equal to 63.
+        * No cached glue was found in the table. Cache it and restart
+        * this function.
+        *
+        * Due to the gap between the read lock and the write lock, it's
+        * possible that we may cache a duplicate glue table entry, but
+        * we don't care.
         */
-       memset(header->upper, 0, sizeof(header->upper));
-       for (i = 0; i < name->length; i++)
-               if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
-                       header->upper[i/8] |= 1 << (i%8);
-       header->attributes |= RDATASET_ATTR_CASESET;
-}
 
-static void
-rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
-       unsigned char *raw = rdataset->private3;        /* RDATASLAB */
-       rdatasetheader_t *header;
+       ctx.glue_list = NULL;
+       ctx.rbtdb = rbtdb;
+       ctx.rbtversion = rbtversion;
 
-       header = (struct rdatasetheader *)(raw - sizeof(*header));
-       setownercase(header, name);
-}
+       RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_write);
 
-static void
-rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
-       const unsigned char *raw = rdataset->private3;        /* RDATASLAB */
-       const rdatasetheader_t *header;
-       unsigned int i;
+       if (ISC_UNLIKELY(rehash_gluetable(rbtversion))) {
+               index = isc_hash_function(&node, sizeof(node),
+                                         ISC_TRUE, NULL) %
+                       rbtversion->glue_table_size;
+       }
 
-       header = (const struct rdatasetheader *)(raw - sizeof(*header));
+       (void)dns_rdataset_additionaldata(rdataset, glue_nsdname_cb, &ctx);
 
-       if (!CASESET(header))
-               return;
+       cur = isc_mem_get(rbtdb->common.mctx, sizeof(*cur));
+       if (cur == NULL) {
+               result = ISC_R_NOMEMORY;
+               goto out;
+       }
 
-       for (i = 0; i < name->length; i++) {
+       /*
+        * XXXMUKS: it looks like the dns_dbversion is not destroyed
+        * when named is terminated by a keyboard break. This doesn't
+        * cleanup the node reference and keeps the process dangling.
+        */
+       /* dns_rbtnode_refincrement0(node, NULL); */
+       cur->node = node;
+
+       if (ctx.glue_list == NULL) {
                /*
-                * Set the case bit if it does not match the recorded bit.
+                * No glue was found. Cache it so.
                 */
-               if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
-                   (header->upper[i/8] & (1 << (i%8))) != 0)
-                       name->ndata[i] &= ~0x20; /* clear the lower case bit */
-               else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
-                        (header->upper[i/8] & (1 << (i%8))) == 0)
-                       name->ndata[i] |= 0x20; /* set the lower case bit */
+               cur->glue_list = (void *) -1;
+       } else {
+               cur->glue_list = ctx.glue_list;
        }
+
+       cur->next = rbtversion->glue_table[index];
+       rbtversion->glue_table[index] = cur;
+       rbtversion->glue_table_nodecount++;
+
+       result = ISC_R_SUCCESS;
+
+ out:
+       RWUNLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_write);
+
+       if (result == ISC_R_SUCCESS) {
+               restarted = ISC_TRUE;
+               goto restart;
+       }
+
+       return (result);
 }
 
 /*%
index 57024273644b4d36d021138491d3223388eb6ebc..a14a2339104d08c7df252a56fc7ba612be96a200 100644 (file)
@@ -36,14 +36,12 @@ static dns_rdatasetmethods_t methods = {
        isc__rdatalist_getnoqname,
        isc__rdatalist_addclosest,
        isc__rdatalist_getclosest,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
        isc__rdatalist_setownercase,
-       isc__rdatalist_getownercase
+       isc__rdatalist_getownercase,
+       NULL  /* addglue */
 };
 
 void
index bbc9c8bd863f62fba4f6b86b00fbb57b02868072..0fc45acf122fec55154dc64458810989fa44e25e 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
 /*! \file */
 
 #include <config.h>
@@ -190,18 +188,16 @@ static dns_rdatasetmethods_t question_methods = {
        question_current,
        question_clone,
        question_count,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL, /* addnoqname */
+       NULL, /* getnoqname */
+       NULL, /* addclosest */
+       NULL, /* getclosest */
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
+       NULL, /* setownercase */
+       NULL, /* getownercase */
+       NULL  /* addglue */
 };
 
 void
@@ -293,6 +289,7 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
 #define MAX_SHUFFLE    32
 #define WANT_FIXED(r)  (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
 #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
+#define WANT_CYCLIC(r) (((r)->attributes & DNS_RDATASETATTR_CYCLIC) != 0)
 
 struct towire_sort {
        int key;
@@ -320,9 +317,11 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
        isc_buffer_t savedbuffer, rdlen, rrbuffer;
        unsigned int headlen;
        isc_boolean_t question = ISC_FALSE;
-       isc_boolean_t shuffle = ISC_FALSE;
-       dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
-       struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
+       isc_boolean_t shuffle = ISC_FALSE, sort = ISC_FALSE;
+       dns_rdata_t orig_fixed[MAX_SHUFFLE];
+       dns_rdata_t *orig = orig_fixed;
+       struct towire_sort new_fixed[MAX_SHUFFLE];
+       struct towire_sort *new = new_fixed;
        dns_fixedname_t fixed;
        dns_name_t *name;
 
@@ -363,53 +362,43 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
        }
 
        /*
-        * Do we want to shuffle this answer?
+        * Do we want to sort and/or shuffle this answer?
         */
-       if (!question && count > 1 &&
-           (!WANT_FIXED(rdataset) || order != NULL) &&
-           rdataset->type != dns_rdatatype_rrsig)
-               shuffle = ISC_TRUE;
-
-       if (shuffle && count > MAX_SHUFFLE) {
-               shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
-               sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
-               if (shuffled == NULL || sorted == NULL)
-                       shuffle = ISC_FALSE;
-       } else {
-               shuffled = shuffled_fixed;
-               sorted = sorted_fixed;
+       if (!question && count > 1 && rdataset->type != dns_rdatatype_rrsig) {
+               if (order != NULL) {
+                       sort = ISC_TRUE;
+               }
+               if (WANT_RANDOM(rdataset) || WANT_CYCLIC(rdataset)) {
+                       shuffle = ISC_TRUE;
+               }
        }
 
-       if (shuffle) {
+       if ((shuffle || sort) && count > MAX_SHUFFLE) {
+               orig = isc_mem_get(cctx->mctx, count * sizeof(*orig));
+               new = isc_mem_get(cctx->mctx, count * sizeof(*new));
+               if (orig == NULL || new == NULL)
+                       shuffle = sort = ISC_FALSE;
+       }
+
+       if (shuffle || sort) {
                /*
                 * First we get handles to all of the rdata.
                 */
                i = 0;
                do {
                        INSIST(i < count);
-                       dns_rdata_init(&shuffled[i]);
-                       dns_rdataset_current(rdataset, &shuffled[i]);
+                       dns_rdata_init(&orig[i]);
+                       dns_rdataset_current(rdataset, &orig[i]);
                        i++;
                        result = dns_rdataset_next(rdataset);
                } while (result == ISC_R_SUCCESS);
                if (result != ISC_R_NOMORE)
                        goto cleanup;
                INSIST(i == count);
+       }
 
-               /*
-                * Now we shuffle.
-                */
-               if (WANT_FIXED(rdataset)) {
-                       /*
-                        * 'Fixed' order.
-                        */
-                       INSIST(order != NULL);
-                       for (i = 0; i < count; i++) {
-                               sorted[i].key = (*order)(&shuffled[i],
-                                                        order_arg);
-                               sorted[i].rdata = &shuffled[i];
-                       }
-               } else if (WANT_RANDOM(rdataset)) {
+       if (shuffle) {
+               if (WANT_RANDOM(rdataset)) {
                        /*
                         * 'Random' order.
                         */
@@ -418,19 +407,19 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
 
                                isc_random_get(&val);
                                choice = i + (val % (count - i));
-                               rdata = shuffled[i];
-                               shuffled[i] = shuffled[choice];
-                               shuffled[choice] = rdata;
+                               rdata = orig[i];
+                               orig[i] = orig[choice];
+                               orig[choice] = rdata;
                                if (order != NULL)
-                                       sorted[i].key = (*order)(&shuffled[i],
+                                       new[i].key = (*order)(&orig[i],
                                                                 order_arg);
                                else
-                                       sorted[i].key = 0; /* Unused */
-                               sorted[i].rdata = &shuffled[i];
+                                       new[i].key = 0; /* Unused */
+                               new[i].rdata = &orig[i];
                        }
-               } else {
+               } else if (WANT_CYCLIC(rdataset)) {
                        /*
-                        * "Cyclic" order.
+                        * 'Cyclic' order.
                         */
                        isc_uint32_t val;
                        unsigned int j;
@@ -441,23 +430,31 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                        j = val % count;
                        for (i = 0; i < count; i++) {
                                if (order != NULL)
-                                       sorted[i].key = (*order)(&shuffled[j],
+                                       new[i].key = (*order)(&orig[j],
                                                                 order_arg);
                                else
-                                       sorted[i].key = 0; /* Unused */
-                               sorted[i].rdata = &shuffled[j];
+                                       new[i].key = 0; /* Unused */
+                               new[i].rdata = &orig[j];
                                j++;
                                if (j == count)
                                        j = 0; /* Wrap around. */
                        }
                }
+       } else if (sort) {
+               for (i = 0; i < count; i++) {
+                       if (order != NULL)
+                               new[i].key = (*order)(&orig[i], order_arg);
+                       else
+                               new[i].key = 0; /* Unused */
+                       new[i].rdata = &orig[i];
+               }
+       }
 
-               /*
-                * Sorted order.
-                */
-               if (order != NULL)
-                       qsort(sorted, count, sizeof(sorted[0]),
-                             towire_compare);
+       /*
+        * Sortlist order.
+        */
+       if (sort) {
+               qsort(new, count, sizeof(new[0]), towire_compare);
        }
 
        savedbuffer = *target;
@@ -502,9 +499,9 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                        /*
                         * Copy out the rdata
                         */
-                       if (shuffle)
-                               rdata = *(sorted[i].rdata);
-                       else {
+                       if (shuffle || sort) {
+                               rdata = *(new[i].rdata);
+                       else {
                                dns_rdata_reset(&rdata);
                                dns_rdataset_current(rdataset, &rdata);
                        }
@@ -519,7 +516,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                        added++;
                }
 
-               if (shuffle) {
+               if (shuffle || sort) {
                        i++;
                        if (i == count)
                                result = ISC_R_NOMORE;
@@ -552,10 +549,10 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
        *target = savedbuffer;
 
  cleanup:
-       if (sorted != NULL && sorted != sorted_fixed)
-               isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
-       if (shuffled != NULL && shuffled != shuffled_fixed)
-               isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
+       if (new != NULL && new != new_fixed)
+               isc_mem_put(cctx->mctx, new, count * sizeof(*new));
+       if (orig != NULL && orig != orig_fixed)
+               isc_mem_put(cctx->mctx, orig, count * sizeof(*orig));
        return (result);
 }
 
@@ -680,83 +677,6 @@ dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
        return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
 }
 
-/*
- * Additional cache stuff
- */
-isc_result_t
-dns_rdataset_getadditional(dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype,
-                          dns_acache_t *acache,
-                          dns_zone_t **zonep,
-                          dns_db_t **dbp,
-                          dns_dbversion_t **versionp,
-                          dns_dbnode_t **nodep,
-                          dns_name_t *fname,
-                          dns_message_t *msg,
-                          isc_stdtime_t now)
-{
-       REQUIRE(DNS_RDATASET_VALID(rdataset));
-       REQUIRE(rdataset->methods != NULL);
-       REQUIRE(zonep == NULL || *zonep == NULL);
-       REQUIRE(dbp != NULL && *dbp == NULL);
-       REQUIRE(versionp != NULL && *versionp == NULL);
-       REQUIRE(nodep != NULL && *nodep == NULL);
-       REQUIRE(fname != NULL);
-       REQUIRE(msg != NULL);
-
-       if (acache != NULL && rdataset->methods->getadditional != NULL) {
-               return ((rdataset->methods->getadditional)(rdataset, type,
-                                                          qtype, acache,
-                                                          zonep, dbp,
-                                                          versionp, nodep,
-                                                          fname, msg, now));
-       }
-
-       return (ISC_R_FAILURE);
-}
-
-isc_result_t
-dns_rdataset_setadditional(dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype,
-                          dns_acache_t *acache,
-                          dns_zone_t *zone,
-                          dns_db_t *db,
-                          dns_dbversion_t *version,
-                          dns_dbnode_t *node,
-                          dns_name_t *fname)
-{
-       REQUIRE(DNS_RDATASET_VALID(rdataset));
-       REQUIRE(rdataset->methods != NULL);
-
-       if (acache != NULL && rdataset->methods->setadditional != NULL) {
-               return ((rdataset->methods->setadditional)(rdataset, type,
-                                                          qtype, acache, zone,
-                                                          db, version,
-                                                          node, fname));
-       }
-
-       return (ISC_R_FAILURE);
-}
-
-isc_result_t
-dns_rdataset_putadditional(dns_acache_t *acache,
-                          dns_rdataset_t *rdataset,
-                          dns_rdatasetadditional_t type,
-                          dns_rdatatype_t qtype)
-{
-       REQUIRE(DNS_RDATASET_VALID(rdataset));
-       REQUIRE(rdataset->methods != NULL);
-
-       if (acache != NULL && rdataset->methods->putadditional != NULL) {
-               return ((rdataset->methods->putadditional)(acache, rdataset,
-                                                          type, qtype));
-       }
-
-       return (ISC_R_FAILURE);
-}
-
 void
 dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
        REQUIRE(DNS_RDATASET_VALID(rdataset));
@@ -830,3 +750,20 @@ dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
        rdataset->ttl = ttl;
        sigrdataset->ttl = ttl;
 }
+
+isc_result_t
+dns_rdataset_addglue(dns_rdataset_t *rdataset,
+                    dns_dbversion_t *version,
+                    unsigned int options,
+                    dns_message_t *msg)
+{
+       REQUIRE(DNS_RDATASET_VALID(rdataset));
+       REQUIRE(rdataset->methods != NULL);
+       REQUIRE(rdataset->type == dns_rdatatype_ns);
+
+       if (rdataset->methods->addglue == NULL)
+               return (ISC_R_NOTIMPLEMENTED);
+
+       return ((rdataset->methods->addglue)(rdataset, version,
+                                            options, msg));
+}
index cdff86c0dc63783646953571e4ae95b60830e8cc..ee5039ab035e7d89402a38f45c4e5b26f78cc778 100644 (file)
@@ -449,18 +449,16 @@ static dns_rdatasetmethods_t rdataset_methods = {
        rdataset_current,
        rdataset_clone,
        rdataset_count,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL, /* addnoqname */
+       NULL, /* getnoqname */
+       NULL, /* addclosest */
+       NULL, /* getclosest */
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
+       NULL, /* setownercase */
+       NULL, /* getownercase */
+       NULL  /* addglue */
 };
 
 void
index 55cbf44554cad75799d95297f039ad253d377fcb..053f1ac655ac3719738689b402f9be02cb344dca 100644 (file)
@@ -1415,16 +1415,14 @@ static dns_rdatasetmethods_t methods = {
        isc__rdatalist_count,
        isc__rdatalist_addnoqname,
        isc__rdatalist_getnoqname,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL, /* addclosest */
+       NULL, /* getclosest */
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
+       NULL, /* setownercase */
+       NULL, /* getownercase */
+       NULL  /* addglue */
 };
 
 static void
index b80c978a022e0c0b8009e95b96a8c351c6ddea3e..5627aaf3325730dc1d9865846d5f62a37757ed40 100644 (file)
@@ -1471,16 +1471,14 @@ static dns_rdatasetmethods_t rdataset_methods = {
        isc__rdatalist_count,
        isc__rdatalist_addnoqname,
        isc__rdatalist_getnoqname,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL
+       NULL, /* addclosest */
+       NULL, /* getclosest */
+       NULL, /* settrust */
+       NULL, /* expire */
+       NULL, /* clearprefetch */
+       NULL, /* setownercase */
+       NULL, /* getownercase */
+       NULL  /* addglue */
 };
 
 static void
index 7c19f1619b10d1806c3bad8e5cf99a53ce3a6137..7908f4dc444bc9e4f7b11542a643787e94b70fa5 100644 (file)
@@ -124,7 +124,7 @@ dns_ssu_external_match(const dns_name_t *identity,
        int fd;
        const char *sock_path;
        unsigned int req_len;
-       isc_region_t token_region;
+       isc_region_t token_region = {NULL, 0};
        unsigned char *data;
        isc_buffer_t buf;
        isc_uint32_t token_len = 0;
index 0e02ccad967633a5eeac949fa0402440b473470d..3c3f4aa502e8f643ae80aa744e26d5aa1b1b12bc 100644 (file)
@@ -24,7 +24,6 @@
 #include <isc/task.h>
 #include <isc/util.h>
 
-#include <dns/acache.h>
 #include <dns/acl.h>
 #include <dns/adb.h>
 #include <dns/badcache.h>
@@ -137,7 +136,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
                goto cleanup_zt;
        }
 
-       view->acache = NULL;
        view->cache = NULL;
        view->cachedb = NULL;
        ISC_LIST_INIT(view->dlz_searched);
@@ -180,8 +178,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
         */
        view->recursion = ISC_TRUE;
        view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
-       view->additionalfromcache = ISC_TRUE;
-       view->additionalfromauth = ISC_TRUE;
        view->enablednssec = ISC_TRUE;
        view->enablevalidation = ISC_TRUE;
        view->acceptexpired = ISC_FALSE;
@@ -380,11 +376,6 @@ destroy(dns_view_t *view) {
                dns_adb_detach(&view->adb);
        if (view->resolver != NULL)
                dns_resolver_detach(&view->resolver);
-       if (view->acache != NULL) {
-               if (view->cachedb != NULL)
-                       dns_acache_putdb(view->acache, view->cachedb);
-               dns_acache_detach(&view->acache);
-       }
        dns_rrl_view_destroy(view);
        if (view->rpzs != NULL)
                dns_rpz_detach_rpzs(&view->rpzs);
@@ -585,8 +576,6 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
                        dns_adb_shutdown(view->adb);
                if (!REQSHUTDOWN(view))
                        dns_requestmgr_shutdown(view->requestmgr);
-               if (view->acache != NULL)
-                       dns_acache_shutdown(view->acache);
                if (view->zonetable != NULL) {
                        if (view->flush)
                                dns_zt_flushanddetach(&view->zonetable);
@@ -851,17 +840,12 @@ dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
 
        view->cacheshared = shared;
        if (view->cache != NULL) {
-               if (view->acache != NULL)
-                       dns_acache_putdb(view->acache, view->cachedb);
                dns_db_detach(&view->cachedb);
                dns_cache_detach(&view->cache);
        }
        dns_cache_attach(cache, &view->cache);
        dns_cache_attachdb(cache, &view->cachedb);
        INSIST(DNS_DB_VALID(view->cachedb));
-
-       if (view->acache != NULL)
-               dns_acache_setdb(view->acache, view->cachedb);
 }
 
 isc_boolean_t
@@ -1637,12 +1621,8 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
                if (result != ISC_R_SUCCESS)
                        return (result);
        }
-       if (view->acache != NULL)
-               dns_acache_putdb(view->acache, view->cachedb);
        dns_db_detach(&view->cachedb);
        dns_cache_attachdb(view->cache, &view->cachedb);
-       if (view->acache != NULL)
-               dns_acache_setdb(view->acache, view->cachedb);
        if (view->resolver != NULL)
                dns_resolver_flushbadcache(view->resolver, NULL);
        if (view->failcache != NULL)
index e7cbb6fa53d362a1d8fc495759c10a7a1e6cf063..cade3361729d796d0bdf2563c6d46b03cc35188b 100644 (file)
@@ -3,21 +3,6 @@ LIBRARY libdns
 ; Exported Functions
 EXPORTS
 
-dns_acache_attach
-dns_acache_attachentry
-dns_acache_cancelentry
-dns_acache_countquerymiss
-dns_acache_create
-dns_acache_createentry
-dns_acache_detach
-dns_acache_detachentry
-dns_acache_getentry
-dns_acache_putdb
-dns_acache_setcachesize
-dns_acache_setcleaninginterval
-dns_acache_setdb
-dns_acache_setentry
-dns_acache_shutdown
 dns_acl_any
 dns_acl_attach
 dns_acl_create
@@ -818,6 +803,7 @@ dns_rdatalist_fromrdataset
 dns_rdatalist_init
 dns_rdatalist_tordataset
 dns_rdataset_addclosest
+dns_rdataset_addglue
 dns_rdataset_additionaldata
 dns_rdataset_addnoqname
 dns_rdataset_clearprefetch
@@ -827,7 +813,6 @@ dns_rdataset_current
 dns_rdataset_disassociate
 dns_rdataset_expire
 dns_rdataset_first
-dns_rdataset_getadditional
 dns_rdataset_getclosest
 dns_rdataset_getnoqname
 dns_rdataset_getownercase
@@ -836,8 +821,6 @@ dns_rdataset_invalidate
 dns_rdataset_isassociated
 dns_rdataset_makequestion
 dns_rdataset_next
-dns_rdataset_putadditional
-dns_rdataset_setadditional
 dns_rdataset_setownercase
 dns_rdataset_settrust
 dns_rdataset_totext
@@ -1266,7 +1249,6 @@ dns_zone_replacedb
 dns_zone_rpz_enable
 dns_zone_rpz_enable_db
 dns_zone_set_parentcatz
-dns_zone_setacache
 dns_zone_setadded
 dns_zone_setalsonotify
 dns_zone_setalsonotifydscpkeys
index fa5d2b5b13fd4ab17d765d5b2368a3fa7fe33fa9..186a045f0218dcc06de3ec58f1b06e3b595cbb68 100644 (file)
@@ -98,10 +98,6 @@ LINK32=link.exe
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
 # Begin Source File
 
-SOURCE=..\include\dns\acache.h
-# End Source File
-# Begin Source File
-
 SOURCE=..\include\dns\acl.h
 # End Source File
 # Begin Source File
@@ -504,10 +500,6 @@ SOURCE=..\include\dns\zt.h
 # PROP Default_Filter "c"
 # Begin Source File
 
-SOURCE=..\acache.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\acl.c
 # End Source File
 # Begin Source File
index 913dbebef0a6ed0c54a4886245b48985fa1ee358..d0d1744987b772fa041f7ffb7110a78c8825c49d 100644 (file)
@@ -120,7 +120,6 @@ CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN"
 !ELSE 
 CLEAN :
 !ENDIF 
-       -@erase "$(INTDIR)\acache.obj"
        -@erase "$(INTDIR)\acl.obj"
        -@erase "$(INTDIR)\adb.obj"
        -@erase "$(INTDIR)\badcache.obj"
@@ -282,7 +281,6 @@ LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) ../../isc/win32/Releas
 DEF_FILE= \
        ".\libdns.def"
 LINK32_OBJS= \
-       "$(INTDIR)\acache.obj" \
        "$(INTDIR)\acl.obj" \
        "$(INTDIR)\adb.obj" \
        "$(INTDIR)\badcache.obj" \
@@ -422,8 +420,6 @@ CLEAN :"libisc - @PLATFORM@ DebugCLEAN"
 !ELSE 
 CLEAN :
 !ENDIF 
-       -@erase "$(INTDIR)\acache.obj"
-       -@erase "$(INTDIR)\acache.sbr"
        -@erase "$(INTDIR)\acl.obj"
        -@erase "$(INTDIR)\acl.sbr"
        -@erase "$(INTDIR)\adb.obj"
@@ -687,7 +683,6 @@ RSC=rc.exe
 BSC32=bscmake.exe
 BSC32_FLAGS=/nologo /o"$(OUTDIR)\libdns.bsc" 
 BSC32_SBRS= \
-       "$(INTDIR)\acache.sbr" \
        "$(INTDIR)\acl.sbr" \
        "$(INTDIR)\adb.sbr" \
        "$(INTDIR)\badcache.sbr" \
@@ -807,7 +802,6 @@ LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) ../../isc/win32/Debug/
 DEF_FILE= \
        ".\libdns.def"
 LINK32_OBJS= \
-       "$(INTDIR)\acache.obj" \
        "$(INTDIR)\acl.obj" \
        "$(INTDIR)\adb.obj" \
        "$(INTDIR)\badcache.obj" \
@@ -937,24 +931,6 @@ LINK32_OBJS= \
 
 
 !IF "$(CFG)" == "libdns - @PLATFORM@ Release" || "$(CFG)" == "libdns - @PLATFORM@ Debug"
-SOURCE=..\acache.c
-
-!IF  "$(CFG)" == "libdns - @PLATFORM@ Release"
-
-
-"$(INTDIR)\acache.obj" : $(SOURCE) "$(INTDIR)"
-       $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF  "$(CFG)" == "libdns - @PLATFORM@ Debug"
-
-
-"$(INTDIR)\acache.obj" "$(INTDIR)\acache.sbr" : $(SOURCE) "$(INTDIR)"
-       $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF 
-
 SOURCE=..\acl.c
 
 !IF  "$(CFG)" == "libdns - @PLATFORM@ Release"
index 363b9c35c1f74d15341e58ab61e0e8d2c8ee70bb..e2244c56ddaf1dd7ad12d9583cc7855c3ed337d9 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Resource Files">
@@ -30,9 +30,6 @@
     <ClCompile Include="version.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\acache.c">
-      <Filter>Library Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\acl.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\rdatalist_p.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\include\dns\acache.h">
-      <Filter>Library Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\include\dns\acl.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
index ca23b1d31f5bf1fb066ffbeafb8a85c39c7a06b2..1308f58f6ff94a520ee8c3e7d01a19a7ffff0bd2 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|@PLATFORM@">
     <None Include="libdns.def" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\acache.c" />
     <ClCompile Include="..\acl.c" />
     <ClCompile Include="..\adb.c" />
     <ClCompile Include="..\badcache.c" />
 @IF PKCS11
     <ClInclude Include="..\dst_pkcs11.h" />
 @END PKCS11
-    <ClInclude Include="..\include\dns\acache.h" />
     <ClInclude Include="..\include\dns\acl.h" />
     <ClInclude Include="..\include\dns\adb.h" />
     <ClInclude Include="..\include\dns\badcache.h" />
index f477efc7650a9927c61217aaed6bf9db0a9cea05..d4c54d16a998fb61ad07eb72cff87b30ea8f2852 100644 (file)
@@ -30,7 +30,6 @@
 #include <isc/timer.h>
 #include <isc/util.h>
 
-#include <dns/acache.h>
 #include <dns/acl.h>
 #include <dns/adb.h>
 #include <dns/callbacks.h>
@@ -302,7 +301,6 @@ struct dns_zone {
        isc_uint32_t            sigvalidityinterval;
        isc_uint32_t            sigresigninginterval;
        dns_view_t              *view;
-       dns_acache_t            *acache;
        dns_checkmxfunc_t       checkmx;
        dns_checksrvfunc_t      checksrv;
        dns_checknsfunc_t       checkns;
@@ -1016,7 +1014,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->sigvalidityinterval = 30 * 24 * 3600;
        zone->sigresigninginterval = 7 * 24 * 3600;
        zone->view = NULL;
-       zone->acache = NULL;
        zone->checkmx = NULL;
        zone->checksrv = NULL;
        zone->checkns = NULL;
@@ -1170,8 +1167,6 @@ zone_free(dns_zone_t *zone) {
                dns_stats_detach(&zone->rcvquerystats);
        if (zone->db != NULL)
                zone_detachdb(zone);
-       if (zone->acache != NULL)
-               dns_acache_detach(&zone->acache);
        if (zone->rpzs != NULL) {
                REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
                dns_rpz_detach_rpzs(&zone->rpzs);
@@ -1518,36 +1513,6 @@ dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
        return (result);
 }
 
-void
-dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
-       REQUIRE(DNS_ZONE_VALID(zone));
-       REQUIRE(acache != NULL);
-
-       LOCK_ZONE(zone);
-       if (zone->acache != NULL)
-               dns_acache_detach(&zone->acache);
-       dns_acache_attach(acache, &zone->acache);
-       ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
-       if (zone->db != NULL) {
-               isc_result_t result;
-
-               /*
-                * If the zone reuses an existing DB, the DB needs to be
-                * set in the acache explicitly.  We can safely ignore the
-                * case where the DB is already set.  If other error happens,
-                * the acache will not work effectively.
-                */
-               result = dns_acache_setdb(acache, zone->db);
-               if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
-                       UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                        "dns_acache_setdb() failed: %s",
-                                        isc_result_totext(result));
-               }
-       }
-       ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-       UNLOCK_ZONE(zone);
-}
-
 static isc_result_t
 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
        char *copy;
@@ -14662,15 +14627,6 @@ zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
        REQUIRE(zone->db == NULL && db != NULL);
 
        dns_db_attach(db, &zone->db);
-       if (zone->acache != NULL) {
-               isc_result_t result;
-               result = dns_acache_setdb(zone->acache, db);
-               if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
-                       UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                        "dns_acache_setdb() failed: %s",
-                                        isc_result_totext(result));
-               }
-       }
 }
 
 /* The caller must hold the dblock as a writer. */
@@ -14678,8 +14634,6 @@ static inline void
 zone_detachdb(dns_zone_t *zone) {
        REQUIRE(zone->db != NULL);
 
-       if (zone->acache != NULL)
-               (void)dns_acache_putdb(zone->acache, zone->db);
        dns_db_detach(&zone->db);
 }
 
index a9c5992c58d49b858a9b2ff1dbd52369b48d3035..c1d85b6d60cdc2e2d3ee5cb9b1213d11748725c3 100644 (file)
@@ -397,6 +397,7 @@ isc__hash_setvec(const isc_uint16_t *vec) {
 
 static isc_uint32_t fnv_offset_basis;
 static isc_once_t fnv_once = ISC_ONCE_INIT;
+static isc_boolean_t fnv_initialized = ISC_FALSE;
 
 static void
 fnv_initialize(void) {
@@ -408,11 +409,14 @@ fnv_initialize(void) {
        while (fnv_offset_basis == 0) {
                isc_random_get(&fnv_offset_basis);
        }
+
+       fnv_initialized = ISC_TRUE;
 }
 
 const void *
 isc_hash_get_initializer(void) {
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        return (&fnv_offset_basis);
 }
@@ -425,7 +429,8 @@ isc_hash_set_initializer(const void *initializer) {
         * Ensure that fnv_initialize() is not called after
         * isc_hash_set_initializer() is called.
         */
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        fnv_offset_basis = *((const unsigned int *) initializer);
 }
@@ -440,7 +445,9 @@ isc_hash_function(const void *data, size_t length,
        const unsigned char *be;
 
        REQUIRE(length == 0 || data != NULL);
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        hval = ISC_UNLIKELY(previous_hashp != NULL) ?
                *previous_hashp : fnv_offset_basis;
@@ -461,35 +468,35 @@ isc_hash_function(const void *data, size_t length,
         */
 
        if (case_sensitive) {
-               while (bp < be - 4) {
-                       hval ^= (isc_uint32_t) bp[0];
+               while (bp <= be - 4) {
+                       hval ^= bp[0];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[1];
+                       hval ^= bp[1];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[2];
+                       hval ^= bp[2];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[3];
+                       hval ^= bp[3];
                        hval *= 16777619;
                        bp += 4;
                }
                while (bp < be) {
-                       hval ^= (isc_uint32_t) *bp++;
+                       hval ^= *bp++;
                        hval *= 16777619;
                }
        } else {
-               while (bp < be - 4) {
-                       hval ^= (isc_uint32_t) maptolower[bp[0]];
+               while (bp <= be - 4) {
+                       hval ^= maptolower[bp[0]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[1]];
+                       hval ^= maptolower[bp[1]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[2]];
+                       hval ^= maptolower[bp[2]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[3]];
+                       hval ^= maptolower[bp[3]];
                        hval *= 16777619;
                        bp += 4;
                }
                while (bp < be) {
-                       hval ^= (isc_uint32_t) maptolower[*bp++];
+                       hval ^= maptolower[*bp++];
                        hval *= 16777619;
                }
        }
@@ -507,7 +514,9 @@ isc_hash_function_reverse(const void *data, size_t length,
        const unsigned char *be;
 
        REQUIRE(length == 0 || data != NULL);
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        hval = ISC_UNLIKELY(previous_hashp != NULL) ?
                *previous_hashp : fnv_offset_basis;
@@ -530,33 +539,33 @@ isc_hash_function_reverse(const void *data, size_t length,
        if (case_sensitive) {
                while (be >= bp + 4) {
                        be -= 4;
-                       hval ^= (isc_uint32_t) be[3];
+                       hval ^= be[3];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[2];
+                       hval ^= be[2];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[1];
+                       hval ^= be[1];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[0];
+                       hval ^= be[0];
                        hval *= 16777619;
                }
                while (--be >= bp) {
-                       hval ^= (isc_uint32_t) *be;
+                       hval ^= *be;
                        hval *= 16777619;
                }
        } else {
                while (be >= bp + 4) {
                        be -= 4;
-                       hval ^= (isc_uint32_t) maptolower[be[3]];
+                       hval ^= maptolower[be[3]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[2]];
+                       hval ^= maptolower[be[2]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[1]];
+                       hval ^= maptolower[be[1]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[0]];
+                       hval ^= maptolower[be[0]];
                        hval *= 16777619;
                }
                while (--be >= bp) {
-                       hval ^= (isc_uint32_t) maptolower[*be];
+                       hval ^= maptolower[*be];
                        hval *= 16777619;
                }
        }
index e904a01161d15b1f1f270cf6f0171255f2d1788e..c0aeec88f67ff15852bb5232dd74e94a7172b694 100644 (file)
  * To make many functions be inline macros (via \#define) define this.
  * If it is undefined, a function will be used.
  */
-/* #define ISC_BUFFER_USEINLINE */
+#define ISC_BUFFER_USEINLINE 1
 
 ISC_LANG_BEGINDECLS
 
@@ -877,8 +877,8 @@ ISC_LANG_ENDDECLS
 #define ISC__BUFFER_PUTMEM(_b, _base, _length) \
        do { \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, _length) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, _length) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= (unsigned int) _length); \
@@ -892,8 +892,8 @@ ISC_LANG_ENDDECLS
                unsigned char *_cp; \
                _length = strlen(_source); \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, _length) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, _length) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= (unsigned int) _length); \
@@ -905,67 +905,71 @@ ISC_LANG_ENDDECLS
 #define ISC__BUFFER_PUTUINT8(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint8_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, 1) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, 1) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= 1U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used++; \
-               _cp[0] = _val2 & 0x00ff; \
+               _cp[0] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT16(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint16_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, 2) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, 2) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= 2U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 2; \
-               _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
-               _cp[1] = (unsigned char)(_val2 & 0x00ffU); \
+               _cp[0] = _val2 >> 8; \
+               _cp[1] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT24(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint32_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, 3) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, 3) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= 3U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 3; \
-               _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
-               _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
-               _cp[2] = (unsigned char)(_val2 & 0x00ffU); \
+               _cp[0] = _val2 >> 16; \
+               _cp[1] = _val2 >> 8; \
+               _cp[2] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT32(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint32_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
-                       isc_buffer_t *tmpbuf = _b; \
-                       REQUIRE(isc_buffer_reserve(&tmpbuf, 4) \
+                       isc_buffer_t *_tmp = _b; \
+                       REQUIRE(isc_buffer_reserve(&_tmp, 4) \
                                == ISC_R_SUCCESS); \
                } \
                REQUIRE(isc_buffer_availablelength(_b) >= 4U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 4; \
-               _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
-               _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
-               _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
-               _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
+               _cp[0] = _val2 >> 24; \
+               _cp[1] = _val2 >> 16; \
+               _cp[2] = _val2 >> 8; \
+               _cp[3] = _val2; \
        } while (0)
 
 #if defined(ISC_BUFFER_USEINLINE)
index d8bedc4a470ec3c1fa01bf26566ad5004d6a9a8a..2926ed141a5c4bed95c67e89e072e2ebc8ac13c8 100644 (file)
 #define ISC_MSG_POSTLOCK       1207 /*%< "postlock" */
 #define ISC_MSG_PREUNLOCK      1208 /*%< "preunlock" */
 #define ISC_MSG_POSTUNLOCK     1209 /*%< "postunlock" */
+#define ISC_MSG_PRINTLOCK2     1210 /*%< "rwlock %p thread %lu ..." w/ atomic */
 
 #define ISC_MSG_UNKNOWNFAMILY  1301 /*%< "unknown address family: %d" */
 
index 9f6ee258a5f5729b347e11954aa6923f64b90a73..bda751eccc1fbbe8b09ea303202bfbc4db44404d 100644 (file)
@@ -200,14 +200,19 @@ struct isc__mempool {
 #define DELETE_TRACE(a, b, c, d, e)
 #define ISC_MEMFUNC_SCOPE
 #else
+#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE|ISC_MEM_DEBUGRECORD)
 #define ADD_TRACE(a, b, c, d, e) \
        do { \
-               if ((isc_mem_debugging & (ISC_MEM_DEBUGTRACE | \
-                                         ISC_MEM_DEBUGRECORD)) != 0 && \
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
                     b != NULL) \
                         add_trace_entry(a, b, c, d, e); \
        } while (0)
-#define DELETE_TRACE(a, b, c, d, e)    delete_trace_entry(a, b, c, d, e)
+#define DELETE_TRACE(a, b, c, d, e)                                    \
+       do {                                                            \
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 &&       \
+                   b != NULL)                                          \
+                       delete_trace_entry(a, b, c, d, e);              \
+       } while(0)
 
 static void
 print_active(isc__mem_t *ctx, FILE *out);
@@ -1553,9 +1558,7 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
        if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0) && (si != NULL))
                mem_getstats(ctx, si[-1].u.size);
 
-#if ISC_MEM_TRACKLINES
        ADD_TRACE(ctx, si, si[-1].u.size, file, line);
-#endif
        if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
            !ctx->is_overmem) {
                ctx->is_overmem = ISC_TRUE;
@@ -2078,7 +2081,7 @@ isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
                UNLOCK(mpctx->lock);
 
 #if ISC_MEM_TRACKLINES
-       if (item != NULL) {
+       if (((isc_mem_debugging & TRACE_OR_RECORD) != 0) && item != NULL) {
                MCTXLOCK(mctx, &mctx->lock);
                ADD_TRACE(mctx, item, mpctx->size, file, line);
                MCTXUNLOCK(mctx, &mctx->lock);
@@ -2107,9 +2110,11 @@ isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) {
        mpctx->allocated--;
 
 #if ISC_MEM_TRACKLINES
-       MCTXLOCK(mctx, &mctx->lock);
-       DELETE_TRACE(mctx, mem, mpctx->size, file, line);
-       MCTXUNLOCK(mctx, &mctx->lock);
+       if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
+               MCTXLOCK(mctx, &mctx->lock);
+               DELETE_TRACE(mctx, mem, mpctx->size, file, line);
+               MCTXUNLOCK(mctx, &mctx->lock);
+       }
 #endif /* ISC_MEM_TRACKLINES */
 
        /*
@@ -2333,17 +2338,19 @@ isc_mem_checkdestroyed(FILE *file) {
        RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
 
        LOCK(&contextslock);
-       if (!ISC_LIST_EMPTY(contexts))  {
+       if (!ISC_LIST_EMPTY(contexts)) {
 #if ISC_MEM_TRACKLINES
-               isc__mem_t *ctx;
-
-               for (ctx = ISC_LIST_HEAD(contexts);
-                    ctx != NULL;
-                    ctx = ISC_LIST_NEXT(ctx, link)) {
-                       fprintf(file, "context: %p\n", ctx);
-                       print_active(ctx, file);
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
+                       isc__mem_t *ctx;
+
+                       for (ctx = ISC_LIST_HEAD(contexts);
+                            ctx != NULL;
+                            ctx = ISC_LIST_NEXT(ctx, link)) {
+                               fprintf(file, "context: %p\n", ctx);
+                               print_active(ctx, file);
+                       }
+                       fflush(file);
                }
-               fflush(file);
 #endif
                INSIST(0);
        }
index 3caa865bc8f2e50357738d5d43c64b014d413e8c..d8dd147514d89396827a1d746f4b8f512b1cb09d 100644 (file)
@@ -50,6 +50,24 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
 
 static void
 print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+       fprintf(stderr,
+               isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                              ISC_MSG_PRINTLOCK2,
+                              "rwlock %p thread %lu %s(%s): "
+                              "write_requests=%u, write_completions=%u, "
+                              "cnt_and_flag=0x%x, readers_waiting=%u, "
+                              "write_granted=%u, write_quota=%u\n"),
+               rwl, isc_thread_self(), operation,
+               (type == isc_rwlocktype_read ?
+                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                               ISC_MSG_READ, "read") :
+                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                               ISC_MSG_WRITE, "write")),
+               rwl->write_requests, rwl->write_completions,
+               rwl->cnt_and_flag, rwl->readers_waiting,
+               rwl->write_granted, rwl->write_quota);
+#else
        fprintf(stderr,
                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
                               ISC_MSG_PRINTLOCK,
@@ -66,10 +84,11 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                                ISC_MSG_READING, "reading") :
                 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
                                ISC_MSG_WRITING, "writing")),
-               rwl->active, rwl->granted, rwl->readers_waiting,
-               rwl->writers_waiting);
-}
+               rwl->active, rwl->granted,
+               rwl->readers_waiting, rwl->writers_waiting);
 #endif
+}
+#endif /* ISC_RWLOCK_TRACE */
 
 isc_result_t
 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
index 63f5048efa9850555361a58d1a07bfd28f2480b5..0b763af7c6b54f84cfbd9bfc6008d742db014d44 100644 (file)
@@ -1816,10 +1816,14 @@ static cfg_type_t cfg_type_dns64 = {
 
 static cfg_clausedef_t
 view_clauses[] = {
-       { "acache-cleaning-interval", &cfg_type_uint32, 0 },
-       { "acache-enable", &cfg_type_boolean, 0 },
-       { "additional-from-auth", &cfg_type_boolean, 0 },
-       { "additional-from-cache", &cfg_type_boolean, 0 },
+       { "acache-cleaning-interval", &cfg_type_uint32,
+         CFG_CLAUSEFLAG_OBSOLETE },
+       { "acache-enable", &cfg_type_boolean,
+         CFG_CLAUSEFLAG_OBSOLETE },
+       { "additional-from-auth", &cfg_type_boolean,
+         CFG_CLAUSEFLAG_OBSOLETE },
+       { "additional-from-cache", &cfg_type_boolean,
+         CFG_CLAUSEFLAG_OBSOLETE },
        { "allow-new-zones", &cfg_type_boolean, 0 },
        { "allow-query-cache", &cfg_type_bracketed_aml, 0 },
        { "allow-query-cache-on", &cfg_type_bracketed_aml, 0 },
@@ -1880,7 +1884,8 @@ view_clauses[] = {
        { "lame-ttl", &cfg_type_ttlval, 0 },
        { "nocookie-udp-size", &cfg_type_uint32, 0 },
        { "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
-       { "max-acache-size", &cfg_type_sizenodefault, 0 },
+       { "max-acache-size", &cfg_type_sizenodefault,
+         CFG_CLAUSEFLAG_OBSOLETE },
        { "max-cache-size", &cfg_type_sizeorpercent, 0 },
        { "max-cache-ttl", &cfg_type_uint32, 0 },
        { "max-clients-per-query", &cfg_type_uint32, 0 },
index 948fb639c473820a237fba061294a9ebf0d973fa..b0ea026470cc392c27e5231a8a4f50bf8d04683c 100644 (file)
 ./lib/dns/.gitignore                           X       2012,2013,2016
 ./lib/dns/Atffile                              X       2011
 ./lib/dns/Makefile.in                          MAKE    1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017
-./lib/dns/acache.c                             C       2004,2005,2006,2007,2008,2012,2013,2015,2016
 ./lib/dns/acl.c                                        C       1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2011,2013,2014,2016
 ./lib/dns/adb.c                                        C       1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016
 ./lib/dns/api                                  X       1999,2000,2001,2006,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017
 ./lib/dns/hmac_link.c                          C.NAI   1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016
 ./lib/dns/include/Makefile.in                  MAKE    1998,1999,2000,2001,2004,2007,2012,2016
 ./lib/dns/include/dns/Makefile.in              MAKE    1998,1999,2000,2001,2002,2003,2004,2007,2008,2009,2011,2012,2013,2014,2015,2016,2017
-./lib/dns/include/dns/acache.h                 C       2004,2006,2007,2013,2016
 ./lib/dns/include/dns/acl.h                    C       1999,2000,2001,2002,2004,2005,2006,2007,2009,2011,2013,2014,2016
 ./lib/dns/include/dns/adb.h                    C       1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2011,2013,2014,2015,2016
 ./lib/dns/include/dns/badcache.h               C       2014,2016