1135446Strhodes/* 2234010Sdougb * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. 4135446Strhodes * 5174187Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18234010Sdougb/* $Id$ */ 19135446Strhodes 20170222Sdougb/*! \file */ 21170222Sdougb 22135446Strhodes#include <config.h> 23135446Strhodes 24135446Strhodes#include <string.h> 25135446Strhodes 26135446Strhodes#include <isc/buffer.h> 27135446Strhodes#include <isc/lex.h> 28135446Strhodes#include <isc/log.h> 29135446Strhodes#include <isc/magic.h> 30135446Strhodes#include <isc/mem.h> 31135446Strhodes#include <isc/once.h> 32135446Strhodes#include <isc/print.h> 33135446Strhodes#include <isc/region.h> 34135446Strhodes#include <isc/util.h> 35135446Strhodes 36135446Strhodes#include <dns/callbacks.h> 37135446Strhodes#include <dns/db.h> 38135446Strhodes#include <dns/dbiterator.h> 39135446Strhodes#include <dns/fixedname.h> 40135446Strhodes#include <dns/log.h> 41135446Strhodes#include <dns/rdata.h> 42135446Strhodes#include <dns/rdatalist.h> 43135446Strhodes#include <dns/rdataset.h> 44135446Strhodes#include <dns/rdatasetiter.h> 45135446Strhodes#include <dns/rdatatype.h> 46135446Strhodes#include <dns/result.h> 47135446Strhodes#include <dns/sdb.h> 48135446Strhodes#include <dns/types.h> 49135446Strhodes 50135446Strhodes#include "rdatalist_p.h" 51135446Strhodes 52135446Strhodesstruct dns_sdbimplementation { 53135446Strhodes const dns_sdbmethods_t *methods; 54135446Strhodes void *driverdata; 55135446Strhodes unsigned int flags; 56135446Strhodes isc_mem_t *mctx; 57135446Strhodes isc_mutex_t driverlock; 58135446Strhodes dns_dbimplementation_t *dbimp; 59135446Strhodes}; 60135446Strhodes 61135446Strhodesstruct dns_sdb { 62135446Strhodes /* Unlocked */ 63135446Strhodes dns_db_t common; 64135446Strhodes char *zone; 65135446Strhodes dns_sdbimplementation_t *implementation; 66135446Strhodes void *dbdata; 67135446Strhodes isc_mutex_t lock; 68135446Strhodes /* Locked */ 69135446Strhodes unsigned int references; 70135446Strhodes}; 71135446Strhodes 72135446Strhodesstruct dns_sdblookup { 73135446Strhodes /* Unlocked */ 74135446Strhodes unsigned int magic; 75135446Strhodes dns_sdb_t *sdb; 76135446Strhodes ISC_LIST(dns_rdatalist_t) lists; 77135446Strhodes ISC_LIST(isc_buffer_t) buffers; 78135446Strhodes dns_name_t *name; 79135446Strhodes ISC_LINK(dns_sdblookup_t) link; 80135446Strhodes isc_mutex_t lock; 81135446Strhodes dns_rdatacallbacks_t callbacks; 82135446Strhodes /* Locked */ 83135446Strhodes unsigned int references; 84135446Strhodes}; 85135446Strhodes 86135446Strhodestypedef struct dns_sdblookup dns_sdbnode_t; 87135446Strhodes 88135446Strhodesstruct dns_sdballnodes { 89135446Strhodes dns_dbiterator_t common; 90135446Strhodes ISC_LIST(dns_sdbnode_t) nodelist; 91135446Strhodes dns_sdbnode_t *current; 92135446Strhodes dns_sdbnode_t *origin; 93135446Strhodes}; 94135446Strhodes 95135446Strhodestypedef dns_sdballnodes_t sdb_dbiterator_t; 96135446Strhodes 97135446Strhodestypedef struct sdb_rdatasetiter { 98135446Strhodes dns_rdatasetiter_t common; 99135446Strhodes dns_rdatalist_t *current; 100135446Strhodes} sdb_rdatasetiter_t; 101135446Strhodes 102135446Strhodes#define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-') 103135446Strhodes 104170222Sdougb/*% 105135446Strhodes * Note that "impmagic" is not the first four bytes of the struct, so 106135446Strhodes * ISC_MAGIC_VALID cannot be used. 107135446Strhodes */ 108135446Strhodes#define VALID_SDB(sdb) ((sdb) != NULL && \ 109135446Strhodes (sdb)->common.impmagic == SDB_MAGIC) 110135446Strhodes 111135446Strhodes#define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L') 112135446Strhodes#define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC) 113135446Strhodes#define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn) 114135446Strhodes 115170222Sdougb/* These values are taken from RFC1537 */ 116135446Strhodes#define SDB_DEFAULT_REFRESH (60 * 60 * 8) 117135446Strhodes#define SDB_DEFAULT_RETRY (60 * 60 * 2) 118135446Strhodes#define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7) 119135446Strhodes#define SDB_DEFAULT_MINIMUM (60 * 60 * 24) 120135446Strhodes 121135446Strhodes/* This is a reasonable value */ 122135446Strhodes#define SDB_DEFAULT_TTL (60 * 60 * 24) 123135446Strhodes 124174187Sdougb#ifdef __COVERITY__ 125174187Sdougb#define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock) 126174187Sdougb#define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock) 127174187Sdougb#else 128135446Strhodes#define MAYBE_LOCK(sdb) \ 129135446Strhodes do { \ 130135446Strhodes unsigned int flags = sdb->implementation->flags; \ 131135446Strhodes if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ 132135446Strhodes LOCK(&sdb->implementation->driverlock); \ 133135446Strhodes } while (0) 134135446Strhodes 135135446Strhodes#define MAYBE_UNLOCK(sdb) \ 136135446Strhodes do { \ 137135446Strhodes unsigned int flags = sdb->implementation->flags; \ 138135446Strhodes if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ 139135446Strhodes UNLOCK(&sdb->implementation->driverlock); \ 140135446Strhodes } while (0) 141174187Sdougb#endif 142135446Strhodes 143135446Strhodesstatic int dummy; 144135446Strhodes 145135446Strhodesstatic isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, 146135446Strhodes dns_dbtype_t type, dns_rdataclass_t rdclass, 147135446Strhodes unsigned int argc, char *argv[], 148135446Strhodes void *driverarg, dns_db_t **dbp); 149135446Strhodes 150135446Strhodesstatic isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, 151135446Strhodes dns_dbversion_t *version, 152135446Strhodes dns_rdatatype_t type, dns_rdatatype_t covers, 153135446Strhodes isc_stdtime_t now, dns_rdataset_t *rdataset, 154135446Strhodes dns_rdataset_t *sigrdataset); 155135446Strhodes 156135446Strhodesstatic isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep); 157135446Strhodes 158135446Strhodesstatic void destroynode(dns_sdbnode_t *node); 159135446Strhodes 160135446Strhodesstatic void detachnode(dns_db_t *db, dns_dbnode_t **targetp); 161135446Strhodes 162135446Strhodes 163135446Strhodesstatic void list_tordataset(dns_rdatalist_t *rdatalist, 164135446Strhodes dns_db_t *db, dns_dbnode_t *node, 165135446Strhodes dns_rdataset_t *rdataset); 166135446Strhodes 167135446Strhodesstatic void dbiterator_destroy(dns_dbiterator_t **iteratorp); 168135446Strhodesstatic isc_result_t dbiterator_first(dns_dbiterator_t *iterator); 169135446Strhodesstatic isc_result_t dbiterator_last(dns_dbiterator_t *iterator); 170135446Strhodesstatic isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, 171135446Strhodes dns_name_t *name); 172135446Strhodesstatic isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); 173135446Strhodesstatic isc_result_t dbiterator_next(dns_dbiterator_t *iterator); 174135446Strhodesstatic isc_result_t dbiterator_current(dns_dbiterator_t *iterator, 175135446Strhodes dns_dbnode_t **nodep, 176135446Strhodes dns_name_t *name); 177135446Strhodesstatic isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); 178135446Strhodesstatic isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, 179135446Strhodes dns_name_t *name); 180135446Strhodes 181135446Strhodesstatic dns_dbiteratormethods_t dbiterator_methods = { 182135446Strhodes dbiterator_destroy, 183135446Strhodes dbiterator_first, 184135446Strhodes dbiterator_last, 185135446Strhodes dbiterator_seek, 186135446Strhodes dbiterator_prev, 187135446Strhodes dbiterator_next, 188135446Strhodes dbiterator_current, 189135446Strhodes dbiterator_pause, 190135446Strhodes dbiterator_origin 191135446Strhodes}; 192135446Strhodes 193135446Strhodesstatic void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); 194135446Strhodesstatic isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); 195135446Strhodesstatic isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); 196135446Strhodesstatic void rdatasetiter_current(dns_rdatasetiter_t *iterator, 197135446Strhodes dns_rdataset_t *rdataset); 198135446Strhodes 199135446Strhodesstatic dns_rdatasetitermethods_t rdatasetiter_methods = { 200135446Strhodes rdatasetiter_destroy, 201135446Strhodes rdatasetiter_first, 202135446Strhodes rdatasetiter_next, 203135446Strhodes rdatasetiter_current 204135446Strhodes}; 205135446Strhodes 206135446Strhodes/* 207135446Strhodes * Functions used by implementors of simple databases 208135446Strhodes */ 209135446Strhodesisc_result_t 210135446Strhodesdns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, 211135446Strhodes void *driverdata, unsigned int flags, isc_mem_t *mctx, 212135446Strhodes dns_sdbimplementation_t **sdbimp) 213135446Strhodes{ 214135446Strhodes dns_sdbimplementation_t *imp; 215135446Strhodes isc_result_t result; 216135446Strhodes 217135446Strhodes REQUIRE(drivername != NULL); 218135446Strhodes REQUIRE(methods != NULL); 219236374Sdougb REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL); 220135446Strhodes REQUIRE(mctx != NULL); 221135446Strhodes REQUIRE(sdbimp != NULL && *sdbimp == NULL); 222135446Strhodes REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | 223135446Strhodes DNS_SDBFLAG_RELATIVERDATA | 224236374Sdougb DNS_SDBFLAG_THREADSAFE| 225236374Sdougb DNS_SDBFLAG_DNS64)) == 0); 226135446Strhodes 227135446Strhodes imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); 228135446Strhodes if (imp == NULL) 229135446Strhodes return (ISC_R_NOMEMORY); 230135446Strhodes imp->methods = methods; 231135446Strhodes imp->driverdata = driverdata; 232135446Strhodes imp->flags = flags; 233135446Strhodes imp->mctx = NULL; 234135446Strhodes isc_mem_attach(mctx, &imp->mctx); 235135446Strhodes result = isc_mutex_init(&imp->driverlock); 236170222Sdougb if (result != ISC_R_SUCCESS) 237135446Strhodes goto cleanup_mctx; 238135446Strhodes 239135446Strhodes imp->dbimp = NULL; 240135446Strhodes result = dns_db_register(drivername, dns_sdb_create, imp, mctx, 241135446Strhodes &imp->dbimp); 242135446Strhodes if (result != ISC_R_SUCCESS) 243135446Strhodes goto cleanup_mutex; 244135446Strhodes *sdbimp = imp; 245135446Strhodes 246135446Strhodes return (ISC_R_SUCCESS); 247135446Strhodes 248135446Strhodes cleanup_mutex: 249135446Strhodes DESTROYLOCK(&imp->driverlock); 250135446Strhodes cleanup_mctx: 251135446Strhodes isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); 252135446Strhodes return (result); 253135446Strhodes} 254135446Strhodes 255135446Strhodesvoid 256135446Strhodesdns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { 257135446Strhodes dns_sdbimplementation_t *imp; 258135446Strhodes isc_mem_t *mctx; 259135446Strhodes 260135446Strhodes REQUIRE(sdbimp != NULL && *sdbimp != NULL); 261135446Strhodes 262135446Strhodes imp = *sdbimp; 263135446Strhodes dns_db_unregister(&imp->dbimp); 264135446Strhodes DESTROYLOCK(&imp->driverlock); 265135446Strhodes 266135446Strhodes mctx = imp->mctx; 267135446Strhodes isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); 268135446Strhodes isc_mem_detach(&mctx); 269135446Strhodes 270135446Strhodes *sdbimp = NULL; 271135446Strhodes} 272135446Strhodes 273135446Strhodesstatic inline unsigned int 274135446Strhodesinitial_size(unsigned int len) { 275135446Strhodes unsigned int size; 276170222Sdougb 277170222Sdougb for (size = 1024; size < (64 * 1024); size *= 2) 278135446Strhodes if (len < size) 279135446Strhodes return (size); 280170222Sdougb return (65535); 281135446Strhodes} 282135446Strhodes 283135446Strhodesisc_result_t 284236374Sdougbdns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, 285236374Sdougb dns_ttl_t ttl, const unsigned char *rdatap, 286236374Sdougb unsigned int rdlen) 287135446Strhodes{ 288135446Strhodes dns_rdatalist_t *rdatalist; 289135446Strhodes dns_rdata_t *rdata; 290135446Strhodes isc_buffer_t *rdatabuf = NULL; 291135446Strhodes isc_result_t result; 292135446Strhodes isc_mem_t *mctx; 293135446Strhodes isc_region_t region; 294135446Strhodes 295135446Strhodes mctx = lookup->sdb->common.mctx; 296135446Strhodes 297135446Strhodes rdatalist = ISC_LIST_HEAD(lookup->lists); 298135446Strhodes while (rdatalist != NULL) { 299135446Strhodes if (rdatalist->type == typeval) 300135446Strhodes break; 301135446Strhodes rdatalist = ISC_LIST_NEXT(rdatalist, link); 302135446Strhodes } 303135446Strhodes 304135446Strhodes if (rdatalist == NULL) { 305135446Strhodes rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); 306135446Strhodes if (rdatalist == NULL) 307135446Strhodes return (ISC_R_NOMEMORY); 308135446Strhodes rdatalist->rdclass = lookup->sdb->common.rdclass; 309135446Strhodes rdatalist->type = typeval; 310135446Strhodes rdatalist->covers = 0; 311135446Strhodes rdatalist->ttl = ttl; 312135446Strhodes ISC_LIST_INIT(rdatalist->rdata); 313135446Strhodes ISC_LINK_INIT(rdatalist, link); 314135446Strhodes ISC_LIST_APPEND(lookup->lists, rdatalist, link); 315186462Sdougb } else 316135446Strhodes if (rdatalist->ttl != ttl) 317135446Strhodes return (DNS_R_BADTTL); 318135446Strhodes 319135446Strhodes rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); 320135446Strhodes if (rdata == NULL) 321135446Strhodes return (ISC_R_NOMEMORY); 322135446Strhodes 323135446Strhodes result = isc_buffer_allocate(mctx, &rdatabuf, rdlen); 324135446Strhodes if (result != ISC_R_SUCCESS) 325135446Strhodes goto failure; 326135446Strhodes DE_CONST(rdatap, region.base); 327135446Strhodes region.length = rdlen; 328135446Strhodes isc_buffer_copyregion(rdatabuf, ®ion); 329135446Strhodes isc_buffer_usedregion(rdatabuf, ®ion); 330135446Strhodes dns_rdata_init(rdata); 331135446Strhodes dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type, 332135446Strhodes ®ion); 333135446Strhodes ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 334135446Strhodes ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); 335135446Strhodes rdata = NULL; 336135446Strhodes 337135446Strhodes failure: 338135446Strhodes if (rdata != NULL) 339135446Strhodes isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); 340135446Strhodes return (result); 341135446Strhodes} 342135446Strhodes 343135446Strhodesisc_result_t 344135446Strhodesdns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, 345135446Strhodes const char *data) 346135446Strhodes{ 347135446Strhodes unsigned int datalen; 348135446Strhodes dns_rdatatype_t typeval; 349135446Strhodes isc_textregion_t r; 350135446Strhodes isc_lex_t *lex = NULL; 351135446Strhodes isc_result_t result; 352135446Strhodes unsigned char *p = NULL; 353135446Strhodes unsigned int size = 0; /* Init to suppress compiler warning */ 354135446Strhodes isc_mem_t *mctx; 355135446Strhodes dns_sdbimplementation_t *imp; 356135446Strhodes dns_name_t *origin; 357135446Strhodes isc_buffer_t b; 358135446Strhodes isc_buffer_t rb; 359135446Strhodes 360135446Strhodes REQUIRE(VALID_SDBLOOKUP(lookup)); 361135446Strhodes REQUIRE(type != NULL); 362135446Strhodes REQUIRE(data != NULL); 363135446Strhodes 364135446Strhodes mctx = lookup->sdb->common.mctx; 365135446Strhodes 366135446Strhodes DE_CONST(type, r.base); 367135446Strhodes r.length = strlen(type); 368135446Strhodes result = dns_rdatatype_fromtext(&typeval, &r); 369135446Strhodes if (result != ISC_R_SUCCESS) 370135446Strhodes return (result); 371135446Strhodes 372135446Strhodes imp = lookup->sdb->implementation; 373135446Strhodes if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) 374135446Strhodes origin = &lookup->sdb->common.origin; 375135446Strhodes else 376135446Strhodes origin = dns_rootname; 377135446Strhodes 378135446Strhodes result = isc_lex_create(mctx, 64, &lex); 379135446Strhodes if (result != ISC_R_SUCCESS) 380135446Strhodes goto failure; 381135446Strhodes 382135446Strhodes datalen = strlen(data); 383135446Strhodes size = initial_size(datalen); 384186462Sdougb do { 385254402Serwin isc_buffer_constinit(&b, data, datalen); 386135446Strhodes isc_buffer_add(&b, datalen); 387135446Strhodes result = isc_lex_openbuffer(lex, &b); 388135446Strhodes if (result != ISC_R_SUCCESS) 389135446Strhodes goto failure; 390135446Strhodes 391170222Sdougb if (size >= 65535) 392170222Sdougb size = 65535; 393135446Strhodes p = isc_mem_get(mctx, size); 394135446Strhodes if (p == NULL) { 395135446Strhodes result = ISC_R_NOMEMORY; 396135446Strhodes goto failure; 397135446Strhodes } 398135446Strhodes isc_buffer_init(&rb, p, size); 399135446Strhodes result = dns_rdata_fromtext(NULL, 400135446Strhodes lookup->sdb->common.rdclass, 401135446Strhodes typeval, lex, 402135446Strhodes origin, 0, 403135446Strhodes mctx, &rb, 404135446Strhodes &lookup->callbacks); 405135446Strhodes if (result != ISC_R_NOSPACE) 406135446Strhodes break; 407135446Strhodes 408170222Sdougb /* 409170222Sdougb * Is the RR too big? 410170222Sdougb */ 411170222Sdougb if (size >= 65535) 412170222Sdougb break; 413135446Strhodes isc_mem_put(mctx, p, size); 414135446Strhodes p = NULL; 415135446Strhodes size *= 2; 416135446Strhodes } while (result == ISC_R_NOSPACE); 417135446Strhodes 418135446Strhodes if (result != ISC_R_SUCCESS) 419135446Strhodes goto failure; 420135446Strhodes 421135446Strhodes result = dns_sdb_putrdata(lookup, typeval, ttl, 422135446Strhodes isc_buffer_base(&rb), 423135446Strhodes isc_buffer_usedlength(&rb)); 424135446Strhodes failure: 425135446Strhodes if (p != NULL) 426135446Strhodes isc_mem_put(mctx, p, size); 427135446Strhodes if (lex != NULL) 428135446Strhodes isc_lex_destroy(&lex); 429135446Strhodes 430135446Strhodes return (result); 431135446Strhodes} 432135446Strhodes 433135446Strhodesstatic isc_result_t 434135446Strhodesgetnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { 435135446Strhodes dns_name_t *newname, *origin; 436135446Strhodes dns_fixedname_t fnewname; 437135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db; 438135446Strhodes dns_sdbimplementation_t *imp = sdb->implementation; 439135446Strhodes dns_sdbnode_t *sdbnode; 440135446Strhodes isc_mem_t *mctx = sdb->common.mctx; 441135446Strhodes isc_buffer_t b; 442135446Strhodes isc_result_t result; 443135446Strhodes 444135446Strhodes dns_fixedname_init(&fnewname); 445135446Strhodes newname = dns_fixedname_name(&fnewname); 446135446Strhodes 447135446Strhodes if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) 448135446Strhodes origin = &sdb->common.origin; 449135446Strhodes else 450135446Strhodes origin = dns_rootname; 451254402Serwin isc_buffer_constinit(&b, name, strlen(name)); 452135446Strhodes isc_buffer_add(&b, strlen(name)); 453135446Strhodes 454224092Sdougb result = dns_name_fromtext(newname, &b, origin, 0, NULL); 455135446Strhodes if (result != ISC_R_SUCCESS) 456135446Strhodes return (result); 457135446Strhodes 458135446Strhodes if (allnodes->common.relative_names) { 459135446Strhodes /* All names are relative to the root */ 460135446Strhodes unsigned int nlabels = dns_name_countlabels(newname); 461135446Strhodes dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); 462135446Strhodes } 463135446Strhodes 464135446Strhodes sdbnode = ISC_LIST_HEAD(allnodes->nodelist); 465135446Strhodes if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) { 466135446Strhodes sdbnode = NULL; 467135446Strhodes result = createnode(sdb, &sdbnode); 468135446Strhodes if (result != ISC_R_SUCCESS) 469135446Strhodes return (result); 470135446Strhodes sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t)); 471135446Strhodes if (sdbnode->name == NULL) { 472135446Strhodes destroynode(sdbnode); 473135446Strhodes return (ISC_R_NOMEMORY); 474135446Strhodes } 475135446Strhodes dns_name_init(sdbnode->name, NULL); 476135446Strhodes result = dns_name_dup(newname, mctx, sdbnode->name); 477135446Strhodes if (result != ISC_R_SUCCESS) { 478135446Strhodes isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t)); 479135446Strhodes destroynode(sdbnode); 480135446Strhodes return (result); 481135446Strhodes } 482135446Strhodes ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link); 483135446Strhodes if (allnodes->origin == NULL && 484135446Strhodes dns_name_equal(newname, &sdb->common.origin)) 485135446Strhodes allnodes->origin = sdbnode; 486135446Strhodes } 487135446Strhodes *nodep = sdbnode; 488135446Strhodes return (ISC_R_SUCCESS); 489135446Strhodes} 490135446Strhodes 491135446Strhodesisc_result_t 492135446Strhodesdns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, 493135446Strhodes const char *type, dns_ttl_t ttl, const char *data) 494135446Strhodes{ 495135446Strhodes isc_result_t result; 496135446Strhodes dns_sdbnode_t *sdbnode = NULL; 497135446Strhodes result = getnode(allnodes, name, &sdbnode); 498135446Strhodes if (result != ISC_R_SUCCESS) 499135446Strhodes return (result); 500135446Strhodes return (dns_sdb_putrr(sdbnode, type, ttl, data)); 501135446Strhodes} 502135446Strhodes 503135446Strhodesisc_result_t 504135446Strhodesdns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, 505135446Strhodes dns_rdatatype_t type, dns_ttl_t ttl, 506135446Strhodes const void *rdata, unsigned int rdlen) 507135446Strhodes{ 508135446Strhodes isc_result_t result; 509135446Strhodes dns_sdbnode_t *sdbnode = NULL; 510135446Strhodes result = getnode(allnodes, name, &sdbnode); 511135446Strhodes if (result != ISC_R_SUCCESS) 512135446Strhodes return (result); 513135446Strhodes return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen)); 514135446Strhodes} 515135446Strhodes 516135446Strhodesisc_result_t 517135446Strhodesdns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, 518135446Strhodes isc_uint32_t serial) 519135446Strhodes{ 520135446Strhodes char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; 521135446Strhodes int n; 522135446Strhodes 523135446Strhodes REQUIRE(mname != NULL); 524135446Strhodes REQUIRE(rname != NULL); 525135446Strhodes 526135446Strhodes n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u", 527135446Strhodes mname, rname, serial, 528135446Strhodes SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY, 529135446Strhodes SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM); 530135446Strhodes if (n >= (int)sizeof(str) || n < 0) 531135446Strhodes return (ISC_R_NOSPACE); 532135446Strhodes return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str)); 533135446Strhodes} 534135446Strhodes 535135446Strhodes/* 536135446Strhodes * DB routines 537135446Strhodes */ 538135446Strhodes 539135446Strhodesstatic void 540135446Strhodesattach(dns_db_t *source, dns_db_t **targetp) { 541135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *) source; 542135446Strhodes 543135446Strhodes REQUIRE(VALID_SDB(sdb)); 544135446Strhodes 545135446Strhodes LOCK(&sdb->lock); 546135446Strhodes REQUIRE(sdb->references > 0); 547135446Strhodes sdb->references++; 548135446Strhodes UNLOCK(&sdb->lock); 549135446Strhodes 550135446Strhodes *targetp = source; 551135446Strhodes} 552135446Strhodes 553135446Strhodesstatic void 554135446Strhodesdestroy(dns_sdb_t *sdb) { 555135446Strhodes isc_mem_t *mctx; 556135446Strhodes dns_sdbimplementation_t *imp = sdb->implementation; 557135446Strhodes 558135446Strhodes mctx = sdb->common.mctx; 559135446Strhodes 560135446Strhodes if (imp->methods->destroy != NULL) { 561135446Strhodes MAYBE_LOCK(sdb); 562135446Strhodes imp->methods->destroy(sdb->zone, imp->driverdata, 563135446Strhodes &sdb->dbdata); 564135446Strhodes MAYBE_UNLOCK(sdb); 565135446Strhodes } 566135446Strhodes 567135446Strhodes isc_mem_free(mctx, sdb->zone); 568135446Strhodes DESTROYLOCK(&sdb->lock); 569135446Strhodes 570135446Strhodes sdb->common.magic = 0; 571135446Strhodes sdb->common.impmagic = 0; 572135446Strhodes 573135446Strhodes dns_name_free(&sdb->common.origin, mctx); 574135446Strhodes 575135446Strhodes isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); 576135446Strhodes isc_mem_detach(&mctx); 577135446Strhodes} 578135446Strhodes 579135446Strhodesstatic void 580135446Strhodesdetach(dns_db_t **dbp) { 581135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)(*dbp); 582135446Strhodes isc_boolean_t need_destroy = ISC_FALSE; 583135446Strhodes 584135446Strhodes REQUIRE(VALID_SDB(sdb)); 585135446Strhodes LOCK(&sdb->lock); 586135446Strhodes REQUIRE(sdb->references > 0); 587135446Strhodes sdb->references--; 588135446Strhodes if (sdb->references == 0) 589135446Strhodes need_destroy = ISC_TRUE; 590135446Strhodes UNLOCK(&sdb->lock); 591135446Strhodes 592135446Strhodes if (need_destroy) 593135446Strhodes destroy(sdb); 594135446Strhodes 595135446Strhodes *dbp = NULL; 596135446Strhodes} 597135446Strhodes 598135446Strhodesstatic isc_result_t 599135446Strhodesbeginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { 600135446Strhodes UNUSED(db); 601135446Strhodes UNUSED(addp); 602135446Strhodes UNUSED(dbloadp); 603135446Strhodes return (ISC_R_NOTIMPLEMENTED); 604135446Strhodes} 605135446Strhodes 606135446Strhodesstatic isc_result_t 607135446Strhodesendload(dns_db_t *db, dns_dbload_t **dbloadp) { 608135446Strhodes UNUSED(db); 609135446Strhodes UNUSED(dbloadp); 610135446Strhodes return (ISC_R_NOTIMPLEMENTED); 611135446Strhodes} 612135446Strhodes 613135446Strhodesstatic isc_result_t 614170222Sdougbdump(dns_db_t *db, dns_dbversion_t *version, const char *filename, 615170222Sdougb dns_masterformat_t masterformat) { 616135446Strhodes UNUSED(db); 617135446Strhodes UNUSED(version); 618135446Strhodes UNUSED(filename); 619170222Sdougb UNUSED(masterformat); 620135446Strhodes return (ISC_R_NOTIMPLEMENTED); 621135446Strhodes} 622135446Strhodes 623135446Strhodesstatic void 624135446Strhodescurrentversion(dns_db_t *db, dns_dbversion_t **versionp) { 625135446Strhodes REQUIRE(versionp != NULL && *versionp == NULL); 626135446Strhodes 627135446Strhodes UNUSED(db); 628135446Strhodes 629135446Strhodes *versionp = (void *) &dummy; 630135446Strhodes return; 631135446Strhodes} 632135446Strhodes 633135446Strhodesstatic isc_result_t 634135446Strhodesnewversion(dns_db_t *db, dns_dbversion_t **versionp) { 635135446Strhodes UNUSED(db); 636135446Strhodes UNUSED(versionp); 637135446Strhodes 638135446Strhodes return (ISC_R_NOTIMPLEMENTED); 639135446Strhodes} 640135446Strhodes 641135446Strhodesstatic void 642186462Sdougbattachversion(dns_db_t *db, dns_dbversion_t *source, 643135446Strhodes dns_dbversion_t **targetp) 644135446Strhodes{ 645135446Strhodes REQUIRE(source != NULL && source == (void *) &dummy); 646135446Strhodes REQUIRE(targetp != NULL && *targetp == NULL); 647135446Strhodes 648135446Strhodes UNUSED(db); 649135446Strhodes *targetp = source; 650135446Strhodes return; 651135446Strhodes} 652135446Strhodes 653135446Strhodesstatic void 654135446Strhodescloseversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { 655135446Strhodes REQUIRE(versionp != NULL && *versionp == (void *) &dummy); 656135446Strhodes REQUIRE(commit == ISC_FALSE); 657135446Strhodes 658135446Strhodes UNUSED(db); 659135446Strhodes UNUSED(commit); 660135446Strhodes 661135446Strhodes *versionp = NULL; 662135446Strhodes} 663135446Strhodes 664135446Strhodesstatic isc_result_t 665135446Strhodescreatenode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) { 666135446Strhodes dns_sdbnode_t *node; 667135446Strhodes isc_result_t result; 668135446Strhodes 669135446Strhodes node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t)); 670135446Strhodes if (node == NULL) 671135446Strhodes return (ISC_R_NOMEMORY); 672135446Strhodes 673135446Strhodes node->sdb = NULL; 674135446Strhodes attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb); 675135446Strhodes ISC_LIST_INIT(node->lists); 676135446Strhodes ISC_LIST_INIT(node->buffers); 677135446Strhodes ISC_LINK_INIT(node, link); 678135446Strhodes node->name = NULL; 679135446Strhodes result = isc_mutex_init(&node->lock); 680135446Strhodes if (result != ISC_R_SUCCESS) { 681135446Strhodes isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t)); 682170222Sdougb return (result); 683135446Strhodes } 684135446Strhodes dns_rdatacallbacks_init(&node->callbacks); 685135446Strhodes node->references = 1; 686135446Strhodes node->magic = SDBLOOKUP_MAGIC; 687135446Strhodes 688135446Strhodes *nodep = node; 689135446Strhodes return (ISC_R_SUCCESS); 690135446Strhodes} 691135446Strhodes 692135446Strhodesstatic void 693135446Strhodesdestroynode(dns_sdbnode_t *node) { 694135446Strhodes dns_rdatalist_t *list; 695135446Strhodes dns_rdata_t *rdata; 696135446Strhodes isc_buffer_t *b; 697135446Strhodes dns_sdb_t *sdb; 698135446Strhodes isc_mem_t *mctx; 699135446Strhodes 700135446Strhodes sdb = node->sdb; 701135446Strhodes mctx = sdb->common.mctx; 702135446Strhodes 703135446Strhodes while (!ISC_LIST_EMPTY(node->lists)) { 704135446Strhodes list = ISC_LIST_HEAD(node->lists); 705135446Strhodes while (!ISC_LIST_EMPTY(list->rdata)) { 706135446Strhodes rdata = ISC_LIST_HEAD(list->rdata); 707135446Strhodes ISC_LIST_UNLINK(list->rdata, rdata, link); 708135446Strhodes isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); 709135446Strhodes } 710135446Strhodes ISC_LIST_UNLINK(node->lists, list, link); 711135446Strhodes isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); 712135446Strhodes } 713135446Strhodes 714135446Strhodes while (!ISC_LIST_EMPTY(node->buffers)) { 715135446Strhodes b = ISC_LIST_HEAD(node->buffers); 716135446Strhodes ISC_LIST_UNLINK(node->buffers, b, link); 717135446Strhodes isc_buffer_free(&b); 718135446Strhodes } 719135446Strhodes 720135446Strhodes if (node->name != NULL) { 721135446Strhodes dns_name_free(node->name, mctx); 722135446Strhodes isc_mem_put(mctx, node->name, sizeof(dns_name_t)); 723135446Strhodes } 724135446Strhodes DESTROYLOCK(&node->lock); 725135446Strhodes node->magic = 0; 726135446Strhodes isc_mem_put(mctx, node, sizeof(dns_sdbnode_t)); 727135446Strhodes detach((dns_db_t **) (void *)&sdb); 728135446Strhodes} 729135446Strhodes 730135446Strhodesstatic isc_result_t 731254897Serwinfindnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, 732254897Serwin dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, 733254897Serwin dns_dbnode_t **nodep) 734135446Strhodes{ 735135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 736135446Strhodes dns_sdbnode_t *node = NULL; 737135446Strhodes isc_result_t result; 738135446Strhodes isc_buffer_t b; 739135446Strhodes char namestr[DNS_NAME_MAXTEXT + 1]; 740135446Strhodes isc_boolean_t isorigin; 741135446Strhodes dns_sdbimplementation_t *imp; 742236374Sdougb dns_name_t relname; 743236374Sdougb unsigned int labels; 744135446Strhodes 745135446Strhodes REQUIRE(VALID_SDB(sdb)); 746135446Strhodes REQUIRE(create == ISC_FALSE); 747135446Strhodes REQUIRE(nodep != NULL && *nodep == NULL); 748135446Strhodes 749135446Strhodes UNUSED(name); 750135446Strhodes UNUSED(create); 751135446Strhodes 752135446Strhodes imp = sdb->implementation; 753135446Strhodes 754236374Sdougb isorigin = dns_name_equal(name, &sdb->common.origin); 755135446Strhodes 756236374Sdougb if (imp->methods->lookup2 != NULL) { 757236374Sdougb if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { 758236374Sdougb labels = dns_name_countlabels(name) - 759236374Sdougb dns_name_countlabels(&db->origin); 760236374Sdougb dns_name_init(&relname, NULL); 761236374Sdougb dns_name_getlabelsequence(name, 0, labels, &relname); 762236374Sdougb name = &relname; 763236374Sdougb } 764135446Strhodes } else { 765236374Sdougb isc_buffer_init(&b, namestr, sizeof(namestr)); 766236374Sdougb if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { 767236374Sdougb 768236374Sdougb labels = dns_name_countlabels(name) - 769236374Sdougb dns_name_countlabels(&db->origin); 770236374Sdougb dns_name_init(&relname, NULL); 771236374Sdougb dns_name_getlabelsequence(name, 0, labels, &relname); 772236374Sdougb result = dns_name_totext(&relname, ISC_TRUE, &b); 773236374Sdougb if (result != ISC_R_SUCCESS) 774236374Sdougb return (result); 775236374Sdougb } else { 776236374Sdougb result = dns_name_totext(name, ISC_TRUE, &b); 777236374Sdougb if (result != ISC_R_SUCCESS) 778236374Sdougb return (result); 779236374Sdougb } 780236374Sdougb isc_buffer_putuint8(&b, 0); 781135446Strhodes } 782135446Strhodes 783135446Strhodes result = createnode(sdb, &node); 784135446Strhodes if (result != ISC_R_SUCCESS) 785135446Strhodes return (result); 786135446Strhodes 787135446Strhodes MAYBE_LOCK(sdb); 788236374Sdougb if (imp->methods->lookup2 != NULL) 789236374Sdougb result = imp->methods->lookup2(&sdb->common.origin, name, 790254897Serwin sdb->dbdata, node, methods, 791254897Serwin clientinfo); 792236374Sdougb else 793236374Sdougb result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, 794254897Serwin node, methods, clientinfo); 795135446Strhodes MAYBE_UNLOCK(sdb); 796135446Strhodes if (result != ISC_R_SUCCESS && 797135446Strhodes !(result == ISC_R_NOTFOUND && 798135446Strhodes isorigin && imp->methods->authority != NULL)) 799135446Strhodes { 800135446Strhodes destroynode(node); 801135446Strhodes return (result); 802135446Strhodes } 803135446Strhodes 804135446Strhodes if (isorigin && imp->methods->authority != NULL) { 805135446Strhodes MAYBE_LOCK(sdb); 806135446Strhodes result = imp->methods->authority(sdb->zone, sdb->dbdata, node); 807135446Strhodes MAYBE_UNLOCK(sdb); 808135446Strhodes if (result != ISC_R_SUCCESS) { 809135446Strhodes destroynode(node); 810135446Strhodes return (result); 811135446Strhodes } 812135446Strhodes } 813186462Sdougb 814135446Strhodes *nodep = node; 815135446Strhodes return (ISC_R_SUCCESS); 816135446Strhodes} 817135446Strhodes 818135446Strhodesstatic isc_result_t 819254897Serwinfindext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, 820254897Serwin dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, 821254897Serwin dns_dbnode_t **nodep, dns_name_t *foundname, 822254897Serwin dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, 823254897Serwin dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 824135446Strhodes{ 825135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 826135446Strhodes dns_dbnode_t *node = NULL; 827135446Strhodes dns_fixedname_t fname; 828135446Strhodes dns_rdataset_t xrdataset; 829135446Strhodes dns_name_t *xname; 830135446Strhodes unsigned int nlabels, olabels; 831135446Strhodes isc_result_t result; 832135446Strhodes unsigned int i; 833236374Sdougb unsigned int flags; 834135446Strhodes 835135446Strhodes REQUIRE(VALID_SDB(sdb)); 836135446Strhodes REQUIRE(nodep == NULL || *nodep == NULL); 837135446Strhodes REQUIRE(version == NULL || version == (void *) &dummy); 838135446Strhodes 839135446Strhodes UNUSED(options); 840135446Strhodes 841135446Strhodes if (!dns_name_issubdomain(name, &db->origin)) 842135446Strhodes return (DNS_R_NXDOMAIN); 843135446Strhodes 844135446Strhodes olabels = dns_name_countlabels(&db->origin); 845135446Strhodes nlabels = dns_name_countlabels(name); 846135446Strhodes 847135446Strhodes dns_fixedname_init(&fname); 848135446Strhodes xname = dns_fixedname_name(&fname); 849135446Strhodes 850135446Strhodes if (rdataset == NULL) { 851135446Strhodes dns_rdataset_init(&xrdataset); 852135446Strhodes rdataset = &xrdataset; 853135446Strhodes } 854135446Strhodes 855135446Strhodes result = DNS_R_NXDOMAIN; 856236374Sdougb flags = sdb->implementation->flags; 857236374Sdougb i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels; 858236374Sdougb for (; i <= nlabels; i++) { 859135446Strhodes /* 860135446Strhodes * Look up the next label. 861135446Strhodes */ 862135446Strhodes dns_name_getlabelsequence(name, nlabels - i, i, xname); 863254897Serwin result = findnodeext(db, xname, ISC_FALSE, methods, 864254897Serwin clientinfo, &node); 865236374Sdougb if (result == ISC_R_NOTFOUND) { 866236374Sdougb /* 867236374Sdougb * No data at zone apex? 868236374Sdougb */ 869236374Sdougb if (i == olabels) 870236374Sdougb return (DNS_R_BADDB); 871135446Strhodes result = DNS_R_NXDOMAIN; 872135446Strhodes continue; 873135446Strhodes } 874236374Sdougb if (result != ISC_R_SUCCESS) 875236374Sdougb return (result); 876135446Strhodes 877135446Strhodes /* 878236374Sdougb * DNS64 zone's don't have DNAME or NS records. 879236374Sdougb */ 880236374Sdougb if ((flags & DNS_SDBFLAG_DNS64) != 0) 881236374Sdougb goto skip; 882236374Sdougb 883236374Sdougb /* 884236374Sdougb * DNS64 zone's don't have DNAME or NS records. 885236374Sdougb */ 886236374Sdougb if ((flags & DNS_SDBFLAG_DNS64) != 0) 887236374Sdougb goto skip; 888236374Sdougb 889236374Sdougb /* 890135446Strhodes * Look for a DNAME at the current label, unless this is 891135446Strhodes * the qname. 892135446Strhodes */ 893135446Strhodes if (i < nlabels) { 894135446Strhodes result = findrdataset(db, node, version, 895135446Strhodes dns_rdatatype_dname, 896135446Strhodes 0, now, rdataset, sigrdataset); 897135446Strhodes if (result == ISC_R_SUCCESS) { 898135446Strhodes result = DNS_R_DNAME; 899135446Strhodes break; 900135446Strhodes } 901135446Strhodes } 902135446Strhodes 903135446Strhodes /* 904135446Strhodes * Look for an NS at the current label, unless this is the 905135446Strhodes * origin or glue is ok. 906135446Strhodes */ 907135446Strhodes if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { 908135446Strhodes result = findrdataset(db, node, version, 909135446Strhodes dns_rdatatype_ns, 910135446Strhodes 0, now, rdataset, sigrdataset); 911135446Strhodes if (result == ISC_R_SUCCESS) { 912135446Strhodes if (i == nlabels && type == dns_rdatatype_any) 913135446Strhodes { 914135446Strhodes result = DNS_R_ZONECUT; 915135446Strhodes dns_rdataset_disassociate(rdataset); 916193149Sdougb if (sigrdataset != NULL && 917193149Sdougb dns_rdataset_isassociated 918193149Sdougb (sigrdataset)) { 919135446Strhodes dns_rdataset_disassociate 920135446Strhodes (sigrdataset); 921193149Sdougb } 922135446Strhodes } else 923135446Strhodes result = DNS_R_DELEGATION; 924135446Strhodes break; 925135446Strhodes } 926135446Strhodes } 927135446Strhodes 928135446Strhodes /* 929135446Strhodes * If the current name is not the qname, add another label 930135446Strhodes * and try again. 931135446Strhodes */ 932135446Strhodes if (i < nlabels) { 933135446Strhodes destroynode(node); 934135446Strhodes node = NULL; 935135446Strhodes continue; 936135446Strhodes } 937135446Strhodes 938236374Sdougb skip: 939135446Strhodes /* 940135446Strhodes * If we're looking for ANY, we're done. 941135446Strhodes */ 942135446Strhodes if (type == dns_rdatatype_any) { 943135446Strhodes result = ISC_R_SUCCESS; 944135446Strhodes break; 945135446Strhodes } 946135446Strhodes 947135446Strhodes /* 948135446Strhodes * Look for the qtype. 949135446Strhodes */ 950135446Strhodes result = findrdataset(db, node, version, type, 951135446Strhodes 0, now, rdataset, sigrdataset); 952135446Strhodes if (result == ISC_R_SUCCESS) 953135446Strhodes break; 954135446Strhodes 955135446Strhodes /* 956135446Strhodes * Look for a CNAME 957135446Strhodes */ 958135446Strhodes if (type != dns_rdatatype_cname) { 959135446Strhodes result = findrdataset(db, node, version, 960135446Strhodes dns_rdatatype_cname, 961135446Strhodes 0, now, rdataset, sigrdataset); 962135446Strhodes if (result == ISC_R_SUCCESS) { 963135446Strhodes result = DNS_R_CNAME; 964135446Strhodes break; 965135446Strhodes } 966135446Strhodes } 967135446Strhodes 968135446Strhodes result = DNS_R_NXRRSET; 969135446Strhodes break; 970135446Strhodes } 971135446Strhodes 972135446Strhodes if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) 973135446Strhodes dns_rdataset_disassociate(rdataset); 974135446Strhodes 975135446Strhodes if (foundname != NULL) { 976135446Strhodes isc_result_t xresult; 977135446Strhodes 978135446Strhodes xresult = dns_name_copy(xname, foundname, NULL); 979135446Strhodes if (xresult != ISC_R_SUCCESS) { 980170222Sdougb if (node != NULL) 981170222Sdougb destroynode(node); 982135446Strhodes if (dns_rdataset_isassociated(rdataset)) 983135446Strhodes dns_rdataset_disassociate(rdataset); 984135446Strhodes return (DNS_R_BADDB); 985135446Strhodes } 986135446Strhodes } 987135446Strhodes 988135446Strhodes if (nodep != NULL) 989135446Strhodes *nodep = node; 990135446Strhodes else if (node != NULL) 991135446Strhodes detachnode(db, &node); 992135446Strhodes 993135446Strhodes return (result); 994135446Strhodes} 995135446Strhodes 996135446Strhodesstatic isc_result_t 997135446Strhodesfindzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, 998135446Strhodes isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, 999135446Strhodes dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1000135446Strhodes{ 1001135446Strhodes UNUSED(db); 1002135446Strhodes UNUSED(name); 1003135446Strhodes UNUSED(options); 1004135446Strhodes UNUSED(now); 1005135446Strhodes UNUSED(nodep); 1006135446Strhodes UNUSED(foundname); 1007135446Strhodes UNUSED(rdataset); 1008135446Strhodes UNUSED(sigrdataset); 1009135446Strhodes 1010135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1011135446Strhodes} 1012135446Strhodes 1013135446Strhodesstatic void 1014135446Strhodesattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { 1015135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1016135446Strhodes dns_sdbnode_t *node = (dns_sdbnode_t *)source; 1017135446Strhodes 1018135446Strhodes REQUIRE(VALID_SDB(sdb)); 1019135446Strhodes 1020135446Strhodes UNUSED(sdb); 1021135446Strhodes 1022135446Strhodes LOCK(&node->lock); 1023135446Strhodes INSIST(node->references > 0); 1024135446Strhodes node->references++; 1025135446Strhodes INSIST(node->references != 0); /* Catch overflow. */ 1026135446Strhodes UNLOCK(&node->lock); 1027135446Strhodes 1028135446Strhodes *targetp = source; 1029135446Strhodes} 1030135446Strhodes 1031135446Strhodesstatic void 1032135446Strhodesdetachnode(dns_db_t *db, dns_dbnode_t **targetp) { 1033135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1034135446Strhodes dns_sdbnode_t *node; 1035135446Strhodes isc_boolean_t need_destroy = ISC_FALSE; 1036135446Strhodes 1037135446Strhodes REQUIRE(VALID_SDB(sdb)); 1038135446Strhodes REQUIRE(targetp != NULL && *targetp != NULL); 1039135446Strhodes 1040135446Strhodes UNUSED(sdb); 1041135446Strhodes 1042135446Strhodes node = (dns_sdbnode_t *)(*targetp); 1043135446Strhodes 1044135446Strhodes LOCK(&node->lock); 1045135446Strhodes INSIST(node->references > 0); 1046135446Strhodes node->references--; 1047135446Strhodes if (node->references == 0) 1048135446Strhodes need_destroy = ISC_TRUE; 1049135446Strhodes UNLOCK(&node->lock); 1050135446Strhodes 1051135446Strhodes if (need_destroy) 1052135446Strhodes destroynode(node); 1053135446Strhodes 1054135446Strhodes *targetp = NULL; 1055135446Strhodes} 1056135446Strhodes 1057135446Strhodesstatic isc_result_t 1058135446Strhodesexpirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { 1059135446Strhodes UNUSED(db); 1060135446Strhodes UNUSED(node); 1061135446Strhodes UNUSED(now); 1062135446Strhodes INSIST(0); 1063135446Strhodes return (ISC_R_UNEXPECTED); 1064135446Strhodes} 1065135446Strhodes 1066135446Strhodesstatic void 1067135446Strhodesprintnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { 1068135446Strhodes UNUSED(db); 1069135446Strhodes UNUSED(node); 1070135446Strhodes UNUSED(out); 1071135446Strhodes return; 1072135446Strhodes} 1073135446Strhodes 1074135446Strhodesstatic isc_result_t 1075193149Sdougbcreateiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) 1076135446Strhodes{ 1077135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1078135446Strhodes sdb_dbiterator_t *sdbiter; 1079135446Strhodes dns_sdbimplementation_t *imp = sdb->implementation; 1080135446Strhodes isc_result_t result; 1081135446Strhodes 1082135446Strhodes REQUIRE(VALID_SDB(sdb)); 1083135446Strhodes 1084135446Strhodes if (imp->methods->allnodes == NULL) 1085135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1086135446Strhodes 1087193149Sdougb if ((options & DNS_DB_NSEC3ONLY) != 0 || 1088193149Sdougb (options & DNS_DB_NONSEC3) != 0) 1089193149Sdougb return (ISC_R_NOTIMPLEMENTED); 1090193149Sdougb 1091135446Strhodes sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t)); 1092135446Strhodes if (sdbiter == NULL) 1093135446Strhodes return (ISC_R_NOMEMORY); 1094135446Strhodes 1095135446Strhodes sdbiter->common.methods = &dbiterator_methods; 1096135446Strhodes sdbiter->common.db = NULL; 1097135446Strhodes dns_db_attach(db, &sdbiter->common.db); 1098193149Sdougb sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES); 1099135446Strhodes sdbiter->common.magic = DNS_DBITERATOR_MAGIC; 1100135446Strhodes ISC_LIST_INIT(sdbiter->nodelist); 1101135446Strhodes sdbiter->current = NULL; 1102135446Strhodes sdbiter->origin = NULL; 1103135446Strhodes 1104135446Strhodes MAYBE_LOCK(sdb); 1105135446Strhodes result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); 1106135446Strhodes MAYBE_UNLOCK(sdb); 1107135446Strhodes if (result != ISC_R_SUCCESS) { 1108135446Strhodes dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter); 1109135446Strhodes return (result); 1110135446Strhodes } 1111135446Strhodes 1112135446Strhodes if (sdbiter->origin != NULL) { 1113135446Strhodes ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link); 1114135446Strhodes ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link); 1115135446Strhodes } 1116135446Strhodes 1117135446Strhodes *iteratorp = (dns_dbiterator_t *)sdbiter; 1118135446Strhodes 1119135446Strhodes return (ISC_R_SUCCESS); 1120135446Strhodes} 1121135446Strhodes 1122135446Strhodesstatic isc_result_t 1123135446Strhodesfindrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1124135446Strhodes dns_rdatatype_t type, dns_rdatatype_t covers, 1125135446Strhodes isc_stdtime_t now, dns_rdataset_t *rdataset, 1126135446Strhodes dns_rdataset_t *sigrdataset) 1127135446Strhodes{ 1128135446Strhodes dns_rdatalist_t *list; 1129135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node; 1130135446Strhodes 1131135446Strhodes REQUIRE(VALID_SDBNODE(node)); 1132135446Strhodes 1133135446Strhodes UNUSED(db); 1134135446Strhodes UNUSED(version); 1135135446Strhodes UNUSED(covers); 1136135446Strhodes UNUSED(now); 1137135446Strhodes UNUSED(sigrdataset); 1138135446Strhodes 1139135446Strhodes if (type == dns_rdatatype_rrsig) 1140135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1141135446Strhodes 1142135446Strhodes list = ISC_LIST_HEAD(sdbnode->lists); 1143135446Strhodes while (list != NULL) { 1144135446Strhodes if (list->type == type) 1145135446Strhodes break; 1146135446Strhodes list = ISC_LIST_NEXT(list, link); 1147135446Strhodes } 1148135446Strhodes if (list == NULL) 1149135446Strhodes return (ISC_R_NOTFOUND); 1150135446Strhodes 1151135446Strhodes list_tordataset(list, db, node, rdataset); 1152135446Strhodes 1153135446Strhodes return (ISC_R_SUCCESS); 1154135446Strhodes} 1155135446Strhodes 1156135446Strhodesstatic isc_result_t 1157135446Strhodesallrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1158135446Strhodes isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) 1159135446Strhodes{ 1160135446Strhodes sdb_rdatasetiter_t *iterator; 1161135446Strhodes 1162135446Strhodes REQUIRE(version == NULL || version == &dummy); 1163186462Sdougb 1164135446Strhodes UNUSED(version); 1165135446Strhodes UNUSED(now); 1166135446Strhodes 1167135446Strhodes iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t)); 1168135446Strhodes if (iterator == NULL) 1169135446Strhodes return (ISC_R_NOMEMORY); 1170135446Strhodes 1171135446Strhodes iterator->common.magic = DNS_RDATASETITER_MAGIC; 1172135446Strhodes iterator->common.methods = &rdatasetiter_methods; 1173135446Strhodes iterator->common.db = db; 1174135446Strhodes iterator->common.node = NULL; 1175135446Strhodes attachnode(db, node, &iterator->common.node); 1176135446Strhodes iterator->common.version = version; 1177135446Strhodes iterator->common.now = now; 1178135446Strhodes 1179135446Strhodes *iteratorp = (dns_rdatasetiter_t *)iterator; 1180135446Strhodes 1181135446Strhodes return (ISC_R_SUCCESS); 1182135446Strhodes} 1183135446Strhodes 1184135446Strhodesstatic isc_result_t 1185135446Strhodesaddrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1186135446Strhodes isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, 1187135446Strhodes dns_rdataset_t *addedrdataset) 1188135446Strhodes{ 1189135446Strhodes UNUSED(db); 1190135446Strhodes UNUSED(node); 1191135446Strhodes UNUSED(version); 1192135446Strhodes UNUSED(now); 1193135446Strhodes UNUSED(rdataset); 1194135446Strhodes UNUSED(options); 1195135446Strhodes UNUSED(addedrdataset); 1196135446Strhodes 1197135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1198135446Strhodes} 1199135446Strhodes 1200135446Strhodesstatic isc_result_t 1201135446Strhodessubtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1202135446Strhodes dns_rdataset_t *rdataset, unsigned int options, 1203135446Strhodes dns_rdataset_t *newrdataset) 1204135446Strhodes{ 1205135446Strhodes UNUSED(db); 1206135446Strhodes UNUSED(node); 1207135446Strhodes UNUSED(version); 1208135446Strhodes UNUSED(rdataset); 1209135446Strhodes UNUSED(options); 1210135446Strhodes UNUSED(newrdataset); 1211135446Strhodes 1212135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1213135446Strhodes} 1214135446Strhodes 1215135446Strhodesstatic isc_result_t 1216135446Strhodesdeleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1217135446Strhodes dns_rdatatype_t type, dns_rdatatype_t covers) 1218135446Strhodes{ 1219135446Strhodes UNUSED(db); 1220135446Strhodes UNUSED(node); 1221135446Strhodes UNUSED(version); 1222135446Strhodes UNUSED(type); 1223135446Strhodes UNUSED(covers); 1224135446Strhodes 1225135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1226135446Strhodes} 1227135446Strhodes 1228135446Strhodesstatic isc_boolean_t 1229135446Strhodesissecure(dns_db_t *db) { 1230135446Strhodes UNUSED(db); 1231135446Strhodes 1232135446Strhodes return (ISC_FALSE); 1233135446Strhodes} 1234135446Strhodes 1235135446Strhodesstatic unsigned int 1236135446Strhodesnodecount(dns_db_t *db) { 1237135446Strhodes UNUSED(db); 1238135446Strhodes 1239135446Strhodes return (0); 1240135446Strhodes} 1241135446Strhodes 1242135446Strhodesstatic isc_boolean_t 1243135446Strhodesispersistent(dns_db_t *db) { 1244135446Strhodes UNUSED(db); 1245135446Strhodes return (ISC_TRUE); 1246135446Strhodes} 1247135446Strhodes 1248135446Strhodesstatic void 1249135446Strhodesovermem(dns_db_t *db, isc_boolean_t overmem) { 1250135446Strhodes UNUSED(db); 1251135446Strhodes UNUSED(overmem); 1252135446Strhodes} 1253135446Strhodes 1254135446Strhodesstatic void 1255135446Strhodessettask(dns_db_t *db, isc_task_t *task) { 1256135446Strhodes UNUSED(db); 1257135446Strhodes UNUSED(task); 1258135446Strhodes} 1259135446Strhodes 1260135446Strhodes 1261135446Strhodesstatic dns_dbmethods_t sdb_methods = { 1262135446Strhodes attach, 1263135446Strhodes detach, 1264135446Strhodes beginload, 1265135446Strhodes endload, 1266135446Strhodes dump, 1267135446Strhodes currentversion, 1268135446Strhodes newversion, 1269135446Strhodes attachversion, 1270135446Strhodes closeversion, 1271254897Serwin NULL, 1272254897Serwin NULL, 1273135446Strhodes findzonecut, 1274135446Strhodes attachnode, 1275135446Strhodes detachnode, 1276135446Strhodes expirenode, 1277135446Strhodes printnode, 1278135446Strhodes createiterator, 1279135446Strhodes findrdataset, 1280135446Strhodes allrdatasets, 1281135446Strhodes addrdataset, 1282135446Strhodes subtractrdataset, 1283135446Strhodes deleterdataset, 1284135446Strhodes issecure, 1285135446Strhodes nodecount, 1286135446Strhodes ispersistent, 1287135446Strhodes overmem, 1288170222Sdougb settask, 1289254897Serwin NULL, /* getoriginnode */ 1290254897Serwin NULL, /* transfernode */ 1291254897Serwin NULL, /* getnsec3parameters */ 1292254897Serwin NULL, /* findnsec3node */ 1293254897Serwin NULL, /* setsigningtime */ 1294254897Serwin NULL, /* getsigningtime */ 1295254897Serwin NULL, /* resigned */ 1296254897Serwin NULL, /* isdnssec */ 1297254897Serwin NULL, /* getrrsetstats */ 1298254897Serwin NULL, /* rpz_enabled */ 1299254897Serwin NULL, /* rpz_findips */ 1300254897Serwin findnodeext, 1301254897Serwin findext 1302135446Strhodes}; 1303135446Strhodes 1304135446Strhodesstatic isc_result_t 1305135446Strhodesdns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, 1306135446Strhodes dns_rdataclass_t rdclass, unsigned int argc, char *argv[], 1307135446Strhodes void *driverarg, dns_db_t **dbp) 1308135446Strhodes{ 1309135446Strhodes dns_sdb_t *sdb; 1310135446Strhodes isc_result_t result; 1311135446Strhodes char zonestr[DNS_NAME_MAXTEXT + 1]; 1312135446Strhodes isc_buffer_t b; 1313135446Strhodes dns_sdbimplementation_t *imp; 1314135446Strhodes 1315135446Strhodes REQUIRE(driverarg != NULL); 1316135446Strhodes 1317135446Strhodes imp = driverarg; 1318135446Strhodes 1319135446Strhodes if (type != dns_dbtype_zone) 1320135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1321135446Strhodes 1322135446Strhodes sdb = isc_mem_get(mctx, sizeof(dns_sdb_t)); 1323135446Strhodes if (sdb == NULL) 1324135446Strhodes return (ISC_R_NOMEMORY); 1325135446Strhodes memset(sdb, 0, sizeof(dns_sdb_t)); 1326135446Strhodes 1327135446Strhodes dns_name_init(&sdb->common.origin, NULL); 1328135446Strhodes sdb->common.attributes = 0; 1329135446Strhodes sdb->common.methods = &sdb_methods; 1330135446Strhodes sdb->common.rdclass = rdclass; 1331135446Strhodes sdb->common.mctx = NULL; 1332135446Strhodes sdb->implementation = imp; 1333135446Strhodes 1334135446Strhodes isc_mem_attach(mctx, &sdb->common.mctx); 1335135446Strhodes 1336135446Strhodes result = isc_mutex_init(&sdb->lock); 1337170222Sdougb if (result != ISC_R_SUCCESS) 1338135446Strhodes goto cleanup_mctx; 1339135446Strhodes 1340135446Strhodes result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); 1341135446Strhodes if (result != ISC_R_SUCCESS) 1342135446Strhodes goto cleanup_lock; 1343135446Strhodes 1344135446Strhodes isc_buffer_init(&b, zonestr, sizeof(zonestr)); 1345135446Strhodes result = dns_name_totext(origin, ISC_TRUE, &b); 1346135446Strhodes if (result != ISC_R_SUCCESS) 1347135446Strhodes goto cleanup_origin; 1348135446Strhodes isc_buffer_putuint8(&b, 0); 1349135446Strhodes 1350135446Strhodes sdb->zone = isc_mem_strdup(mctx, zonestr); 1351135446Strhodes if (sdb->zone == NULL) { 1352135446Strhodes result = ISC_R_NOMEMORY; 1353135446Strhodes goto cleanup_origin; 1354135446Strhodes } 1355135446Strhodes 1356135446Strhodes sdb->dbdata = NULL; 1357135446Strhodes if (imp->methods->create != NULL) { 1358135446Strhodes MAYBE_LOCK(sdb); 1359135446Strhodes result = imp->methods->create(sdb->zone, argc, argv, 1360135446Strhodes imp->driverdata, &sdb->dbdata); 1361135446Strhodes MAYBE_UNLOCK(sdb); 1362135446Strhodes if (result != ISC_R_SUCCESS) 1363135446Strhodes goto cleanup_zonestr; 1364135446Strhodes } 1365135446Strhodes 1366135446Strhodes sdb->references = 1; 1367135446Strhodes 1368135446Strhodes sdb->common.magic = DNS_DB_MAGIC; 1369135446Strhodes sdb->common.impmagic = SDB_MAGIC; 1370135446Strhodes 1371135446Strhodes *dbp = (dns_db_t *)sdb; 1372135446Strhodes 1373135446Strhodes return (ISC_R_SUCCESS); 1374135446Strhodes 1375135446Strhodes cleanup_zonestr: 1376135446Strhodes isc_mem_free(mctx, sdb->zone); 1377135446Strhodes cleanup_origin: 1378135446Strhodes dns_name_free(&sdb->common.origin, mctx); 1379135446Strhodes cleanup_lock: 1380225361Sdougb (void)isc_mutex_destroy(&sdb->lock); 1381135446Strhodes cleanup_mctx: 1382135446Strhodes isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); 1383135446Strhodes isc_mem_detach(&mctx); 1384135446Strhodes 1385135446Strhodes return (result); 1386135446Strhodes} 1387135446Strhodes 1388135446Strhodes 1389135446Strhodes/* 1390135446Strhodes * Rdataset Methods 1391135446Strhodes */ 1392135446Strhodes 1393135446Strhodesstatic void 1394135446Strhodesdisassociate(dns_rdataset_t *rdataset) { 1395135446Strhodes dns_dbnode_t *node = rdataset->private5; 1396135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1397135446Strhodes dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1398135446Strhodes 1399135446Strhodes detachnode(db, &node); 1400135446Strhodes isc__rdatalist_disassociate(rdataset); 1401135446Strhodes} 1402135446Strhodes 1403135446Strhodesstatic void 1404135446Strhodesrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { 1405135446Strhodes dns_dbnode_t *node = source->private5; 1406135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1407135446Strhodes dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1408135446Strhodes dns_dbnode_t *tempdb = NULL; 1409135446Strhodes 1410135446Strhodes isc__rdatalist_clone(source, target); 1411135446Strhodes attachnode(db, node, &tempdb); 1412135446Strhodes source->private5 = tempdb; 1413135446Strhodes} 1414135446Strhodes 1415135446Strhodesstatic dns_rdatasetmethods_t methods = { 1416135446Strhodes disassociate, 1417135446Strhodes isc__rdatalist_first, 1418135446Strhodes isc__rdatalist_next, 1419135446Strhodes isc__rdatalist_current, 1420135446Strhodes rdataset_clone, 1421135446Strhodes isc__rdatalist_count, 1422135446Strhodes isc__rdatalist_addnoqname, 1423170222Sdougb isc__rdatalist_getnoqname, 1424170222Sdougb NULL, 1425170222Sdougb NULL, 1426193149Sdougb NULL, 1427193149Sdougb NULL, 1428205292Sdougb NULL, 1429205292Sdougb NULL, 1430170222Sdougb NULL 1431135446Strhodes}; 1432135446Strhodes 1433135446Strhodesstatic void 1434135446Strhodeslist_tordataset(dns_rdatalist_t *rdatalist, 1435135446Strhodes dns_db_t *db, dns_dbnode_t *node, 1436135446Strhodes dns_rdataset_t *rdataset) 1437135446Strhodes{ 1438135446Strhodes /* 1439135446Strhodes * The sdb rdataset is an rdatalist with some additions. 1440135446Strhodes * - private1 & private2 are used by the rdatalist. 1441135446Strhodes * - private3 & private 4 are unused. 1442135446Strhodes * - private5 is the node. 1443135446Strhodes */ 1444135446Strhodes 1445135446Strhodes /* This should never fail. */ 1446135446Strhodes RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == 1447135446Strhodes ISC_R_SUCCESS); 1448135446Strhodes 1449135446Strhodes rdataset->methods = &methods; 1450135446Strhodes dns_db_attachnode(db, node, &rdataset->private5); 1451135446Strhodes} 1452135446Strhodes 1453135446Strhodes/* 1454135446Strhodes * Database Iterator Methods 1455135446Strhodes */ 1456135446Strhodesstatic void 1457135446Strhodesdbiterator_destroy(dns_dbiterator_t **iteratorp) { 1458135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp); 1459135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db; 1460135446Strhodes 1461135446Strhodes while (!ISC_LIST_EMPTY(sdbiter->nodelist)) { 1462135446Strhodes dns_sdbnode_t *node; 1463135446Strhodes node = ISC_LIST_HEAD(sdbiter->nodelist); 1464135446Strhodes ISC_LIST_UNLINK(sdbiter->nodelist, node, link); 1465135446Strhodes destroynode(node); 1466135446Strhodes } 1467135446Strhodes 1468135446Strhodes dns_db_detach(&sdbiter->common.db); 1469135446Strhodes isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t)); 1470135446Strhodes 1471135446Strhodes *iteratorp = NULL; 1472135446Strhodes} 1473135446Strhodes 1474135446Strhodesstatic isc_result_t 1475135446Strhodesdbiterator_first(dns_dbiterator_t *iterator) { 1476135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1477135446Strhodes 1478135446Strhodes sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1479135446Strhodes if (sdbiter->current == NULL) 1480135446Strhodes return (ISC_R_NOMORE); 1481135446Strhodes else 1482135446Strhodes return (ISC_R_SUCCESS); 1483135446Strhodes} 1484135446Strhodes 1485135446Strhodesstatic isc_result_t 1486135446Strhodesdbiterator_last(dns_dbiterator_t *iterator) { 1487135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1488135446Strhodes 1489135446Strhodes sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist); 1490135446Strhodes if (sdbiter->current == NULL) 1491135446Strhodes return (ISC_R_NOMORE); 1492135446Strhodes else 1493135446Strhodes return (ISC_R_SUCCESS); 1494135446Strhodes} 1495135446Strhodes 1496135446Strhodesstatic isc_result_t 1497135446Strhodesdbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { 1498135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1499135446Strhodes 1500135446Strhodes sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1501204619Sdougb while (sdbiter->current != NULL) { 1502135446Strhodes if (dns_name_equal(sdbiter->current->name, name)) 1503135446Strhodes return (ISC_R_SUCCESS); 1504204619Sdougb sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); 1505204619Sdougb } 1506135446Strhodes return (ISC_R_NOTFOUND); 1507135446Strhodes} 1508135446Strhodes 1509135446Strhodesstatic isc_result_t 1510135446Strhodesdbiterator_prev(dns_dbiterator_t *iterator) { 1511135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1512135446Strhodes 1513135446Strhodes sdbiter->current = ISC_LIST_PREV(sdbiter->current, link); 1514135446Strhodes if (sdbiter->current == NULL) 1515135446Strhodes return (ISC_R_NOMORE); 1516135446Strhodes else 1517135446Strhodes return (ISC_R_SUCCESS); 1518135446Strhodes} 1519135446Strhodes 1520135446Strhodesstatic isc_result_t 1521135446Strhodesdbiterator_next(dns_dbiterator_t *iterator) { 1522135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1523135446Strhodes 1524135446Strhodes sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); 1525135446Strhodes if (sdbiter->current == NULL) 1526135446Strhodes return (ISC_R_NOMORE); 1527135446Strhodes else 1528135446Strhodes return (ISC_R_SUCCESS); 1529135446Strhodes} 1530135446Strhodes 1531135446Strhodesstatic isc_result_t 1532135446Strhodesdbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, 1533135446Strhodes dns_name_t *name) 1534135446Strhodes{ 1535135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1536135446Strhodes 1537135446Strhodes attachnode(iterator->db, sdbiter->current, nodep); 1538135446Strhodes if (name != NULL) 1539135446Strhodes return (dns_name_copy(sdbiter->current->name, name, NULL)); 1540135446Strhodes return (ISC_R_SUCCESS); 1541135446Strhodes} 1542135446Strhodes 1543135446Strhodesstatic isc_result_t 1544135446Strhodesdbiterator_pause(dns_dbiterator_t *iterator) { 1545135446Strhodes UNUSED(iterator); 1546135446Strhodes return (ISC_R_SUCCESS); 1547135446Strhodes} 1548135446Strhodes 1549135446Strhodesstatic isc_result_t 1550135446Strhodesdbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { 1551135446Strhodes UNUSED(iterator); 1552135446Strhodes return (dns_name_copy(dns_rootname, name, NULL)); 1553135446Strhodes} 1554135446Strhodes 1555135446Strhodes/* 1556135446Strhodes * Rdataset Iterator Methods 1557135446Strhodes */ 1558135446Strhodes 1559135446Strhodesstatic void 1560135446Strhodesrdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { 1561135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp); 1562135446Strhodes detachnode(sdbiterator->common.db, &sdbiterator->common.node); 1563135446Strhodes isc_mem_put(sdbiterator->common.db->mctx, sdbiterator, 1564135446Strhodes sizeof(sdb_rdatasetiter_t)); 1565135446Strhodes *iteratorp = NULL; 1566135446Strhodes} 1567135446Strhodes 1568135446Strhodesstatic isc_result_t 1569135446Strhodesrdatasetiter_first(dns_rdatasetiter_t *iterator) { 1570135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1571135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node; 1572135446Strhodes 1573135446Strhodes if (ISC_LIST_EMPTY(sdbnode->lists)) 1574135446Strhodes return (ISC_R_NOMORE); 1575135446Strhodes sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists); 1576135446Strhodes return (ISC_R_SUCCESS); 1577135446Strhodes} 1578135446Strhodes 1579135446Strhodesstatic isc_result_t 1580135446Strhodesrdatasetiter_next(dns_rdatasetiter_t *iterator) { 1581135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1582135446Strhodes 1583135446Strhodes sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link); 1584135446Strhodes if (sdbiterator->current == NULL) 1585135446Strhodes return (ISC_R_NOMORE); 1586135446Strhodes else 1587135446Strhodes return (ISC_R_SUCCESS); 1588135446Strhodes} 1589135446Strhodes 1590135446Strhodesstatic void 1591135446Strhodesrdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { 1592135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1593135446Strhodes 1594135446Strhodes list_tordataset(sdbiterator->current, iterator->db, iterator->node, 1595135446Strhodes rdataset); 1596135446Strhodes} 1597