a1cf2291a974b55e9ba6aaa6fa97c1caf5367903Tinderbox User * Copyright (C) 2009-2016 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B')
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N')
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * temporary storage for ongoing name resolution with the common DB interfaces.
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * It actually doesn't cache anything. The implementation expects any stored
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * data is released within a short period, and does not care about the
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * scalability in terms of the number of nodes.
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Unlocked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Locked */
a8f061d5c61bbdbe922cbb0adb70ae81770b52cbMark Andrews /* Unlocked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Locked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews/* Copied from rbtdb.c */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic void rdataset_disassociate(dns_rdataset_t *rdataset);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrewsstatic isc_result_t rdataset_first(dns_rdataset_t *rdataset);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic isc_result_t rdataset_next(dns_rdataset_t *rdataset);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic unsigned int rdataset_count(dns_rdataset_t *rdataset);
be2c2c29a88db96bd51f11d671ec207f0b6b0d45Mark Andrewsstatic void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void rdatasetiter_current(dns_rdatasetiter_t *iterator,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic dns_rdatasetitermethods_t rdatasetiter_methods = {
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrewsdns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdns_ecdb_unregister(dns_dbimplementation_t **dbimp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * DB routines
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb));
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
be2c2c29a88db96bd51f11d671ec207f0b6b0d45Mark Andrewsattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdbnode_t *node = (dns_ecdbnode_t *)source;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews INSIST(node->references != 0); /* Catch overflow. */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST_UNLINK(node->rdatasets, header, link);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdetachnode(dns_db_t *db, dns_dbnode_t **nodep) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsfind(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* an 'ephemeral' node is never reused. */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews "isc_mutex_init() failed: %s",
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews result = dns_name_dup(name, mctx, &node->name);
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaramanbind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman rdatasetheader_t *header, dns_rdataset_t *rdataset)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Caller must be holding the node lock.
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman REQUIRE(!dns_rdataset_isassociated(rdataset));
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman raw = (unsigned char *)header + sizeof(*header);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman * Reset iterator state.
93c211afc97e7a072c12ef346581065e4065ff15Evan Huntaddrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman * Sanity check: this implementation does not allow overriding an
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman * existing rdataset of the same type.
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL;
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman result = dns_rdataslab_fromrdataset(rdataset, mctx,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->attributes |= RDATASET_ATTR_NXDOMAIN;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman header->attributes |= RDATASET_ATTR_NEGATIVE;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman bind_rdataset(ecdb, ecdbnode, header, addedrdataset);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaramandeleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman dns_rdatatype_t type, dns_rdatatype_t covers)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaramancreateiterator(dns_db_t *db, unsigned int options,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaramanallrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t));
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.magic = DNS_RDATASETITER_MAGIC;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.methods = &rdatasetiter_methods;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman attachnode(db, node, &iterator->common.node);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *iteratorp = (dns_rdatasetiter_t *)iterator;
static isc_result_t
return (ISC_R_NOMEMORY);
return (result);
return (ISC_R_UNEXPECTED);
return (ISC_R_SUCCESS);
static isc_result_t
if (count == 0) {
return (ISC_R_NOMORE);
count--;
return (ISC_R_SUCCESS);
static isc_result_t
if (count == 0)
return (ISC_R_NOMORE);
count--;
return (ISC_R_SUCCESS);
isc_region_t r;
length--;
raw++;
return (count);
header--;
sizeof(ecdb_rdatasetiter_t));
static isc_result_t
return (ISC_R_NOMORE);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_NOMORE);
return (ISC_R_SUCCESS);