sdb.c revision 236374
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 { 385135446Strhodes isc_buffer_init(&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; 451135446Strhodes isc_buffer_init(&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 731135446Strhodesfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, 732135446Strhodes dns_dbnode_t **nodep) 733135446Strhodes{ 734135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 735135446Strhodes dns_sdbnode_t *node = NULL; 736135446Strhodes isc_result_t result; 737135446Strhodes isc_buffer_t b; 738135446Strhodes char namestr[DNS_NAME_MAXTEXT + 1]; 739135446Strhodes isc_boolean_t isorigin; 740135446Strhodes dns_sdbimplementation_t *imp; 741236374Sdougb dns_name_t relname; 742236374Sdougb unsigned int labels; 743135446Strhodes 744135446Strhodes REQUIRE(VALID_SDB(sdb)); 745135446Strhodes REQUIRE(create == ISC_FALSE); 746135446Strhodes REQUIRE(nodep != NULL && *nodep == NULL); 747135446Strhodes 748135446Strhodes UNUSED(name); 749135446Strhodes UNUSED(create); 750135446Strhodes 751135446Strhodes imp = sdb->implementation; 752135446Strhodes 753236374Sdougb isorigin = dns_name_equal(name, &sdb->common.origin); 754135446Strhodes 755236374Sdougb if (imp->methods->lookup2 != NULL) { 756236374Sdougb if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { 757236374Sdougb labels = dns_name_countlabels(name) - 758236374Sdougb dns_name_countlabels(&db->origin); 759236374Sdougb dns_name_init(&relname, NULL); 760236374Sdougb dns_name_getlabelsequence(name, 0, labels, &relname); 761236374Sdougb name = &relname; 762236374Sdougb } 763135446Strhodes } else { 764236374Sdougb isc_buffer_init(&b, namestr, sizeof(namestr)); 765236374Sdougb if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { 766236374Sdougb 767236374Sdougb labels = dns_name_countlabels(name) - 768236374Sdougb dns_name_countlabels(&db->origin); 769236374Sdougb dns_name_init(&relname, NULL); 770236374Sdougb dns_name_getlabelsequence(name, 0, labels, &relname); 771236374Sdougb result = dns_name_totext(&relname, ISC_TRUE, &b); 772236374Sdougb if (result != ISC_R_SUCCESS) 773236374Sdougb return (result); 774236374Sdougb } else { 775236374Sdougb result = dns_name_totext(name, ISC_TRUE, &b); 776236374Sdougb if (result != ISC_R_SUCCESS) 777236374Sdougb return (result); 778236374Sdougb } 779236374Sdougb isc_buffer_putuint8(&b, 0); 780135446Strhodes } 781135446Strhodes 782135446Strhodes result = createnode(sdb, &node); 783135446Strhodes if (result != ISC_R_SUCCESS) 784135446Strhodes return (result); 785135446Strhodes 786135446Strhodes MAYBE_LOCK(sdb); 787236374Sdougb if (imp->methods->lookup2 != NULL) 788236374Sdougb result = imp->methods->lookup2(&sdb->common.origin, name, 789236374Sdougb sdb->dbdata, node); 790236374Sdougb else 791236374Sdougb result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, 792236374Sdougb node); 793135446Strhodes MAYBE_UNLOCK(sdb); 794135446Strhodes if (result != ISC_R_SUCCESS && 795135446Strhodes !(result == ISC_R_NOTFOUND && 796135446Strhodes isorigin && imp->methods->authority != NULL)) 797135446Strhodes { 798135446Strhodes destroynode(node); 799135446Strhodes return (result); 800135446Strhodes } 801135446Strhodes 802135446Strhodes if (isorigin && imp->methods->authority != NULL) { 803135446Strhodes MAYBE_LOCK(sdb); 804135446Strhodes result = imp->methods->authority(sdb->zone, sdb->dbdata, node); 805135446Strhodes MAYBE_UNLOCK(sdb); 806135446Strhodes if (result != ISC_R_SUCCESS) { 807135446Strhodes destroynode(node); 808135446Strhodes return (result); 809135446Strhodes } 810135446Strhodes } 811186462Sdougb 812135446Strhodes *nodep = node; 813135446Strhodes return (ISC_R_SUCCESS); 814135446Strhodes} 815135446Strhodes 816135446Strhodesstatic isc_result_t 817135446Strhodesfind(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, 818135446Strhodes dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, 819135446Strhodes dns_dbnode_t **nodep, dns_name_t *foundname, 820135446Strhodes dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 821135446Strhodes{ 822135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 823135446Strhodes dns_dbnode_t *node = NULL; 824135446Strhodes dns_fixedname_t fname; 825135446Strhodes dns_rdataset_t xrdataset; 826135446Strhodes dns_name_t *xname; 827135446Strhodes unsigned int nlabels, olabels; 828135446Strhodes isc_result_t result; 829135446Strhodes unsigned int i; 830236374Sdougb unsigned int flags; 831135446Strhodes 832135446Strhodes REQUIRE(VALID_SDB(sdb)); 833135446Strhodes REQUIRE(nodep == NULL || *nodep == NULL); 834135446Strhodes REQUIRE(version == NULL || version == (void *) &dummy); 835135446Strhodes 836135446Strhodes UNUSED(options); 837135446Strhodes 838135446Strhodes if (!dns_name_issubdomain(name, &db->origin)) 839135446Strhodes return (DNS_R_NXDOMAIN); 840135446Strhodes 841135446Strhodes olabels = dns_name_countlabels(&db->origin); 842135446Strhodes nlabels = dns_name_countlabels(name); 843135446Strhodes 844135446Strhodes dns_fixedname_init(&fname); 845135446Strhodes xname = dns_fixedname_name(&fname); 846135446Strhodes 847135446Strhodes if (rdataset == NULL) { 848135446Strhodes dns_rdataset_init(&xrdataset); 849135446Strhodes rdataset = &xrdataset; 850135446Strhodes } 851135446Strhodes 852135446Strhodes result = DNS_R_NXDOMAIN; 853236374Sdougb flags = sdb->implementation->flags; 854236374Sdougb i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels; 855236374Sdougb for (; i <= nlabels; i++) { 856135446Strhodes /* 857135446Strhodes * Look up the next label. 858135446Strhodes */ 859135446Strhodes dns_name_getlabelsequence(name, nlabels - i, i, xname); 860135446Strhodes result = findnode(db, xname, ISC_FALSE, &node); 861236374Sdougb if (result == ISC_R_NOTFOUND) { 862236374Sdougb /* 863236374Sdougb * No data at zone apex? 864236374Sdougb */ 865236374Sdougb if (i == olabels) 866236374Sdougb return (DNS_R_BADDB); 867135446Strhodes result = DNS_R_NXDOMAIN; 868135446Strhodes continue; 869135446Strhodes } 870236374Sdougb if (result != ISC_R_SUCCESS) 871236374Sdougb return (result); 872135446Strhodes 873135446Strhodes /* 874236374Sdougb * DNS64 zone's don't have DNAME or NS records. 875236374Sdougb */ 876236374Sdougb if ((flags & DNS_SDBFLAG_DNS64) != 0) 877236374Sdougb goto skip; 878236374Sdougb 879236374Sdougb /* 880236374Sdougb * DNS64 zone's don't have DNAME or NS records. 881236374Sdougb */ 882236374Sdougb if ((flags & DNS_SDBFLAG_DNS64) != 0) 883236374Sdougb goto skip; 884236374Sdougb 885236374Sdougb /* 886135446Strhodes * Look for a DNAME at the current label, unless this is 887135446Strhodes * the qname. 888135446Strhodes */ 889135446Strhodes if (i < nlabels) { 890135446Strhodes result = findrdataset(db, node, version, 891135446Strhodes dns_rdatatype_dname, 892135446Strhodes 0, now, rdataset, sigrdataset); 893135446Strhodes if (result == ISC_R_SUCCESS) { 894135446Strhodes result = DNS_R_DNAME; 895135446Strhodes break; 896135446Strhodes } 897135446Strhodes } 898135446Strhodes 899135446Strhodes /* 900135446Strhodes * Look for an NS at the current label, unless this is the 901135446Strhodes * origin or glue is ok. 902135446Strhodes */ 903135446Strhodes if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { 904135446Strhodes result = findrdataset(db, node, version, 905135446Strhodes dns_rdatatype_ns, 906135446Strhodes 0, now, rdataset, sigrdataset); 907135446Strhodes if (result == ISC_R_SUCCESS) { 908135446Strhodes if (i == nlabels && type == dns_rdatatype_any) 909135446Strhodes { 910135446Strhodes result = DNS_R_ZONECUT; 911135446Strhodes dns_rdataset_disassociate(rdataset); 912193149Sdougb if (sigrdataset != NULL && 913193149Sdougb dns_rdataset_isassociated 914193149Sdougb (sigrdataset)) { 915135446Strhodes dns_rdataset_disassociate 916135446Strhodes (sigrdataset); 917193149Sdougb } 918135446Strhodes } else 919135446Strhodes result = DNS_R_DELEGATION; 920135446Strhodes break; 921135446Strhodes } 922135446Strhodes } 923135446Strhodes 924135446Strhodes /* 925135446Strhodes * If the current name is not the qname, add another label 926135446Strhodes * and try again. 927135446Strhodes */ 928135446Strhodes if (i < nlabels) { 929135446Strhodes destroynode(node); 930135446Strhodes node = NULL; 931135446Strhodes continue; 932135446Strhodes } 933135446Strhodes 934236374Sdougb skip: 935135446Strhodes /* 936135446Strhodes * If we're looking for ANY, we're done. 937135446Strhodes */ 938135446Strhodes if (type == dns_rdatatype_any) { 939135446Strhodes result = ISC_R_SUCCESS; 940135446Strhodes break; 941135446Strhodes } 942135446Strhodes 943135446Strhodes /* 944135446Strhodes * Look for the qtype. 945135446Strhodes */ 946135446Strhodes result = findrdataset(db, node, version, type, 947135446Strhodes 0, now, rdataset, sigrdataset); 948135446Strhodes if (result == ISC_R_SUCCESS) 949135446Strhodes break; 950135446Strhodes 951135446Strhodes /* 952135446Strhodes * Look for a CNAME 953135446Strhodes */ 954135446Strhodes if (type != dns_rdatatype_cname) { 955135446Strhodes result = findrdataset(db, node, version, 956135446Strhodes dns_rdatatype_cname, 957135446Strhodes 0, now, rdataset, sigrdataset); 958135446Strhodes if (result == ISC_R_SUCCESS) { 959135446Strhodes result = DNS_R_CNAME; 960135446Strhodes break; 961135446Strhodes } 962135446Strhodes } 963135446Strhodes 964135446Strhodes result = DNS_R_NXRRSET; 965135446Strhodes break; 966135446Strhodes } 967135446Strhodes 968135446Strhodes if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) 969135446Strhodes dns_rdataset_disassociate(rdataset); 970135446Strhodes 971135446Strhodes if (foundname != NULL) { 972135446Strhodes isc_result_t xresult; 973135446Strhodes 974135446Strhodes xresult = dns_name_copy(xname, foundname, NULL); 975135446Strhodes if (xresult != ISC_R_SUCCESS) { 976170222Sdougb if (node != NULL) 977170222Sdougb destroynode(node); 978135446Strhodes if (dns_rdataset_isassociated(rdataset)) 979135446Strhodes dns_rdataset_disassociate(rdataset); 980135446Strhodes return (DNS_R_BADDB); 981135446Strhodes } 982135446Strhodes } 983135446Strhodes 984135446Strhodes if (nodep != NULL) 985135446Strhodes *nodep = node; 986135446Strhodes else if (node != NULL) 987135446Strhodes detachnode(db, &node); 988135446Strhodes 989135446Strhodes return (result); 990135446Strhodes} 991135446Strhodes 992135446Strhodesstatic isc_result_t 993135446Strhodesfindzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, 994135446Strhodes isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, 995135446Strhodes dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 996135446Strhodes{ 997135446Strhodes UNUSED(db); 998135446Strhodes UNUSED(name); 999135446Strhodes UNUSED(options); 1000135446Strhodes UNUSED(now); 1001135446Strhodes UNUSED(nodep); 1002135446Strhodes UNUSED(foundname); 1003135446Strhodes UNUSED(rdataset); 1004135446Strhodes UNUSED(sigrdataset); 1005135446Strhodes 1006135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1007135446Strhodes} 1008135446Strhodes 1009135446Strhodesstatic void 1010135446Strhodesattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { 1011135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1012135446Strhodes dns_sdbnode_t *node = (dns_sdbnode_t *)source; 1013135446Strhodes 1014135446Strhodes REQUIRE(VALID_SDB(sdb)); 1015135446Strhodes 1016135446Strhodes UNUSED(sdb); 1017135446Strhodes 1018135446Strhodes LOCK(&node->lock); 1019135446Strhodes INSIST(node->references > 0); 1020135446Strhodes node->references++; 1021135446Strhodes INSIST(node->references != 0); /* Catch overflow. */ 1022135446Strhodes UNLOCK(&node->lock); 1023135446Strhodes 1024135446Strhodes *targetp = source; 1025135446Strhodes} 1026135446Strhodes 1027135446Strhodesstatic void 1028135446Strhodesdetachnode(dns_db_t *db, dns_dbnode_t **targetp) { 1029135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1030135446Strhodes dns_sdbnode_t *node; 1031135446Strhodes isc_boolean_t need_destroy = ISC_FALSE; 1032135446Strhodes 1033135446Strhodes REQUIRE(VALID_SDB(sdb)); 1034135446Strhodes REQUIRE(targetp != NULL && *targetp != NULL); 1035135446Strhodes 1036135446Strhodes UNUSED(sdb); 1037135446Strhodes 1038135446Strhodes node = (dns_sdbnode_t *)(*targetp); 1039135446Strhodes 1040135446Strhodes LOCK(&node->lock); 1041135446Strhodes INSIST(node->references > 0); 1042135446Strhodes node->references--; 1043135446Strhodes if (node->references == 0) 1044135446Strhodes need_destroy = ISC_TRUE; 1045135446Strhodes UNLOCK(&node->lock); 1046135446Strhodes 1047135446Strhodes if (need_destroy) 1048135446Strhodes destroynode(node); 1049135446Strhodes 1050135446Strhodes *targetp = NULL; 1051135446Strhodes} 1052135446Strhodes 1053135446Strhodesstatic isc_result_t 1054135446Strhodesexpirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { 1055135446Strhodes UNUSED(db); 1056135446Strhodes UNUSED(node); 1057135446Strhodes UNUSED(now); 1058135446Strhodes INSIST(0); 1059135446Strhodes return (ISC_R_UNEXPECTED); 1060135446Strhodes} 1061135446Strhodes 1062135446Strhodesstatic void 1063135446Strhodesprintnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { 1064135446Strhodes UNUSED(db); 1065135446Strhodes UNUSED(node); 1066135446Strhodes UNUSED(out); 1067135446Strhodes return; 1068135446Strhodes} 1069135446Strhodes 1070135446Strhodesstatic isc_result_t 1071193149Sdougbcreateiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) 1072135446Strhodes{ 1073135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)db; 1074135446Strhodes sdb_dbiterator_t *sdbiter; 1075135446Strhodes dns_sdbimplementation_t *imp = sdb->implementation; 1076135446Strhodes isc_result_t result; 1077135446Strhodes 1078135446Strhodes REQUIRE(VALID_SDB(sdb)); 1079135446Strhodes 1080135446Strhodes if (imp->methods->allnodes == NULL) 1081135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1082135446Strhodes 1083193149Sdougb if ((options & DNS_DB_NSEC3ONLY) != 0 || 1084193149Sdougb (options & DNS_DB_NONSEC3) != 0) 1085193149Sdougb return (ISC_R_NOTIMPLEMENTED); 1086193149Sdougb 1087135446Strhodes sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t)); 1088135446Strhodes if (sdbiter == NULL) 1089135446Strhodes return (ISC_R_NOMEMORY); 1090135446Strhodes 1091135446Strhodes sdbiter->common.methods = &dbiterator_methods; 1092135446Strhodes sdbiter->common.db = NULL; 1093135446Strhodes dns_db_attach(db, &sdbiter->common.db); 1094193149Sdougb sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES); 1095135446Strhodes sdbiter->common.magic = DNS_DBITERATOR_MAGIC; 1096135446Strhodes ISC_LIST_INIT(sdbiter->nodelist); 1097135446Strhodes sdbiter->current = NULL; 1098135446Strhodes sdbiter->origin = NULL; 1099135446Strhodes 1100135446Strhodes MAYBE_LOCK(sdb); 1101135446Strhodes result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); 1102135446Strhodes MAYBE_UNLOCK(sdb); 1103135446Strhodes if (result != ISC_R_SUCCESS) { 1104135446Strhodes dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter); 1105135446Strhodes return (result); 1106135446Strhodes } 1107135446Strhodes 1108135446Strhodes if (sdbiter->origin != NULL) { 1109135446Strhodes ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link); 1110135446Strhodes ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link); 1111135446Strhodes } 1112135446Strhodes 1113135446Strhodes *iteratorp = (dns_dbiterator_t *)sdbiter; 1114135446Strhodes 1115135446Strhodes return (ISC_R_SUCCESS); 1116135446Strhodes} 1117135446Strhodes 1118135446Strhodesstatic isc_result_t 1119135446Strhodesfindrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1120135446Strhodes dns_rdatatype_t type, dns_rdatatype_t covers, 1121135446Strhodes isc_stdtime_t now, dns_rdataset_t *rdataset, 1122135446Strhodes dns_rdataset_t *sigrdataset) 1123135446Strhodes{ 1124135446Strhodes dns_rdatalist_t *list; 1125135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node; 1126135446Strhodes 1127135446Strhodes REQUIRE(VALID_SDBNODE(node)); 1128135446Strhodes 1129135446Strhodes UNUSED(db); 1130135446Strhodes UNUSED(version); 1131135446Strhodes UNUSED(covers); 1132135446Strhodes UNUSED(now); 1133135446Strhodes UNUSED(sigrdataset); 1134135446Strhodes 1135135446Strhodes if (type == dns_rdatatype_rrsig) 1136135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1137135446Strhodes 1138135446Strhodes list = ISC_LIST_HEAD(sdbnode->lists); 1139135446Strhodes while (list != NULL) { 1140135446Strhodes if (list->type == type) 1141135446Strhodes break; 1142135446Strhodes list = ISC_LIST_NEXT(list, link); 1143135446Strhodes } 1144135446Strhodes if (list == NULL) 1145135446Strhodes return (ISC_R_NOTFOUND); 1146135446Strhodes 1147135446Strhodes list_tordataset(list, db, node, rdataset); 1148135446Strhodes 1149135446Strhodes return (ISC_R_SUCCESS); 1150135446Strhodes} 1151135446Strhodes 1152135446Strhodesstatic isc_result_t 1153135446Strhodesallrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1154135446Strhodes isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) 1155135446Strhodes{ 1156135446Strhodes sdb_rdatasetiter_t *iterator; 1157135446Strhodes 1158135446Strhodes REQUIRE(version == NULL || version == &dummy); 1159186462Sdougb 1160135446Strhodes UNUSED(version); 1161135446Strhodes UNUSED(now); 1162135446Strhodes 1163135446Strhodes iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t)); 1164135446Strhodes if (iterator == NULL) 1165135446Strhodes return (ISC_R_NOMEMORY); 1166135446Strhodes 1167135446Strhodes iterator->common.magic = DNS_RDATASETITER_MAGIC; 1168135446Strhodes iterator->common.methods = &rdatasetiter_methods; 1169135446Strhodes iterator->common.db = db; 1170135446Strhodes iterator->common.node = NULL; 1171135446Strhodes attachnode(db, node, &iterator->common.node); 1172135446Strhodes iterator->common.version = version; 1173135446Strhodes iterator->common.now = now; 1174135446Strhodes 1175135446Strhodes *iteratorp = (dns_rdatasetiter_t *)iterator; 1176135446Strhodes 1177135446Strhodes return (ISC_R_SUCCESS); 1178135446Strhodes} 1179135446Strhodes 1180135446Strhodesstatic isc_result_t 1181135446Strhodesaddrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1182135446Strhodes isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, 1183135446Strhodes dns_rdataset_t *addedrdataset) 1184135446Strhodes{ 1185135446Strhodes UNUSED(db); 1186135446Strhodes UNUSED(node); 1187135446Strhodes UNUSED(version); 1188135446Strhodes UNUSED(now); 1189135446Strhodes UNUSED(rdataset); 1190135446Strhodes UNUSED(options); 1191135446Strhodes UNUSED(addedrdataset); 1192135446Strhodes 1193135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1194135446Strhodes} 1195135446Strhodes 1196135446Strhodesstatic isc_result_t 1197135446Strhodessubtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1198135446Strhodes dns_rdataset_t *rdataset, unsigned int options, 1199135446Strhodes dns_rdataset_t *newrdataset) 1200135446Strhodes{ 1201135446Strhodes UNUSED(db); 1202135446Strhodes UNUSED(node); 1203135446Strhodes UNUSED(version); 1204135446Strhodes UNUSED(rdataset); 1205135446Strhodes UNUSED(options); 1206135446Strhodes UNUSED(newrdataset); 1207135446Strhodes 1208135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1209135446Strhodes} 1210135446Strhodes 1211135446Strhodesstatic isc_result_t 1212135446Strhodesdeleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1213135446Strhodes dns_rdatatype_t type, dns_rdatatype_t covers) 1214135446Strhodes{ 1215135446Strhodes UNUSED(db); 1216135446Strhodes UNUSED(node); 1217135446Strhodes UNUSED(version); 1218135446Strhodes UNUSED(type); 1219135446Strhodes UNUSED(covers); 1220135446Strhodes 1221135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1222135446Strhodes} 1223135446Strhodes 1224135446Strhodesstatic isc_boolean_t 1225135446Strhodesissecure(dns_db_t *db) { 1226135446Strhodes UNUSED(db); 1227135446Strhodes 1228135446Strhodes return (ISC_FALSE); 1229135446Strhodes} 1230135446Strhodes 1231135446Strhodesstatic unsigned int 1232135446Strhodesnodecount(dns_db_t *db) { 1233135446Strhodes UNUSED(db); 1234135446Strhodes 1235135446Strhodes return (0); 1236135446Strhodes} 1237135446Strhodes 1238135446Strhodesstatic isc_boolean_t 1239135446Strhodesispersistent(dns_db_t *db) { 1240135446Strhodes UNUSED(db); 1241135446Strhodes return (ISC_TRUE); 1242135446Strhodes} 1243135446Strhodes 1244135446Strhodesstatic void 1245135446Strhodesovermem(dns_db_t *db, isc_boolean_t overmem) { 1246135446Strhodes UNUSED(db); 1247135446Strhodes UNUSED(overmem); 1248135446Strhodes} 1249135446Strhodes 1250135446Strhodesstatic void 1251135446Strhodessettask(dns_db_t *db, isc_task_t *task) { 1252135446Strhodes UNUSED(db); 1253135446Strhodes UNUSED(task); 1254135446Strhodes} 1255135446Strhodes 1256135446Strhodes 1257135446Strhodesstatic dns_dbmethods_t sdb_methods = { 1258135446Strhodes attach, 1259135446Strhodes detach, 1260135446Strhodes beginload, 1261135446Strhodes endload, 1262135446Strhodes dump, 1263135446Strhodes currentversion, 1264135446Strhodes newversion, 1265135446Strhodes attachversion, 1266135446Strhodes closeversion, 1267135446Strhodes findnode, 1268135446Strhodes find, 1269135446Strhodes findzonecut, 1270135446Strhodes attachnode, 1271135446Strhodes detachnode, 1272135446Strhodes expirenode, 1273135446Strhodes printnode, 1274135446Strhodes createiterator, 1275135446Strhodes findrdataset, 1276135446Strhodes allrdatasets, 1277135446Strhodes addrdataset, 1278135446Strhodes subtractrdataset, 1279135446Strhodes deleterdataset, 1280135446Strhodes issecure, 1281135446Strhodes nodecount, 1282135446Strhodes ispersistent, 1283135446Strhodes overmem, 1284170222Sdougb settask, 1285193149Sdougb NULL, 1286193149Sdougb NULL, 1287193149Sdougb NULL, 1288193149Sdougb NULL, 1289193149Sdougb NULL, 1290193149Sdougb NULL, 1291193149Sdougb NULL, 1292193149Sdougb NULL, 1293224092Sdougb NULL, 1294224092Sdougb NULL, 1295170222Sdougb NULL 1296135446Strhodes}; 1297135446Strhodes 1298135446Strhodesstatic isc_result_t 1299135446Strhodesdns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, 1300135446Strhodes dns_rdataclass_t rdclass, unsigned int argc, char *argv[], 1301135446Strhodes void *driverarg, dns_db_t **dbp) 1302135446Strhodes{ 1303135446Strhodes dns_sdb_t *sdb; 1304135446Strhodes isc_result_t result; 1305135446Strhodes char zonestr[DNS_NAME_MAXTEXT + 1]; 1306135446Strhodes isc_buffer_t b; 1307135446Strhodes dns_sdbimplementation_t *imp; 1308135446Strhodes 1309135446Strhodes REQUIRE(driverarg != NULL); 1310135446Strhodes 1311135446Strhodes imp = driverarg; 1312135446Strhodes 1313135446Strhodes if (type != dns_dbtype_zone) 1314135446Strhodes return (ISC_R_NOTIMPLEMENTED); 1315135446Strhodes 1316135446Strhodes sdb = isc_mem_get(mctx, sizeof(dns_sdb_t)); 1317135446Strhodes if (sdb == NULL) 1318135446Strhodes return (ISC_R_NOMEMORY); 1319135446Strhodes memset(sdb, 0, sizeof(dns_sdb_t)); 1320135446Strhodes 1321135446Strhodes dns_name_init(&sdb->common.origin, NULL); 1322135446Strhodes sdb->common.attributes = 0; 1323135446Strhodes sdb->common.methods = &sdb_methods; 1324135446Strhodes sdb->common.rdclass = rdclass; 1325135446Strhodes sdb->common.mctx = NULL; 1326135446Strhodes sdb->implementation = imp; 1327135446Strhodes 1328135446Strhodes isc_mem_attach(mctx, &sdb->common.mctx); 1329135446Strhodes 1330135446Strhodes result = isc_mutex_init(&sdb->lock); 1331170222Sdougb if (result != ISC_R_SUCCESS) 1332135446Strhodes goto cleanup_mctx; 1333135446Strhodes 1334135446Strhodes result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); 1335135446Strhodes if (result != ISC_R_SUCCESS) 1336135446Strhodes goto cleanup_lock; 1337135446Strhodes 1338135446Strhodes isc_buffer_init(&b, zonestr, sizeof(zonestr)); 1339135446Strhodes result = dns_name_totext(origin, ISC_TRUE, &b); 1340135446Strhodes if (result != ISC_R_SUCCESS) 1341135446Strhodes goto cleanup_origin; 1342135446Strhodes isc_buffer_putuint8(&b, 0); 1343135446Strhodes 1344135446Strhodes sdb->zone = isc_mem_strdup(mctx, zonestr); 1345135446Strhodes if (sdb->zone == NULL) { 1346135446Strhodes result = ISC_R_NOMEMORY; 1347135446Strhodes goto cleanup_origin; 1348135446Strhodes } 1349135446Strhodes 1350135446Strhodes sdb->dbdata = NULL; 1351135446Strhodes if (imp->methods->create != NULL) { 1352135446Strhodes MAYBE_LOCK(sdb); 1353135446Strhodes result = imp->methods->create(sdb->zone, argc, argv, 1354135446Strhodes imp->driverdata, &sdb->dbdata); 1355135446Strhodes MAYBE_UNLOCK(sdb); 1356135446Strhodes if (result != ISC_R_SUCCESS) 1357135446Strhodes goto cleanup_zonestr; 1358135446Strhodes } 1359135446Strhodes 1360135446Strhodes sdb->references = 1; 1361135446Strhodes 1362135446Strhodes sdb->common.magic = DNS_DB_MAGIC; 1363135446Strhodes sdb->common.impmagic = SDB_MAGIC; 1364135446Strhodes 1365135446Strhodes *dbp = (dns_db_t *)sdb; 1366135446Strhodes 1367135446Strhodes return (ISC_R_SUCCESS); 1368135446Strhodes 1369135446Strhodes cleanup_zonestr: 1370135446Strhodes isc_mem_free(mctx, sdb->zone); 1371135446Strhodes cleanup_origin: 1372135446Strhodes dns_name_free(&sdb->common.origin, mctx); 1373135446Strhodes cleanup_lock: 1374225361Sdougb (void)isc_mutex_destroy(&sdb->lock); 1375135446Strhodes cleanup_mctx: 1376135446Strhodes isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); 1377135446Strhodes isc_mem_detach(&mctx); 1378135446Strhodes 1379135446Strhodes return (result); 1380135446Strhodes} 1381135446Strhodes 1382135446Strhodes 1383135446Strhodes/* 1384135446Strhodes * Rdataset Methods 1385135446Strhodes */ 1386135446Strhodes 1387135446Strhodesstatic void 1388135446Strhodesdisassociate(dns_rdataset_t *rdataset) { 1389135446Strhodes dns_dbnode_t *node = rdataset->private5; 1390135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1391135446Strhodes dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1392135446Strhodes 1393135446Strhodes detachnode(db, &node); 1394135446Strhodes isc__rdatalist_disassociate(rdataset); 1395135446Strhodes} 1396135446Strhodes 1397135446Strhodesstatic void 1398135446Strhodesrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { 1399135446Strhodes dns_dbnode_t *node = source->private5; 1400135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1401135446Strhodes dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1402135446Strhodes dns_dbnode_t *tempdb = NULL; 1403135446Strhodes 1404135446Strhodes isc__rdatalist_clone(source, target); 1405135446Strhodes attachnode(db, node, &tempdb); 1406135446Strhodes source->private5 = tempdb; 1407135446Strhodes} 1408135446Strhodes 1409135446Strhodesstatic dns_rdatasetmethods_t methods = { 1410135446Strhodes disassociate, 1411135446Strhodes isc__rdatalist_first, 1412135446Strhodes isc__rdatalist_next, 1413135446Strhodes isc__rdatalist_current, 1414135446Strhodes rdataset_clone, 1415135446Strhodes isc__rdatalist_count, 1416135446Strhodes isc__rdatalist_addnoqname, 1417170222Sdougb isc__rdatalist_getnoqname, 1418170222Sdougb NULL, 1419170222Sdougb NULL, 1420193149Sdougb NULL, 1421193149Sdougb NULL, 1422205292Sdougb NULL, 1423205292Sdougb NULL, 1424170222Sdougb NULL 1425135446Strhodes}; 1426135446Strhodes 1427135446Strhodesstatic void 1428135446Strhodeslist_tordataset(dns_rdatalist_t *rdatalist, 1429135446Strhodes dns_db_t *db, dns_dbnode_t *node, 1430135446Strhodes dns_rdataset_t *rdataset) 1431135446Strhodes{ 1432135446Strhodes /* 1433135446Strhodes * The sdb rdataset is an rdatalist with some additions. 1434135446Strhodes * - private1 & private2 are used by the rdatalist. 1435135446Strhodes * - private3 & private 4 are unused. 1436135446Strhodes * - private5 is the node. 1437135446Strhodes */ 1438135446Strhodes 1439135446Strhodes /* This should never fail. */ 1440135446Strhodes RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == 1441135446Strhodes ISC_R_SUCCESS); 1442135446Strhodes 1443135446Strhodes rdataset->methods = &methods; 1444135446Strhodes dns_db_attachnode(db, node, &rdataset->private5); 1445135446Strhodes} 1446135446Strhodes 1447135446Strhodes/* 1448135446Strhodes * Database Iterator Methods 1449135446Strhodes */ 1450135446Strhodesstatic void 1451135446Strhodesdbiterator_destroy(dns_dbiterator_t **iteratorp) { 1452135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp); 1453135446Strhodes dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db; 1454135446Strhodes 1455135446Strhodes while (!ISC_LIST_EMPTY(sdbiter->nodelist)) { 1456135446Strhodes dns_sdbnode_t *node; 1457135446Strhodes node = ISC_LIST_HEAD(sdbiter->nodelist); 1458135446Strhodes ISC_LIST_UNLINK(sdbiter->nodelist, node, link); 1459135446Strhodes destroynode(node); 1460135446Strhodes } 1461135446Strhodes 1462135446Strhodes dns_db_detach(&sdbiter->common.db); 1463135446Strhodes isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t)); 1464135446Strhodes 1465135446Strhodes *iteratorp = NULL; 1466135446Strhodes} 1467135446Strhodes 1468135446Strhodesstatic isc_result_t 1469135446Strhodesdbiterator_first(dns_dbiterator_t *iterator) { 1470135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1471135446Strhodes 1472135446Strhodes sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1473135446Strhodes if (sdbiter->current == NULL) 1474135446Strhodes return (ISC_R_NOMORE); 1475135446Strhodes else 1476135446Strhodes return (ISC_R_SUCCESS); 1477135446Strhodes} 1478135446Strhodes 1479135446Strhodesstatic isc_result_t 1480135446Strhodesdbiterator_last(dns_dbiterator_t *iterator) { 1481135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1482135446Strhodes 1483135446Strhodes sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist); 1484135446Strhodes if (sdbiter->current == NULL) 1485135446Strhodes return (ISC_R_NOMORE); 1486135446Strhodes else 1487135446Strhodes return (ISC_R_SUCCESS); 1488135446Strhodes} 1489135446Strhodes 1490135446Strhodesstatic isc_result_t 1491135446Strhodesdbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { 1492135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1493135446Strhodes 1494135446Strhodes sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1495204619Sdougb while (sdbiter->current != NULL) { 1496135446Strhodes if (dns_name_equal(sdbiter->current->name, name)) 1497135446Strhodes return (ISC_R_SUCCESS); 1498204619Sdougb sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); 1499204619Sdougb } 1500135446Strhodes return (ISC_R_NOTFOUND); 1501135446Strhodes} 1502135446Strhodes 1503135446Strhodesstatic isc_result_t 1504135446Strhodesdbiterator_prev(dns_dbiterator_t *iterator) { 1505135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1506135446Strhodes 1507135446Strhodes sdbiter->current = ISC_LIST_PREV(sdbiter->current, link); 1508135446Strhodes if (sdbiter->current == NULL) 1509135446Strhodes return (ISC_R_NOMORE); 1510135446Strhodes else 1511135446Strhodes return (ISC_R_SUCCESS); 1512135446Strhodes} 1513135446Strhodes 1514135446Strhodesstatic isc_result_t 1515135446Strhodesdbiterator_next(dns_dbiterator_t *iterator) { 1516135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1517135446Strhodes 1518135446Strhodes sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); 1519135446Strhodes if (sdbiter->current == NULL) 1520135446Strhodes return (ISC_R_NOMORE); 1521135446Strhodes else 1522135446Strhodes return (ISC_R_SUCCESS); 1523135446Strhodes} 1524135446Strhodes 1525135446Strhodesstatic isc_result_t 1526135446Strhodesdbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, 1527135446Strhodes dns_name_t *name) 1528135446Strhodes{ 1529135446Strhodes sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1530135446Strhodes 1531135446Strhodes attachnode(iterator->db, sdbiter->current, nodep); 1532135446Strhodes if (name != NULL) 1533135446Strhodes return (dns_name_copy(sdbiter->current->name, name, NULL)); 1534135446Strhodes return (ISC_R_SUCCESS); 1535135446Strhodes} 1536135446Strhodes 1537135446Strhodesstatic isc_result_t 1538135446Strhodesdbiterator_pause(dns_dbiterator_t *iterator) { 1539135446Strhodes UNUSED(iterator); 1540135446Strhodes return (ISC_R_SUCCESS); 1541135446Strhodes} 1542135446Strhodes 1543135446Strhodesstatic isc_result_t 1544135446Strhodesdbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { 1545135446Strhodes UNUSED(iterator); 1546135446Strhodes return (dns_name_copy(dns_rootname, name, NULL)); 1547135446Strhodes} 1548135446Strhodes 1549135446Strhodes/* 1550135446Strhodes * Rdataset Iterator Methods 1551135446Strhodes */ 1552135446Strhodes 1553135446Strhodesstatic void 1554135446Strhodesrdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { 1555135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp); 1556135446Strhodes detachnode(sdbiterator->common.db, &sdbiterator->common.node); 1557135446Strhodes isc_mem_put(sdbiterator->common.db->mctx, sdbiterator, 1558135446Strhodes sizeof(sdb_rdatasetiter_t)); 1559135446Strhodes *iteratorp = NULL; 1560135446Strhodes} 1561135446Strhodes 1562135446Strhodesstatic isc_result_t 1563135446Strhodesrdatasetiter_first(dns_rdatasetiter_t *iterator) { 1564135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1565135446Strhodes dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node; 1566135446Strhodes 1567135446Strhodes if (ISC_LIST_EMPTY(sdbnode->lists)) 1568135446Strhodes return (ISC_R_NOMORE); 1569135446Strhodes sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists); 1570135446Strhodes return (ISC_R_SUCCESS); 1571135446Strhodes} 1572135446Strhodes 1573135446Strhodesstatic isc_result_t 1574135446Strhodesrdatasetiter_next(dns_rdatasetiter_t *iterator) { 1575135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1576135446Strhodes 1577135446Strhodes sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link); 1578135446Strhodes if (sdbiterator->current == NULL) 1579135446Strhodes return (ISC_R_NOMORE); 1580135446Strhodes else 1581135446Strhodes return (ISC_R_SUCCESS); 1582135446Strhodes} 1583135446Strhodes 1584135446Strhodesstatic void 1585135446Strhodesrdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { 1586135446Strhodes sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1587135446Strhodes 1588135446Strhodes list_tordataset(sdbiterator->current, iterator->db, iterator->node, 1589135446Strhodes rdataset); 1590135446Strhodes} 1591