1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews/*
a1cf2291a974b55e9ba6aaa6fa97c1caf5367903Tinderbox User * Copyright (C) 2009-2016 Internet Systems Consortium, Inc. ("ISC")
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews *
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 */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include "config.h"
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
7a272c6b0de3b8c0ad018b9896e287da19c43befAutomatic Updater#include <isc/result.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <isc/util.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <isc/mutex.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <isc/mem.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/db.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/ecdb.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/rdata.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/rdataset.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/rdatasetiter.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <dns/rdataslab.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B')
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define VALID_ECDB(db) ((db) != NULL && \
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews (db)->common.impmagic == ECDB_MAGIC)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
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
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews/*%
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 */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewstypedef struct dns_ecdb {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Unlocked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_db_t common;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mutex_t lock;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Locked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews unsigned int references;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST(struct dns_ecdbnode) nodes;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews} dns_ecdb_t;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
a8f061d5c61bbdbe922cbb0adb70ae81770b52cbMark Andrewstypedef struct dns_ecdbnode {
a8f061d5c61bbdbe922cbb0adb70ae81770b52cbMark Andrews /* Unlocked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews unsigned int magic;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mutex_t lock;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_name_t name;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LINK(struct dns_ecdbnode) link;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* Locked */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST(struct rdatasetheader) rdatasets;
d19fc9d988171a1a7ff87d200b86c9aa657aa3beMark Andrews unsigned int references;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews} dns_ecdbnode_t;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewstypedef struct rdatasetheader {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdatatype_t type;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ttl_t ttl;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_trust_t trust;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdatatype_t covers;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews unsigned int attributes;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LINK(struct rdatasetheader) link;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein} rdatasetheader_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews/* Copied from rbtdb.c */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define RDATASET_ATTR_NXDOMAIN 0x0010
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define RDATASET_ATTR_NEGATIVE 0x0100
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#define NXDOMAIN(header) \
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define NEGATIVE(header) \
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_dbtype_t type,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdataclass_t rdclass,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews unsigned int argc, char *argv[],
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews void *driverarg, dns_db_t **dbp);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
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 Andrews
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic dns_rdatasetmethods_t rdataset_methods = {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt rdataset_disassociate,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_first,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_next,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_current,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_clone,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_count,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* addnoqname */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* getnoqname */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* addclosest */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* getclosest */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* getadditional */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* setadditional */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* putadditional */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdataset_settrust, /* settrust */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* expire */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* clearprefetch */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL, /* setownercase */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews NULL /* getownercase */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews};
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewstypedef struct ecdb_rdatasetiter {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdatasetiter_t common;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetheader_t *current;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews} ecdb_rdatasetiter_t;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
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 Andrews dns_rdataset_t *rdataset);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic dns_rdatasetitermethods_t rdatasetiter_methods = {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetiter_destroy,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetiter_first,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetiter_next,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetiter_current
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews};
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsisc_result_t
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrewsdns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(mctx != NULL);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews REQUIRE(dbimp != NULL && *dbimp == NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsvoid
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdns_ecdb_unregister(dns_dbimplementation_t **dbimp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(dbimp != NULL && *dbimp != NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_db_unregister(dbimp);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews/*%
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * DB routines
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsattach(dns_db_t *source, dns_db_t **targetp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)source;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(targetp != NULL && *targetp == NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews LOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ecdb->references++;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNLOCK(&ecdb->lock);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews *targetp = source;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdestroy_ecdb(dns_ecdb_t **ecdbp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = *ecdbp;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews isc_mem_t *mctx = ecdb->common.mctx;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (dns_name_dynamic(&ecdb->common.origin))
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_name_free(&ecdb->common.origin, mctx);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews DESTROYLOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ecdb->common.impmagic = 0;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ecdb->common.magic = 0;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb));
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews *ecdbp = NULL;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdetach(dns_db_t **dbp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_boolean_t need_destroy = ISC_FALSE;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(dbp != NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ecdb = (dns_ecdb_t *)*dbp;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews LOCK(&ecdb->lock);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews ecdb->references--;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews need_destroy = ISC_TRUE;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNLOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (need_destroy)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews destroy_ecdb(&ecdb);
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews *dbp = NULL;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
be2c2c29a88db96bd51f11d671ec207f0b6b0d45Mark Andrewsattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdbnode_t *node = (dns_ecdbnode_t *)source;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDBNODE(node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(targetp != NULL && *targetp == NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt LOCK(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews INSIST(node->references > 0);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node->references++;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews INSIST(node->references != 0); /* Catch overflow. */
be2c2c29a88db96bd51f11d671ec207f0b6b0d45Mark Andrews UNLOCK(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *targetp = node;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
be2c2c29a88db96bd51f11d671ec207f0b6b0d45Mark Andrewsdestroynode(dns_ecdbnode_t *node) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_t *mctx;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = node->ecdb;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_boolean_t need_destroydb = ISC_FALSE;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews rdatasetheader_t *header;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews mctx = ecdb->common.mctx;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews LOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST_UNLINK(ecdb->nodes, node, link);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews need_destroydb = ISC_TRUE;
b99bfa184bc9375421b5df915eea7dfac6a68a99Evan Hunt UNLOCK(&ecdb->lock);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 dns_name_free(&node->name, mctx);
7a272c6b0de3b8c0ad018b9896e287da19c43befAutomatic Updater
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) {
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews unsigned int headersize;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST_UNLINK(node->rdatasets, header, link);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews headersize =
3f40de5598aaf9fa1aa90d6eb82350152bc66ec8Mark Andrews dns_rdataslab_size((unsigned char *)header,
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews sizeof(*header));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_put(mctx, header, headersize);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews }
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews DESTROYLOCK(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node->magic = 0;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_put(mctx, node, sizeof(*node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (need_destroydb)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews destroy_ecdb(&ecdb);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic void
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsdetachnode(dns_db_t *db, dns_dbnode_t **nodep) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdbnode_t *node;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_boolean_t need_destroy = ISC_FALSE;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(nodep != NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node = (dns_ecdbnode_t *)*nodep;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDBNODE(node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
b454c0319685041db3f3e8fd7671e1b364fd20c5Evan Hunt UNUSED(ecdb); /* in case REQUIRE() is empty */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
7a272c6b0de3b8c0ad018b9896e287da19c43befAutomatic Updater LOCK(&node->lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt INSIST(node->references > 0);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node->references--;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (node->references == 0)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews need_destroy = ISC_TRUE;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNLOCK(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (need_destroy)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews destroynode(node);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews *nodep = NULL;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t
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 *sigrdataset)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews{
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(name);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(version);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(type);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(options);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(now);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(nodep);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(foundname);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(rdataset);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(sigrdataset);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_NOTFOUND);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsstatic isc_result_t
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsfindzonecut(dns_db_t *db, dns_name_t *name,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews unsigned int options, isc_stdtime_t now,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_dbnode_t **nodep, dns_name_t *foundname,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews{
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(name);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(options);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(now);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(nodep);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(foundname);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(rdataset);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(sigrdataset);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_NOTFOUND);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
b454c0319685041db3f3e8fd7671e1b364fd20c5Evan Huntstatic isc_result_t
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_dbnode_t **nodep)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_t *mctx;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_ecdbnode_t *node;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_result_t result;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_ECDB(ecdb));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(nodep != NULL && *nodep == NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNUSED(name);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (create != ISC_TRUE) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /* an 'ephemeral' node is never reused. */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_NOTFOUND);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews }
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews mctx = ecdb->common.mctx;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node = isc_mem_get(mctx, sizeof(*node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (node == NULL)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_NOMEMORY);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews result = isc_mutex_init(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (result != ISC_R_SUCCESS) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews "isc_mutex_init() failed: %s",
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_result_totext(result));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_put(mctx, node, sizeof(*node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_UNEXPECTED);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews }
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews dns_name_init(&node->name, NULL);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews result = dns_name_dup(name, mctx, &node->name);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (result != ISC_R_SUCCESS) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews DESTROYLOCK(&node->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews isc_mem_put(mctx, node, sizeof(*node));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (result);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews }
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node->ecdb= ecdb;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews node->references = 1;
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST_INIT(node->rdatasets);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LINK_INIT(node, link);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews LOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews ISC_LIST_APPEND(ecdb->nodes, node, link);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews UNLOCK(&ecdb->lock);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt node->magic = ECDBNODE_MAGIC;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews *nodep = node;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (ISC_R_SUCCESS);
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman}
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman
caa252e5adf952d8981c7dacd28c5d2296ff5896Evan Huntstatic void
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaramanbind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman rdatasetheader_t *header, dns_rdataset_t *rdataset)
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt unsigned char *raw;
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman /*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Caller must be holding the node lock.
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman */
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman REQUIRE(!dns_rdataset_isassociated(rdataset));
ce376a81fa674d240197628ceb6113a4fa5a1ab3Mukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->methods = &rdataset_methods;
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman rdataset->rdclass = ecdb->common.rdclass;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->type = header->type;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman rdataset->covers = header->covers;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->ttl = header->ttl;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->trust = header->trust;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (NXDOMAIN(header))
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (NEGATIVE(header))
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->private1 = ecdb;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->private2 = node;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman raw = (unsigned char *)header + sizeof(*header);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman rdataset->private3 = raw;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman rdataset->count = 0;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman /*
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman * Reset iterator state.
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt */
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt rdataset->privateuint4 = 0;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman rdataset->private5 = NULL;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt INSIST(node->references > 0);
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt node->references++;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt}
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt
93c211afc97e7a072c12ef346581065e4065ff15Evan Huntstatic isc_result_t
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,
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt dns_rdataset_t *addedrdataset)
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt{
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt isc_region_t r;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt isc_result_t result = ISC_R_SUCCESS;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman isc_mem_t *mctx;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt rdatasetheader_t *header;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt REQUIRE(VALID_ECDB(ecdb));
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt REQUIRE(VALID_ECDBNODE(ecdbnode));
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(version);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(now);
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman UNUSED(options);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman mctx = ecdb->common.mctx;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman LOCK(&ecdbnode->lock);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman /*
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman * Sanity check: this implementation does not allow overriding an
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman * existing rdataset of the same type.
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL;
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman header = ISC_LIST_NEXT(header, link)) {
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman INSIST(header->type != rdataset->type ||
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->covers != rdataset->covers);
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman }
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman result = dns_rdataslab_fromrdataset(rdataset, mctx,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman &r, sizeof(rdatasetheader_t));
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (result != ISC_R_SUCCESS)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman goto unlock;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header = (rdatasetheader_t *)r.base;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->type = rdataset->type;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt header->ttl = rdataset->ttl;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->trust = rdataset->trust;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->covers = rdataset->covers;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman header->attributes = 0;
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;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman ISC_LINK_INIT(header, link);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (addedrdataset == NULL)
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman goto unlock;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman bind_rdataset(ecdb, ecdbnode, header, addedrdataset);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman unlock:
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNLOCK(&ecdbnode->lock);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman return (result);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman}
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaramanstatic isc_result_t
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 Sivaraman{
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman UNUSED(db);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(node);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman UNUSED(version);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(type);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman UNUSED(covers);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_R_NOTIMPLEMENTED);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman}
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaramanstatic isc_result_t
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaramancreateiterator(dns_db_t *db, unsigned int options,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman dns_dbiterator_t **iteratorp)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman{
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(db);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(options);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman UNUSED(iteratorp);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman return (ISC_R_NOTIMPLEMENTED);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman}
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaramanstatic isc_result_t
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{
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman isc_mem_t *mctx;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman ecdb_rdatasetiter_t *iterator;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman REQUIRE(VALID_ECDB(ecdb));
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman REQUIRE(VALID_ECDBNODE(ecdbnode));
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman mctx = ecdb->common.mctx;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t));
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman if (iterator == NULL)
614ce1b65ff9ef158aa5a19a9acf2edb99170963Mukund Sivaraman return (ISC_R_NOMEMORY);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.magic = DNS_RDATASETITER_MAGIC;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.methods = &rdatasetiter_methods;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.db = db;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.node = NULL;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman attachnode(db, node, &iterator->common.node);
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt iterator->common.version = version;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman iterator->common.now = now;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *iteratorp = (dns_rdatasetiter_t *)iterator;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_R_SUCCESS);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman}
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaramanstatic dns_dbmethods_t ecdb_methods = {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman attach,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman detach,
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* beginload */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* endload */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* serialize */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* dump */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* currentversion */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* newversion */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* attachversion */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* closeversion */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman findnode,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman find,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman findzonecut,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman attachnode,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman detachnode,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* expirenode */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* printnode */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman createiterator, /* createiterator */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* findrdataset */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman allrdatasets,
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman addrdataset,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* subtractrdataset */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman deleterdataset,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* issecure */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* nodecount */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* ispersistent */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman NULL, /* overmem */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* settask */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* getoriginnode */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* transfernode */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* getnsec3parameters */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* findnsec3node */
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman NULL, /* setsigningtime */
NULL, /* getsigningtime */
NULL, /* resigned */
NULL, /* isdnssec */
NULL, /* getrrsetstats */
NULL, /* rpz_attach */
NULL, /* rpz_ready */
NULL, /* findnodeext */
NULL, /* findext */
NULL, /* setcachestats */
NULL, /* hashsize */
NULL, /* nodefullname */
NULL /* getsize */
};
static isc_result_t
dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
void *driverarg, dns_db_t **dbp)
{
dns_ecdb_t *ecdb;
isc_result_t result;
REQUIRE(mctx != NULL);
REQUIRE(origin == dns_rootname);
REQUIRE(type == dns_dbtype_cache);
REQUIRE(dbp != NULL && *dbp == NULL);
UNUSED(argc);
UNUSED(argv);
UNUSED(driverarg);
ecdb = isc_mem_get(mctx, sizeof(*ecdb));
if (ecdb == NULL)
return (ISC_R_NOMEMORY);
ecdb->common.attributes = DNS_DBATTR_CACHE;
ecdb->common.rdclass = rdclass;
ecdb->common.methods = &ecdb_methods;
dns_name_init(&ecdb->common.origin, NULL);
result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, ecdb, sizeof(*ecdb));
return (result);
}
result = isc_mutex_init(&ecdb->lock);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_mutex_init() failed: %s",
isc_result_totext(result));
if (dns_name_dynamic(&ecdb->common.origin))
dns_name_free(&ecdb->common.origin, mctx);
isc_mem_put(mctx, ecdb, sizeof(*ecdb));
return (ISC_R_UNEXPECTED);
}
ecdb->references = 1;
ISC_LIST_INIT(ecdb->nodes);
ecdb->common.mctx = NULL;
isc_mem_attach(mctx, &ecdb->common.mctx);
ecdb->common.impmagic = ECDB_MAGIC;
ecdb->common.magic = DNS_DB_MAGIC;
*dbp = (dns_db_t *)ecdb;
return (ISC_R_SUCCESS);
}
/*%
* Rdataset Methods
*/
static void
rdataset_disassociate(dns_rdataset_t *rdataset) {
dns_db_t *db = rdataset->private1;
dns_dbnode_t *node = rdataset->private2;
dns_db_detachnode(db, &node);
}
static isc_result_t
rdataset_first(dns_rdataset_t *rdataset) {
unsigned char *raw = rdataset->private3;
unsigned int count;
count = raw[0] * 256 + raw[1];
if (count == 0) {
rdataset->private5 = NULL;
return (ISC_R_NOMORE);
}
#if DNS_RDATASET_FIXED
raw += 2 + (4 * count);
#else
raw += 2;
#endif
/*
* The privateuint4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
* it.
*/
count--;
rdataset->privateuint4 = count;
rdataset->private5 = raw;
return (ISC_R_SUCCESS);
}
static isc_result_t
rdataset_next(dns_rdataset_t *rdataset) {
unsigned int count;
unsigned int length;
unsigned char *raw;
count = rdataset->privateuint4;
if (count == 0)
return (ISC_R_NOMORE);
count--;
rdataset->privateuint4 = count;
raw = rdataset->private5;
length = raw[0] * 256 + raw[1];
#if DNS_RDATASET_FIXED
raw += length + 4;
#else
raw += length + 2;
#endif
rdataset->private5 = raw;
return (ISC_R_SUCCESS);
}
static void
rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
unsigned char *raw = rdataset->private5;
isc_region_t r;
unsigned int length;
unsigned int flags = 0;
REQUIRE(raw != NULL);
length = raw[0] * 256 + raw[1];
#if DNS_RDATASET_FIXED
raw += 4;
#else
raw += 2;
#endif
if (rdataset->type == dns_rdatatype_rrsig) {
if (*raw & DNS_RDATASLAB_OFFLINE)
flags |= DNS_RDATA_OFFLINE;
length--;
raw++;
}
r.length = length;
r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
rdata->flags |= flags;
}
static void
rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
dns_db_t *db = source->private1;
dns_dbnode_t *node = source->private2;
dns_dbnode_t *cloned_node = NULL;
attachnode(db, node, &cloned_node);
*target = *source;
/*
* Reset iterator state.
*/
target->privateuint4 = 0;
target->private5 = NULL;
}
static unsigned int
rdataset_count(dns_rdataset_t *rdataset) {
unsigned char *raw = rdataset->private3;
unsigned int count;
count = raw[0] * 256 + raw[1];
return (count);
}
static void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
rdatasetheader_t *header = rdataset->private3;
header--;
header->trust = rdataset->trust = trust;
}
/*
* Rdataset Iterator Methods
*/
static void
rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
isc_mem_t *mctx;
union {
dns_rdatasetiter_t *rdatasetiterator;
ecdb_rdatasetiter_t *ecdbiterator;
} u;
REQUIRE(iteratorp != NULL);
REQUIRE(DNS_RDATASETITER_VALID(*iteratorp));
u.rdatasetiterator = *iteratorp;
mctx = u.ecdbiterator->common.db->mctx;
u.ecdbiterator->common.magic = 0;
dns_db_detachnode(u.ecdbiterator->common.db,
&u.ecdbiterator->common.node);
isc_mem_put(mctx, u.ecdbiterator,
sizeof(ecdb_rdatasetiter_t));
*iteratorp = NULL;
}
static isc_result_t
rdatasetiter_first(dns_rdatasetiter_t *iterator) {
ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node;
REQUIRE(DNS_RDATASETITER_VALID(iterator));
if (ISC_LIST_EMPTY(ecdbnode->rdatasets))
return (ISC_R_NOMORE);
ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets);
return (ISC_R_SUCCESS);
}
static isc_result_t
rdatasetiter_next(dns_rdatasetiter_t *iterator) {
ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
REQUIRE(DNS_RDATASETITER_VALID(iterator));
ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link);
if (ecdbiterator->current == NULL)
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static void
rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
dns_ecdb_t *ecdb;
ecdb = (dns_ecdb_t *)iterator->db;
REQUIRE(VALID_ECDB(ecdb));
bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset);
}