sdb.c revision 193149
1163953Srrs/* 2169382Srrs * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") 3218319Srrs * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. 4218319Srrs * 5163953Srrs * Permission to use, copy, modify, and/or distribute this software for any 6163953Srrs * purpose with or without fee is hereby granted, provided that the above 7163953Srrs * copyright notice and this permission notice appear in all copies. 8163953Srrs * 9163953Srrs * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10231038Stuexen * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11163953Srrs * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12163953Srrs * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13163953Srrs * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14231038Stuexen * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15163953Srrs * PERFORMANCE OF THIS SOFTWARE. 16163953Srrs */ 17163953Srrs 18163953Srrs/* $Id: sdb.c,v 1.66.48.2 2009/04/21 23:47:18 tbox Exp $ */ 19163953Srrs 20163953Srrs/*! \file */ 21163953Srrs 22163953Srrs#include <config.h> 23163953Srrs 24163953Srrs#include <string.h> 25163953Srrs 26163953Srrs#include <isc/buffer.h> 27163953Srrs#include <isc/lex.h> 28163953Srrs#include <isc/log.h> 29163953Srrs#include <isc/magic.h> 30163953Srrs#include <isc/mem.h> 31163953Srrs#include <isc/once.h> 32163953Srrs#include <isc/print.h> 33163953Srrs#include <isc/region.h> 34163953Srrs#include <isc/util.h> 35163953Srrs 36163953Srrs#include <dns/callbacks.h> 37163953Srrs#include <dns/db.h> 38163953Srrs#include <dns/dbiterator.h> 39166086Srrs#include <dns/fixedname.h> 40163953Srrs#include <dns/log.h> 41163953Srrs#include <dns/rdata.h> 42163953Srrs#include <dns/rdatalist.h> 43163953Srrs#include <dns/rdataset.h> 44167598Srrs#include <dns/rdatasetiter.h> 45163953Srrs#include <dns/rdatatype.h> 46163953Srrs#include <dns/result.h> 47163953Srrs#include <dns/sdb.h> 48163953Srrs#include <dns/types.h> 49163953Srrs 50163953Srrs#include "rdatalist_p.h" 51163953Srrs 52163953Srrsstruct dns_sdbimplementation { 53163953Srrs const dns_sdbmethods_t *methods; 54185694Srrs void *driverdata; 55163953Srrs unsigned int flags; 56163953Srrs isc_mem_t *mctx; 57163953Srrs isc_mutex_t driverlock; 58163953Srrs dns_dbimplementation_t *dbimp; 59163953Srrs}; 60163953Srrs 61163953Srrsstruct dns_sdb { 62169420Srrs /* Unlocked */ 63169420Srrs dns_db_t common; 64169420Srrs char *zone; 65163953Srrs dns_sdbimplementation_t *implementation; 66163953Srrs void *dbdata; 67163953Srrs isc_mutex_t lock; 68163953Srrs /* Locked */ 69163953Srrs unsigned int references; 70163953Srrs}; 71163953Srrs 72163953Srrsstruct dns_sdblookup { 73163953Srrs /* Unlocked */ 74163953Srrs unsigned int magic; 75163953Srrs dns_sdb_t *sdb; 76163953Srrs ISC_LIST(dns_rdatalist_t) lists; 77163953Srrs ISC_LIST(isc_buffer_t) buffers; 78179157Srrs dns_name_t *name; 79179157Srrs ISC_LINK(dns_sdblookup_t) link; 80179157Srrs isc_mutex_t lock; 81179157Srrs dns_rdatacallbacks_t callbacks; 82179157Srrs /* Locked */ 83169420Srrs unsigned int references; 84169420Srrs}; 85169420Srrs 86163953Srrstypedef struct dns_sdblookup dns_sdbnode_t; 87163953Srrs 88163953Srrsstruct dns_sdballnodes { 89163953Srrs dns_dbiterator_t common; 90163953Srrs ISC_LIST(dns_sdbnode_t) nodelist; 91163953Srrs dns_sdbnode_t *current; 92163953Srrs dns_sdbnode_t *origin; 93163953Srrs}; 94169420Srrs 95169420Srrstypedef dns_sdballnodes_t sdb_dbiterator_t; 96169420Srrs 97163953Srrstypedef struct sdb_rdatasetiter { 98163953Srrs dns_rdatasetiter_t common; 99163953Srrs dns_rdatalist_t *current; 100163953Srrs} sdb_rdatasetiter_t; 101167598Srrs 102224641Stuexen#define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-') 103163953Srrs 104163953Srrs/*% 105163953Srrs * Note that "impmagic" is not the first four bytes of the struct, so 106172090Srrs * ISC_MAGIC_VALID cannot be used. 107163953Srrs */ 108224641Stuexen#define VALID_SDB(sdb) ((sdb) != NULL && \ 109224641Stuexen (sdb)->common.impmagic == SDB_MAGIC) 110224641Stuexen 111224641Stuexen#define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L') 112224641Stuexen#define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC) 113224641Stuexen#define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn) 114224641Stuexen 115224641Stuexen/* These values are taken from RFC1537 */ 116224641Stuexen#define SDB_DEFAULT_REFRESH (60 * 60 * 8) 117163953Srrs#define SDB_DEFAULT_RETRY (60 * 60 * 2) 118163953Srrs#define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7) 119163953Srrs#define SDB_DEFAULT_MINIMUM (60 * 60 * 24) 120163953Srrs 121163953Srrs/* This is a reasonable value */ 122163953Srrs#define SDB_DEFAULT_TTL (60 * 60 * 24) 123163953Srrs 124179783Srrs#ifdef __COVERITY__ 125171943Srrs#define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock) 126171943Srrs#define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock) 127171943Srrs#else 128171943Srrs#define MAYBE_LOCK(sdb) \ 129171943Srrs do { \ 130171943Srrs unsigned int flags = sdb->implementation->flags; \ 131163953Srrs if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ 132163953Srrs LOCK(&sdb->implementation->driverlock); \ 133163953Srrs } while (0) 134179783Srrs 135171943Srrs#define MAYBE_UNLOCK(sdb) \ 136171943Srrs do { \ 137171943Srrs unsigned int flags = sdb->implementation->flags; \ 138171943Srrs if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ 139171943Srrs UNLOCK(&sdb->implementation->driverlock); \ 140171943Srrs } while (0) 141163953Srrs#endif 142163953Srrs 143169420Srrsstatic int dummy; 144169420Srrs 145169420Srrsstatic isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, 146169420Srrs dns_dbtype_t type, dns_rdataclass_t rdclass, 147163953Srrs unsigned int argc, char *argv[], 148163953Srrs void *driverarg, dns_db_t **dbp); 149163953Srrs 150163953Srrsstatic isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, 151163953Srrs dns_dbversion_t *version, 152163953Srrs dns_rdatatype_t type, dns_rdatatype_t covers, 153163953Srrs isc_stdtime_t now, dns_rdataset_t *rdataset, 154163953Srrs dns_rdataset_t *sigrdataset); 155163953Srrs 156163953Srrsstatic isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep); 157163953Srrs 158163953Srrsstatic void destroynode(dns_sdbnode_t *node); 159163953Srrs 160163953Srrsstatic void detachnode(dns_db_t *db, dns_dbnode_t **targetp); 161165647Srrs 162163953Srrs 163163953Srrsstatic void list_tordataset(dns_rdatalist_t *rdatalist, 164163953Srrs dns_db_t *db, dns_dbnode_t *node, 165165647Srrs dns_rdataset_t *rdataset); 166163953Srrs 167165220Srrsstatic void dbiterator_destroy(dns_dbiterator_t **iteratorp); 168163953Srrsstatic isc_result_t dbiterator_first(dns_dbiterator_t *iterator); 169165220Srrsstatic isc_result_t dbiterator_last(dns_dbiterator_t *iterator); 170172090Srrsstatic isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, 171163953Srrs dns_name_t *name); 172163953Srrsstatic isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); 173163953Srrsstatic isc_result_t dbiterator_next(dns_dbiterator_t *iterator); 174163953Srrsstatic isc_result_t dbiterator_current(dns_dbiterator_t *iterator, 175163953Srrs dns_dbnode_t **nodep, 176214928Stuexen dns_name_t *name); 177214928Stuexenstatic isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); 178214928Stuexenstatic isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, 179214928Stuexen dns_name_t *name); 180163953Srrs 181163953Srrsstatic dns_dbiteratormethods_t dbiterator_methods = { 182163953Srrs dbiterator_destroy, 183171440Srrs dbiterator_first, 184163953Srrs dbiterator_last, 185163953Srrs dbiterator_seek, 186171440Srrs dbiterator_prev, 187163953Srrs dbiterator_next, 188163953Srrs dbiterator_current, 189171440Srrs dbiterator_pause, 190171440Srrs dbiterator_origin 191171440Srrs}; 192171440Srrs 193163953Srrsstatic void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); 194163953Srrsstatic isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); 195163953Srrsstatic isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); 196163953Srrsstatic void rdatasetiter_current(dns_rdatasetiter_t *iterator, 197171440Srrs dns_rdataset_t *rdataset); 198171440Srrs 199171440Srrsstatic dns_rdatasetitermethods_t rdatasetiter_methods = { 200171440Srrs rdatasetiter_destroy, 201171440Srrs rdatasetiter_first, 202171440Srrs rdatasetiter_next, 203171440Srrs rdatasetiter_current 204171440Srrs}; 205171440Srrs 206163953Srrs/* 207171440Srrs * Functions used by implementors of simple databases 208171440Srrs */ 209171440Srrsisc_result_t 210171440Srrsdns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, 211163953Srrs void *driverdata, unsigned int flags, isc_mem_t *mctx, 212171440Srrs dns_sdbimplementation_t **sdbimp) 213171440Srrs{ 214171440Srrs dns_sdbimplementation_t *imp; 215171440Srrs isc_result_t result; 216171440Srrs 217171440Srrs REQUIRE(drivername != NULL); 218171440Srrs REQUIRE(methods != NULL); 219171440Srrs REQUIRE(methods->lookup != NULL); 220171440Srrs REQUIRE(mctx != NULL); 221171440Srrs REQUIRE(sdbimp != NULL && *sdbimp == NULL); 222171440Srrs REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | 223171440Srrs DNS_SDBFLAG_RELATIVERDATA | 224171440Srrs DNS_SDBFLAG_THREADSAFE)) == 0); 225171440Srrs 226171440Srrs imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); 227171440Srrs if (imp == NULL) 228171440Srrs return (ISC_R_NOMEMORY); 229171440Srrs imp->methods = methods; 230171440Srrs imp->driverdata = driverdata; 231171440Srrs imp->flags = flags; 232171440Srrs imp->mctx = NULL; 233171440Srrs isc_mem_attach(mctx, &imp->mctx); 234171440Srrs result = isc_mutex_init(&imp->driverlock); 235171440Srrs if (result != ISC_R_SUCCESS) 236171440Srrs goto cleanup_mctx; 237171440Srrs 238171440Srrs imp->dbimp = NULL; 239171440Srrs result = dns_db_register(drivername, dns_sdb_create, imp, mctx, 240171440Srrs &imp->dbimp); 241171440Srrs if (result != ISC_R_SUCCESS) 242171440Srrs goto cleanup_mutex; 243171440Srrs *sdbimp = imp; 244171440Srrs 245171440Srrs return (ISC_R_SUCCESS); 246171440Srrs 247171440Srrs cleanup_mutex: 248171440Srrs DESTROYLOCK(&imp->driverlock); 249171440Srrs cleanup_mctx: 250171440Srrs isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); 251171440Srrs return (result); 252171440Srrs} 253171440Srrs 254171440Srrsvoid 255171440Srrsdns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { 256171440Srrs dns_sdbimplementation_t *imp; 257171440Srrs isc_mem_t *mctx; 258171440Srrs 259171440Srrs REQUIRE(sdbimp != NULL && *sdbimp != NULL); 260171440Srrs 261171440Srrs imp = *sdbimp; 262171440Srrs dns_db_unregister(&imp->dbimp); 263171440Srrs DESTROYLOCK(&imp->driverlock); 264171440Srrs 265171440Srrs mctx = imp->mctx; 266171440Srrs isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); 267171440Srrs isc_mem_detach(&mctx); 268171440Srrs 269171440Srrs *sdbimp = NULL; 270171440Srrs} 271171440Srrs 272171440Srrsstatic inline unsigned int 273171440Srrsinitial_size(unsigned int len) { 274171440Srrs unsigned int size; 275171440Srrs 276171440Srrs for (size = 1024; size < (64 * 1024); size *= 2) 277171440Srrs if (len < size) 278171440Srrs return (size); 279171440Srrs return (65535); 280171440Srrs} 281171440Srrs 282171440Srrsisc_result_t 283171440Srrsdns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl, 284171440Srrs const unsigned char *rdatap, unsigned int rdlen) 285171440Srrs{ 286171440Srrs dns_rdatalist_t *rdatalist; 287171440Srrs dns_rdata_t *rdata; 288180387Srrs isc_buffer_t *rdatabuf = NULL; 289171440Srrs isc_result_t result; 290171440Srrs isc_mem_t *mctx; 291171440Srrs isc_region_t region; 292171440Srrs 293171440Srrs mctx = lookup->sdb->common.mctx; 294171440Srrs 295171440Srrs rdatalist = ISC_LIST_HEAD(lookup->lists); 296171440Srrs while (rdatalist != NULL) { 297171440Srrs if (rdatalist->type == typeval) 298171440Srrs break; 299171440Srrs rdatalist = ISC_LIST_NEXT(rdatalist, link); 300171440Srrs } 301171440Srrs 302171440Srrs if (rdatalist == NULL) { 303171440Srrs rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); 304171440Srrs if (rdatalist == NULL) 305171440Srrs return (ISC_R_NOMEMORY); 306171440Srrs rdatalist->rdclass = lookup->sdb->common.rdclass; 307171440Srrs rdatalist->type = typeval; 308214928Stuexen rdatalist->covers = 0; 309163953Srrs rdatalist->ttl = ttl; 310163953Srrs ISC_LIST_INIT(rdatalist->rdata); 311163953Srrs ISC_LINK_INIT(rdatalist, link); 312163953Srrs ISC_LIST_APPEND(lookup->lists, rdatalist, link); 313163953Srrs } else 314163953Srrs if (rdatalist->ttl != ttl) 315171440Srrs return (DNS_R_BADTTL); 316171440Srrs 317171440Srrs rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); 318171440Srrs if (rdata == NULL) 319163953Srrs return (ISC_R_NOMEMORY); 320163953Srrs 321163953Srrs result = isc_buffer_allocate(mctx, &rdatabuf, rdlen); 322163953Srrs if (result != ISC_R_SUCCESS) 323163953Srrs goto failure; 324163953Srrs DE_CONST(rdatap, region.base); 325163953Srrs region.length = rdlen; 326163953Srrs isc_buffer_copyregion(rdatabuf, ®ion); 327163953Srrs isc_buffer_usedregion(rdatabuf, ®ion); 328163953Srrs dns_rdata_init(rdata); 329163953Srrs dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type, 330163953Srrs ®ion); 331163953Srrs ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 332163953Srrs ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); 333163953Srrs rdata = NULL; 334163953Srrs 335171440Srrs failure: 336171440Srrs if (rdata != NULL) 337163953Srrs isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); 338163953Srrs return (result); 339163953Srrs} 340171440Srrs 341171440Srrs 342163953Srrsisc_result_t 343163953Srrsdns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, 344163953Srrs const char *data) 345163953Srrs{ 346163953Srrs unsigned int datalen; 347163953Srrs dns_rdatatype_t typeval; 348163953Srrs isc_textregion_t r; 349212225Srrs isc_lex_t *lex = NULL; 350212225Srrs isc_result_t result; 351212225Srrs unsigned char *p = NULL; 352163953Srrs unsigned int size = 0; /* Init to suppress compiler warning */ 353163953Srrs isc_mem_t *mctx; 354163953Srrs dns_sdbimplementation_t *imp; 355163953Srrs dns_name_t *origin; 356163953Srrs isc_buffer_t b; 357163953Srrs isc_buffer_t rb; 358163953Srrs 359163953Srrs REQUIRE(VALID_SDBLOOKUP(lookup)); 360163953Srrs REQUIRE(type != NULL); 361212225Srrs REQUIRE(data != NULL); 362212225Srrs 363212225Srrs mctx = lookup->sdb->common.mctx; 364163953Srrs 365163953Srrs DE_CONST(type, r.base); 366167598Srrs r.length = strlen(type); 367167598Srrs result = dns_rdatatype_fromtext(&typeval, &r); 368167598Srrs if (result != ISC_R_SUCCESS) 369167598Srrs return (result); 370163953Srrs 371163953Srrs imp = lookup->sdb->implementation; 372214928Stuexen if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) 373214928Stuexen origin = &lookup->sdb->common.origin; 374163953Srrs else 375214928Stuexen origin = dns_rootname; 376163953Srrs 377163953Srrs result = isc_lex_create(mctx, 64, &lex); 378163953Srrs if (result != ISC_R_SUCCESS) 379163953Srrs goto failure; 380163953Srrs 381163953Srrs datalen = strlen(data); 382163953Srrs size = initial_size(datalen); 383163953Srrs do { 384163953Srrs isc_buffer_init(&b, data, datalen); 385163953Srrs isc_buffer_add(&b, datalen); 386163953Srrs result = isc_lex_openbuffer(lex, &b); 387163953Srrs if (result != ISC_R_SUCCESS) 388212225Srrs goto failure; 389212225Srrs 390212225Srrs if (size >= 65535) 391163953Srrs size = 65535; 392163953Srrs p = isc_mem_get(mctx, size); 393163953Srrs if (p == NULL) { 394163953Srrs result = ISC_R_NOMEMORY; 395163953Srrs goto failure; 396163953Srrs } 397163953Srrs isc_buffer_init(&rb, p, size); 398163953Srrs result = dns_rdata_fromtext(NULL, 399169655Srrs lookup->sdb->common.rdclass, 400163953Srrs typeval, lex, 401163953Srrs origin, 0, 402163953Srrs mctx, &rb, 403163953Srrs &lookup->callbacks); 404163953Srrs if (result != ISC_R_NOSPACE) 405163953Srrs break; 406163953Srrs 407163953Srrs /* 408163953Srrs * Is the RR too big? 409163953Srrs */ 410163953Srrs if (size >= 65535) 411163953Srrs break; 412163953Srrs isc_mem_put(mctx, p, size); 413163953Srrs p = NULL; 414163953Srrs size *= 2; 415163953Srrs } while (result == ISC_R_NOSPACE); 416163953Srrs 417163953Srrs if (result != ISC_R_SUCCESS) 418210599Srrs goto failure; 419163953Srrs 420170642Srrs result = dns_sdb_putrdata(lookup, typeval, ttl, 421170642Srrs isc_buffer_base(&rb), 422170642Srrs isc_buffer_usedlength(&rb)); 423163953Srrs failure: 424163953Srrs if (p != NULL) 425163953Srrs isc_mem_put(mctx, p, size); 426163953Srrs if (lex != NULL) 427210599Srrs isc_lex_destroy(&lex); 428163953Srrs 429171440Srrs return (result); 430171440Srrs} 431163953Srrs 432163953Srrsstatic isc_result_t 433163953Srrsgetnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { 434184333Srrs dns_name_t *newname, *origin; 435184333Srrs dns_fixedname_t fnewname; 436182367Srrs dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db; 437182367Srrs dns_sdbimplementation_t *imp = sdb->implementation; 438216822Stuexen dns_sdbnode_t *sdbnode; 439182367Srrs isc_mem_t *mctx = sdb->common.mctx; 440182367Srrs isc_buffer_t b; 441182367Srrs isc_result_t result; 442216822Stuexen 443216825Stuexen dns_fixedname_init(&fnewname); 444182367Srrs newname = dns_fixedname_name(&fnewname); 445216822Stuexen 446182367Srrs if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) 447182367Srrs origin = &sdb->common.origin; 448182367Srrs else 449182367Srrs origin = dns_rootname; 450182367Srrs isc_buffer_init(&b, name, strlen(name)); 451182367Srrs isc_buffer_add(&b, strlen(name)); 452182367Srrs 453182367Srrs result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL); 454182367Srrs if (result != ISC_R_SUCCESS) 455216822Stuexen return (result); 456196260Stuexen 457182367Srrs if (allnodes->common.relative_names) { 458182367Srrs /* All names are relative to the root */ 459182367Srrs unsigned int nlabels = dns_name_countlabels(newname); 460182367Srrs dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); 461221627Stuexen } 462182367Srrs 463182367Srrs sdbnode = ISC_LIST_HEAD(allnodes->nodelist); 464182367Srrs if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) { 465216822Stuexen sdbnode = NULL; 466182367Srrs result = createnode(sdb, &sdbnode); 467182367Srrs if (result != ISC_R_SUCCESS) 468182367Srrs return (result); 469182367Srrs sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t)); 470184333Srrs if (sdbnode->name == NULL) { 471184333Srrs destroynode(sdbnode); 472163953Srrs return (ISC_R_NOMEMORY); 473163953Srrs } 474163953Srrs dns_name_init(sdbnode->name, NULL); 475163953Srrs result = dns_name_dup(newname, mctx, sdbnode->name); 476163953Srrs if (result != ISC_R_SUCCESS) { 477210599Srrs isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t)); 478210599Srrs destroynode(sdbnode); 479163953Srrs return (result); 480163953Srrs } 481163953Srrs ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link); 482163953Srrs if (allnodes->origin == NULL && 483163953Srrs dns_name_equal(newname, &sdb->common.origin)) 484163953Srrs allnodes->origin = sdbnode; 485163953Srrs } 486163953Srrs *nodep = sdbnode; 487216822Stuexen return (ISC_R_SUCCESS); 488163953Srrs} 489163953Srrs 490219014Stuexenisc_result_t 491210599Srrsdns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, 492168709Srrs const char *type, dns_ttl_t ttl, const char *data) 493163953Srrs{ 494168709Srrs isc_result_t result; 495163953Srrs dns_sdbnode_t *sdbnode = NULL; 496182367Srrs result = getnode(allnodes, name, &sdbnode); 497163953Srrs if (result != ISC_R_SUCCESS) 498171440Srrs return (result); 499163953Srrs return (dns_sdb_putrr(sdbnode, type, ttl, data)); 500163953Srrs} 501163953Srrs 502163953Srrsisc_result_t 503163953Srrsdns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, 504163953Srrs dns_rdatatype_t type, dns_ttl_t ttl, 505163953Srrs const void *rdata, unsigned int rdlen) 506169378Srrs{ 507163953Srrs isc_result_t result; 508219014Stuexen dns_sdbnode_t *sdbnode = NULL; 509219014Stuexen result = getnode(allnodes, name, &sdbnode); 510224641Stuexen if (result != ISC_R_SUCCESS) 511219014Stuexen return (result); 512170744Srrs return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen)); 513170744Srrs} 514170744Srrs 515224641Stuexenisc_result_t 516170744Srrsdns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, 517170744Srrs isc_uint32_t serial) 518219014Stuexen{ 519219014Stuexen char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; 520163953Srrs int n; 521163953Srrs 522163953Srrs REQUIRE(mname != NULL); 523163953Srrs REQUIRE(rname != NULL); 524163953Srrs 525163953Srrs n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u", 526163953Srrs mname, rname, serial, 527163953Srrs SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY, 528163953Srrs SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM); 529163953Srrs if (n >= (int)sizeof(str) || n < 0) 530163953Srrs return (ISC_R_NOSPACE); 531224641Stuexen return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str)); 532219014Stuexen} 533170744Srrs 534170744Srrs/* 535163953Srrs * DB routines 536163953Srrs */ 537163953Srrs 538163953Srrsstatic void 539163953Srrsattach(dns_db_t *source, dns_db_t **targetp) { 540168709Srrs dns_sdb_t *sdb = (dns_sdb_t *) source; 541168709Srrs 542163953Srrs REQUIRE(VALID_SDB(sdb)); 543163953Srrs 544210599Srrs LOCK(&sdb->lock); 545163953Srrs REQUIRE(sdb->references > 0); 546163953Srrs sdb->references++; 547184333Srrs UNLOCK(&sdb->lock); 548182367Srrs 549184333Srrs *targetp = source; 550216822Stuexen} 551216825Stuexen 552163953Srrsstatic void 553182367Srrsdestroy(dns_sdb_t *sdb) { 554182367Srrs isc_mem_t *mctx; 555182367Srrs dns_sdbimplementation_t *imp = sdb->implementation; 556182367Srrs 557182367Srrs mctx = sdb->common.mctx; 558182367Srrs 559182367Srrs if (imp->methods->destroy != NULL) { 560182367Srrs MAYBE_LOCK(sdb); 561182367Srrs imp->methods->destroy(sdb->zone, imp->driverdata, 562182367Srrs &sdb->dbdata); 563182367Srrs MAYBE_UNLOCK(sdb); 564182367Srrs } 565182367Srrs 566182367Srrs isc_mem_free(mctx, sdb->zone); 567163953Srrs DESTROYLOCK(&sdb->lock); 568163953Srrs 569163953Srrs sdb->common.magic = 0; 570163953Srrs sdb->common.impmagic = 0; 571163953Srrs 572163953Srrs dns_name_free(&sdb->common.origin, mctx); 573163953Srrs 574163953Srrs isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); 575163953Srrs isc_mem_detach(&mctx); 576163953Srrs} 577163953Srrs 578224641Stuexenstatic void 579170744Srrsdetach(dns_db_t **dbp) { 580170744Srrs dns_sdb_t *sdb = (dns_sdb_t *)(*dbp); 581170744Srrs isc_boolean_t need_destroy = ISC_FALSE; 582170744Srrs 583170744Srrs REQUIRE(VALID_SDB(sdb)); 584163953Srrs LOCK(&sdb->lock); 585163953Srrs REQUIRE(sdb->references > 0); 586163953Srrs sdb->references--; 587163953Srrs if (sdb->references == 0) 588163953Srrs need_destroy = ISC_TRUE; 589163953Srrs UNLOCK(&sdb->lock); 590224641Stuexen 591170744Srrs if (need_destroy) 592170744Srrs destroy(sdb); 593170744Srrs 594170744Srrs *dbp = NULL; 595170744Srrs} 596163953Srrs 597163953Srrsstatic isc_result_t 598163953Srrsbeginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { 599163953Srrs UNUSED(db); 600163953Srrs UNUSED(addp); 601163953Srrs UNUSED(dbloadp); 602163953Srrs return (ISC_R_NOTIMPLEMENTED); 603163953Srrs} 604163953Srrs 605163953Srrsstatic isc_result_t 606163953Srrsendload(dns_db_t *db, dns_dbload_t **dbloadp) { 607163953Srrs UNUSED(db); 608163953Srrs UNUSED(dbloadp); 609163953Srrs return (ISC_R_NOTIMPLEMENTED); 610163953Srrs} 611196260Stuexen 612163953Srrsstatic isc_result_t 613212801Stuexendump(dns_db_t *db, dns_dbversion_t *version, const char *filename, 614163953Srrs dns_masterformat_t masterformat) { 615163953Srrs UNUSED(db); 616169420Srrs UNUSED(version); 617163953Srrs UNUSED(filename); 618163953Srrs UNUSED(masterformat); 619189790Srrs return (ISC_R_NOTIMPLEMENTED); 620210599Srrs} 621163953Srrs 622185694Srrsstatic void 623163953Srrscurrentversion(dns_db_t *db, dns_dbversion_t **versionp) { 624163953Srrs REQUIRE(versionp != NULL && *versionp == NULL); 625196260Stuexen 626163953Srrs UNUSED(db); 627163953Srrs 628163953Srrs *versionp = (void *) &dummy; 629169420Srrs return; 630163953Srrs} 631163953Srrs 632189790Srrsstatic isc_result_t 633210599Srrsnewversion(dns_db_t *db, dns_dbversion_t **versionp) { 634163953Srrs UNUSED(db); 635185694Srrs UNUSED(versionp); 636163953Srrs 637163953Srrs return (ISC_R_NOTIMPLEMENTED); 638168709Srrs} 639163953Srrs 640163953Srrsstatic void 641163953Srrsattachversion(dns_db_t *db, dns_dbversion_t *source, 642163953Srrs dns_dbversion_t **targetp) 643163953Srrs{ 644163953Srrs REQUIRE(source != NULL && source == (void *) &dummy); 645163953Srrs REQUIRE(targetp != NULL && *targetp == NULL); 646224641Stuexen 647170744Srrs UNUSED(db); 648170744Srrs *targetp = source; 649170744Srrs return; 650168709Srrs} 651168709Srrs 652168709Srrsstatic void 653168709Srrscloseversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { 654168709Srrs REQUIRE(versionp != NULL && *versionp == (void *) &dummy); 655168709Srrs REQUIRE(commit == ISC_FALSE); 656168709Srrs 657179783Srrs UNUSED(db); 658170744Srrs UNUSED(commit); 659170744Srrs 660170744Srrs *versionp = NULL; 661170744Srrs} 662170744Srrs 663170744Srrsstatic isc_result_t 664168709Srrscreatenode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) { 665168709Srrs dns_sdbnode_t *node; 666168709Srrs isc_result_t result; 667179783Srrs 668163953Srrs node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t)); 669163953Srrs if (node == NULL) 670163953Srrs return (ISC_R_NOMEMORY); 671165220Srrs 672163953Srrs node->sdb = NULL; 673163953Srrs attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb); 674163953Srrs ISC_LIST_INIT(node->lists); 675219397Srrs ISC_LIST_INIT(node->buffers); 676219397Srrs ISC_LINK_INIT(node, link); 677219397Srrs node->name = NULL; 678219397Srrs result = isc_mutex_init(&node->lock); 679219397Srrs if (result != ISC_R_SUCCESS) { 680219397Srrs isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t)); 681163953Srrs return (result); 682163953Srrs } 683163953Srrs dns_rdatacallbacks_init(&node->callbacks); 684163953Srrs node->references = 1; 685163953Srrs node->magic = SDBLOOKUP_MAGIC; 686163953Srrs 687163953Srrs *nodep = node; 688163953Srrs return (ISC_R_SUCCESS); 689163953Srrs} 690163953Srrs 691163953Srrsstatic void 692163953Srrsdestroynode(dns_sdbnode_t *node) { 693163953Srrs dns_rdatalist_t *list; 694163953Srrs dns_rdata_t *rdata; 695170181Srrs isc_buffer_t *b; 696170181Srrs dns_sdb_t *sdb; 697170181Srrs isc_mem_t *mctx; 698216669Stuexen 699163953Srrs sdb = node->sdb; 700163953Srrs mctx = sdb->common.mctx; 701210599Srrs 702163953Srrs while (!ISC_LIST_EMPTY(node->lists)) { 703163953Srrs list = ISC_LIST_HEAD(node->lists); 704163953Srrs while (!ISC_LIST_EMPTY(list->rdata)) { 705210599Srrs rdata = ISC_LIST_HEAD(list->rdata); 706163953Srrs ISC_LIST_UNLINK(list->rdata, rdata, link); 707163953Srrs isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); 708163953Srrs } 709163953Srrs ISC_LIST_UNLINK(node->lists, list, link); 710163953Srrs isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); 711168709Srrs } 712168709Srrs 713168709Srrs while (!ISC_LIST_EMPTY(node->buffers)) { 714168709Srrs b = ISC_LIST_HEAD(node->buffers); 715224641Stuexen ISC_LIST_UNLINK(node->buffers, b, link); 716170744Srrs isc_buffer_free(&b); 717170744Srrs } 718163953Srrs 719169420Srrs if (node->name != NULL) { 720169420Srrs dns_name_free(node->name, mctx); 721169420Srrs isc_mem_put(mctx, node->name, sizeof(dns_name_t)); 722169420Srrs } 723169420Srrs DESTROYLOCK(&node->lock); 724169420Srrs node->magic = 0; 725169420Srrs isc_mem_put(mctx, node, sizeof(dns_sdbnode_t)); 726169420Srrs detach((dns_db_t **) (void *)&sdb); 727169420Srrs} 728169420Srrs 729163953Srrsstatic isc_result_t 730163953Srrsfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, 731163953Srrs dns_dbnode_t **nodep) 732210599Srrs{ 733210493Srrs dns_sdb_t *sdb = (dns_sdb_t *)db; 734210493Srrs dns_sdbnode_t *node = NULL; 735210493Srrs isc_result_t result; 736210493Srrs isc_buffer_t b; 737210493Srrs char namestr[DNS_NAME_MAXTEXT + 1]; 738210493Srrs isc_boolean_t isorigin; 739210493Srrs dns_sdbimplementation_t *imp; 740210493Srrs 741210493Srrs REQUIRE(VALID_SDB(sdb)); 742210493Srrs REQUIRE(create == ISC_FALSE); 743210493Srrs REQUIRE(nodep != NULL && *nodep == NULL); 744210493Srrs 745210493Srrs UNUSED(name); 746210493Srrs UNUSED(create); 747210493Srrs 748210493Srrs imp = sdb->implementation; 749210493Srrs 750210493Srrs isc_buffer_init(&b, namestr, sizeof(namestr)); 751210493Srrs if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { 752210493Srrs dns_name_t relname; 753210599Srrs unsigned int labels; 754163953Srrs 755163953Srrs labels = dns_name_countlabels(name) - 756163953Srrs dns_name_countlabels(&db->origin); 757163953Srrs dns_name_init(&relname, NULL); 758163953Srrs dns_name_getlabelsequence(name, 0, labels, &relname); 759163953Srrs result = dns_name_totext(&relname, ISC_TRUE, &b); 760210599Srrs if (result != ISC_R_SUCCESS) 761163953Srrs return (result); 762165220Srrs } else { 763171477Srrs result = dns_name_totext(name, ISC_TRUE, &b); 764171477Srrs if (result != ISC_R_SUCCESS) 765163953Srrs return (result); 766163953Srrs } 767163953Srrs isc_buffer_putuint8(&b, 0); 768163953Srrs 769163953Srrs result = createnode(sdb, &node); 770163953Srrs if (result != ISC_R_SUCCESS) 771169420Srrs return (result); 772169420Srrs 773169420Srrs isorigin = dns_name_equal(name, &sdb->common.origin); 774163953Srrs 775163953Srrs MAYBE_LOCK(sdb); 776163953Srrs result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node); 777163953Srrs MAYBE_UNLOCK(sdb); 778163953Srrs if (result != ISC_R_SUCCESS && 779169420Srrs !(result == ISC_R_NOTFOUND && 780169420Srrs isorigin && imp->methods->authority != NULL)) 781169420Srrs { 782163953Srrs destroynode(node); 783163953Srrs return (result); 784163953Srrs } 785179783Srrs 786170744Srrs if (isorigin && imp->methods->authority != NULL) { 787170744Srrs MAYBE_LOCK(sdb); 788170744Srrs result = imp->methods->authority(sdb->zone, sdb->dbdata, node); 789170744Srrs MAYBE_UNLOCK(sdb); 790170744Srrs if (result != ISC_R_SUCCESS) { 791170744Srrs destroynode(node); 792168709Srrs return (result); 793168709Srrs } 794163953Srrs } 795163953Srrs 796163953Srrs *nodep = node; 797163953Srrs return (ISC_R_SUCCESS); 798163953Srrs} 799163953Srrs 800163953Srrsstatic isc_result_t 801163953Srrsfind(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, 802163953Srrs dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, 803163953Srrs dns_dbnode_t **nodep, dns_name_t *foundname, 804163953Srrs dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 805163953Srrs{ 806163953Srrs dns_sdb_t *sdb = (dns_sdb_t *)db; 807163953Srrs dns_dbnode_t *node = NULL; 808210599Srrs dns_fixedname_t fname; 809163953Srrs dns_rdataset_t xrdataset; 810179783Srrs dns_name_t *xname; 811170744Srrs unsigned int nlabels, olabels; 812170744Srrs isc_result_t result; 813179783Srrs unsigned int i; 814163953Srrs 815163953Srrs REQUIRE(VALID_SDB(sdb)); 816163953Srrs REQUIRE(nodep == NULL || *nodep == NULL); 817163953Srrs REQUIRE(version == NULL || version == (void *) &dummy); 818163953Srrs 819163953Srrs UNUSED(options); 820163953Srrs UNUSED(sdb); 821163953Srrs 822163953Srrs if (!dns_name_issubdomain(name, &db->origin)) 823163953Srrs return (DNS_R_NXDOMAIN); 824163953Srrs 825163953Srrs olabels = dns_name_countlabels(&db->origin); 826163953Srrs nlabels = dns_name_countlabels(name); 827163953Srrs 828163953Srrs dns_fixedname_init(&fname); 829163953Srrs xname = dns_fixedname_name(&fname); 830163953Srrs 831163953Srrs if (rdataset == NULL) { 832168709Srrs dns_rdataset_init(&xrdataset); 833163953Srrs rdataset = &xrdataset; 834163953Srrs } 835163953Srrs 836163953Srrs result = DNS_R_NXDOMAIN; 837163953Srrs 838163953Srrs for (i = olabels; i <= nlabels; i++) { 839163953Srrs /* 840163953Srrs * Unless this is an explicit lookup at the origin, don't 841163953Srrs * look at the origin. 842163953Srrs */ 843163953Srrs if (i == olabels && i != nlabels) 844163953Srrs continue; 845169378Srrs 846163953Srrs /* 847163953Srrs * Look up the next label. 848163953Srrs */ 849163953Srrs dns_name_getlabelsequence(name, nlabels - i, i, xname); 850163953Srrs result = findnode(db, xname, ISC_FALSE, &node); 851224641Stuexen if (result != ISC_R_SUCCESS) { 852224641Stuexen result = DNS_R_NXDOMAIN; 853185694Srrs continue; 854224641Stuexen } 855224641Stuexen 856224641Stuexen /* 857185694Srrs * Look for a DNAME at the current label, unless this is 858224641Stuexen * the qname. 859224641Stuexen */ 860163953Srrs if (i < nlabels) { 861163953Srrs result = findrdataset(db, node, version, 862163953Srrs dns_rdatatype_dname, 863163953Srrs 0, now, rdataset, sigrdataset); 864163953Srrs if (result == ISC_R_SUCCESS) { 865163953Srrs result = DNS_R_DNAME; 866163953Srrs break; 867163953Srrs } 868163953Srrs } 869163953Srrs 870163953Srrs /* 871163953Srrs * Look for an NS at the current label, unless this is the 872163953Srrs * origin or glue is ok. 873163953Srrs */ 874163953Srrs if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { 875163953Srrs result = findrdataset(db, node, version, 876224641Stuexen dns_rdatatype_ns, 877224641Stuexen 0, now, rdataset, sigrdataset); 878224641Stuexen if (result == ISC_R_SUCCESS) { 879224641Stuexen if (i == nlabels && type == dns_rdatatype_any) 880224641Stuexen { 881224641Stuexen result = DNS_R_ZONECUT; 882224641Stuexen dns_rdataset_disassociate(rdataset); 883224641Stuexen if (sigrdataset != NULL && 884224641Stuexen dns_rdataset_isassociated 885224641Stuexen (sigrdataset)) { 886224641Stuexen dns_rdataset_disassociate 887224641Stuexen (sigrdataset); 888224641Stuexen } 889224641Stuexen } else 890224641Stuexen result = DNS_R_DELEGATION; 891224641Stuexen break; 892224641Stuexen } 893224641Stuexen } 894224641Stuexen 895224641Stuexen /* 896224641Stuexen * If the current name is not the qname, add another label 897224641Stuexen * and try again. 898224641Stuexen */ 899224641Stuexen if (i < nlabels) { 900224641Stuexen destroynode(node); 901224641Stuexen node = NULL; 902224641Stuexen continue; 903224641Stuexen } 904224641Stuexen 905224641Stuexen /* 906224641Stuexen * If we're looking for ANY, we're done. 907224641Stuexen */ 908224641Stuexen if (type == dns_rdatatype_any) { 909224641Stuexen result = ISC_R_SUCCESS; 910224641Stuexen break; 911224641Stuexen } 912224641Stuexen 913224641Stuexen /* 914224641Stuexen * Look for the qtype. 915224641Stuexen */ 916224641Stuexen result = findrdataset(db, node, version, type, 917224641Stuexen 0, now, rdataset, sigrdataset); 918224641Stuexen if (result == ISC_R_SUCCESS) 919224641Stuexen break; 920224641Stuexen 921224641Stuexen /* 922163953Srrs * Look for a CNAME 923212712Stuexen */ 924169352Srrs if (type != dns_rdatatype_cname) { 925169352Srrs result = findrdataset(db, node, version, 926169352Srrs dns_rdatatype_cname, 927169352Srrs 0, now, rdataset, sigrdataset); 928169352Srrs if (result == ISC_R_SUCCESS) { 929169352Srrs result = DNS_R_CNAME; 930169352Srrs break; 931169352Srrs } 932169352Srrs } 933169352Srrs 934169352Srrs result = DNS_R_NXRRSET; 935169352Srrs break; 936169352Srrs } 937169352Srrs 938169352Srrs if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) 939169352Srrs dns_rdataset_disassociate(rdataset); 940163953Srrs 941163953Srrs if (foundname != NULL) { 942163953Srrs isc_result_t xresult; 943163953Srrs 944163953Srrs xresult = dns_name_copy(xname, foundname, NULL); 945163953Srrs if (xresult != ISC_R_SUCCESS) { 946163953Srrs if (node != NULL) 947163953Srrs destroynode(node); 948163953Srrs if (dns_rdataset_isassociated(rdataset)) 949224641Stuexen dns_rdataset_disassociate(rdataset); 950224641Stuexen return (DNS_R_BADDB); 951163953Srrs } 952224641Stuexen } 953224641Stuexen 954163953Srrs if (nodep != NULL) 955163953Srrs *nodep = node; 956163953Srrs else if (node != NULL) 957163953Srrs detachnode(db, &node); 958163953Srrs 959163953Srrs return (result); 960163953Srrs} 961163953Srrs 962163953Srrsstatic isc_result_t 963163953Srrsfindzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, 964163953Srrs isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, 965163953Srrs dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 966163953Srrs{ 967163953Srrs UNUSED(db); 968163953Srrs UNUSED(name); 969163953Srrs UNUSED(options); 970163953Srrs UNUSED(now); 971163953Srrs UNUSED(nodep); 972163953Srrs UNUSED(foundname); 973216825Stuexen UNUSED(rdataset); 974163953Srrs UNUSED(sigrdataset); 975163953Srrs 976163953Srrs return (ISC_R_NOTIMPLEMENTED); 977163953Srrs} 978163953Srrs 979163953Srrsstatic void 980163953Srrsattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { 981179783Srrs dns_sdb_t *sdb = (dns_sdb_t *)db; 982170744Srrs dns_sdbnode_t *node = (dns_sdbnode_t *)source; 983170744Srrs 984163953Srrs REQUIRE(VALID_SDB(sdb)); 985163953Srrs 986163953Srrs UNUSED(sdb); 987163953Srrs 988163953Srrs LOCK(&node->lock); 989163953Srrs INSIST(node->references > 0); 990163953Srrs node->references++; 991163953Srrs INSIST(node->references != 0); /* Catch overflow. */ 992163953Srrs UNLOCK(&node->lock); 993163953Srrs 994163953Srrs *targetp = source; 995163953Srrs} 996163953Srrs 997163953Srrsstatic void 998163953Srrsdetachnode(dns_db_t *db, dns_dbnode_t **targetp) { 999172090Srrs dns_sdb_t *sdb = (dns_sdb_t *)db; 1000163953Srrs dns_sdbnode_t *node; 1001163953Srrs isc_boolean_t need_destroy = ISC_FALSE; 1002163953Srrs 1003163953Srrs REQUIRE(VALID_SDB(sdb)); 1004163953Srrs REQUIRE(targetp != NULL && *targetp != NULL); 1005163953Srrs 1006163953Srrs UNUSED(sdb); 1007163953Srrs 1008163953Srrs node = (dns_sdbnode_t *)(*targetp); 1009163953Srrs 1010163953Srrs LOCK(&node->lock); 1011210599Srrs INSIST(node->references > 0); 1012163953Srrs node->references--; 1013163953Srrs if (node->references == 0) 1014163953Srrs need_destroy = ISC_TRUE; 1015163953Srrs UNLOCK(&node->lock); 1016163953Srrs 1017163953Srrs if (need_destroy) 1018163953Srrs destroynode(node); 1019163953Srrs 1020214928Stuexen *targetp = NULL; 1021212712Stuexen} 1022163953Srrs 1023163953Srrsstatic isc_result_t 1024163953Srrsexpirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { 1025163953Srrs UNUSED(db); 1026172090Srrs UNUSED(node); 1027163953Srrs UNUSED(now); 1028163953Srrs INSIST(0); 1029163953Srrs return (ISC_R_UNEXPECTED); 1030163953Srrs} 1031163953Srrs 1032163953Srrsstatic void 1033163953Srrsprintnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { 1034163953Srrs UNUSED(db); 1035163953Srrs UNUSED(node); 1036163953Srrs UNUSED(out); 1037163953Srrs return; 1038231038Stuexen} 1039163953Srrs 1040163953Srrsstatic isc_result_t 1041163953Srrscreateiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) 1042163953Srrs{ 1043163953Srrs dns_sdb_t *sdb = (dns_sdb_t *)db; 1044163953Srrs sdb_dbiterator_t *sdbiter; 1045163953Srrs dns_sdbimplementation_t *imp = sdb->implementation; 1046163953Srrs isc_result_t result; 1047163953Srrs 1048163953Srrs REQUIRE(VALID_SDB(sdb)); 1049163953Srrs 1050163953Srrs if (imp->methods->allnodes == NULL) 1051163953Srrs return (ISC_R_NOTIMPLEMENTED); 1052163953Srrs 1053163953Srrs if ((options & DNS_DB_NSEC3ONLY) != 0 || 1054163953Srrs (options & DNS_DB_NONSEC3) != 0) 1055163953Srrs return (ISC_R_NOTIMPLEMENTED); 1056163953Srrs 1057163953Srrs sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t)); 1058163953Srrs if (sdbiter == NULL) 1059163953Srrs return (ISC_R_NOMEMORY); 1060165647Srrs 1061163953Srrs sdbiter->common.methods = &dbiterator_methods; 1062163953Srrs sdbiter->common.db = NULL; 1063163953Srrs dns_db_attach(db, &sdbiter->common.db); 1064165647Srrs sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES); 1065163953Srrs sdbiter->common.magic = DNS_DBITERATOR_MAGIC; 1066171440Srrs ISC_LIST_INIT(sdbiter->nodelist); 1067163953Srrs sdbiter->current = NULL; 1068171440Srrs sdbiter->origin = NULL; 1069163953Srrs 1070172090Srrs MAYBE_LOCK(sdb); 1071163953Srrs result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); 1072165220Srrs MAYBE_UNLOCK(sdb); 1073163953Srrs if (result != ISC_R_SUCCESS) { 1074163953Srrs dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter); 1075169420Srrs return (result); 1076163953Srrs } 1077163953Srrs 1078163953Srrs if (sdbiter->origin != NULL) { 1079163953Srrs ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link); 1080163953Srrs ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link); 1081163953Srrs } 1082163953Srrs 1083163953Srrs *iteratorp = (dns_dbiterator_t *)sdbiter; 1084163953Srrs 1085163953Srrs return (ISC_R_SUCCESS); 1086163953Srrs} 1087163953Srrs 1088163953Srrsstatic isc_result_t 1089163953Srrsfindrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1090163953Srrs dns_rdatatype_t type, dns_rdatatype_t covers, 1091163953Srrs isc_stdtime_t now, dns_rdataset_t *rdataset, 1092210599Srrs dns_rdataset_t *sigrdataset) 1093163953Srrs{ 1094163953Srrs dns_rdatalist_t *list; 1095163953Srrs dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node; 1096163953Srrs 1097163953Srrs REQUIRE(VALID_SDBNODE(node)); 1098163953Srrs 1099163953Srrs UNUSED(db); 1100163953Srrs UNUSED(version); 1101163953Srrs UNUSED(covers); 1102163953Srrs UNUSED(now); 1103163953Srrs UNUSED(sigrdataset); 1104163953Srrs 1105163953Srrs if (type == dns_rdatatype_rrsig) 1106163953Srrs return (ISC_R_NOTIMPLEMENTED); 1107163953Srrs 1108163953Srrs list = ISC_LIST_HEAD(sdbnode->lists); 1109163953Srrs while (list != NULL) { 1110163953Srrs if (list->type == type) 1111163953Srrs break; 1112163953Srrs list = ISC_LIST_NEXT(list, link); 1113163953Srrs } 1114163953Srrs if (list == NULL) 1115163953Srrs return (ISC_R_NOTFOUND); 1116163953Srrs 1117163953Srrs list_tordataset(list, db, node, rdataset); 1118163953Srrs 1119163953Srrs return (ISC_R_SUCCESS); 1120163953Srrs} 1121163953Srrs 1122163953Srrsstatic isc_result_t 1123169420Srrsallrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1124163953Srrs isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) 1125163953Srrs{ 1126163953Srrs sdb_rdatasetiter_t *iterator; 1127163953Srrs 1128163953Srrs REQUIRE(version == NULL || version == &dummy); 1129163953Srrs 1130163953Srrs UNUSED(version); 1131163953Srrs UNUSED(now); 1132163953Srrs 1133163953Srrs iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t)); 1134163953Srrs if (iterator == NULL) 1135163953Srrs return (ISC_R_NOMEMORY); 1136163953Srrs 1137210599Srrs iterator->common.magic = DNS_RDATASETITER_MAGIC; 1138163953Srrs iterator->common.methods = &rdatasetiter_methods; 1139163953Srrs iterator->common.db = db; 1140163953Srrs iterator->common.node = NULL; 1141163953Srrs attachnode(db, node, &iterator->common.node); 1142163953Srrs iterator->common.version = version; 1143163953Srrs iterator->common.now = now; 1144163953Srrs 1145163953Srrs *iteratorp = (dns_rdatasetiter_t *)iterator; 1146163953Srrs 1147163953Srrs return (ISC_R_SUCCESS); 1148163953Srrs} 1149163953Srrs 1150163953Srrsstatic isc_result_t 1151163953Srrsaddrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1152163953Srrs isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, 1153163953Srrs dns_rdataset_t *addedrdataset) 1154163953Srrs{ 1155163953Srrs UNUSED(db); 1156224641Stuexen UNUSED(node); 1157163953Srrs UNUSED(version); 1158163953Srrs UNUSED(now); 1159163953Srrs UNUSED(rdataset); 1160163953Srrs UNUSED(options); 1161212712Stuexen UNUSED(addedrdataset); 1162163953Srrs 1163163953Srrs return (ISC_R_NOTIMPLEMENTED); 1164163953Srrs} 1165163953Srrs 1166163953Srrsstatic isc_result_t 1167163953Srrssubtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1168163953Srrs dns_rdataset_t *rdataset, unsigned int options, 1169163953Srrs dns_rdataset_t *newrdataset) 1170163953Srrs{ 1171163953Srrs UNUSED(db); 1172163953Srrs UNUSED(node); 1173163953Srrs UNUSED(version); 1174163953Srrs UNUSED(rdataset); 1175163953Srrs UNUSED(options); 1176163953Srrs UNUSED(newrdataset); 1177163953Srrs 1178216822Stuexen return (ISC_R_NOTIMPLEMENTED); 1179163953Srrs} 1180171572Srrs 1181179157Srrsstatic isc_result_t 1182163953Srrsdeleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 1183172190Srrs dns_rdatatype_t type, dns_rdatatype_t covers) 1184163953Srrs{ 1185171572Srrs UNUSED(db); 1186171572Srrs UNUSED(node); 1187171572Srrs UNUSED(version); 1188163953Srrs UNUSED(type); 1189163953Srrs UNUSED(covers); 1190179157Srrs 1191163953Srrs return (ISC_R_NOTIMPLEMENTED); 1192163953Srrs} 1193163953Srrs 1194163953Srrsstatic isc_boolean_t 1195163953Srrsissecure(dns_db_t *db) { 1196163953Srrs UNUSED(db); 1197163953Srrs 1198163953Srrs return (ISC_FALSE); 1199163953Srrs} 1200163953Srrs 1201163953Srrsstatic unsigned int 1202171572Srrsnodecount(dns_db_t *db) { 1203171572Srrs UNUSED(db); 1204171572Srrs 1205171572Srrs return (0); 1206171572Srrs} 1207163953Srrs 1208169420Srrsstatic isc_boolean_t 1209163953Srrsispersistent(dns_db_t *db) { 1210163953Srrs UNUSED(db); 1211163953Srrs return (ISC_TRUE); 1212163953Srrs} 1213171572Srrs 1214171572Srrsstatic void 1215163953Srrsovermem(dns_db_t *db, isc_boolean_t overmem) { 1216210599Srrs UNUSED(db); 1217163953Srrs UNUSED(overmem); 1218179157Srrs} 1219179157Srrs 1220179157Srrsstatic void 1221179157Srrssettask(dns_db_t *db, isc_task_t *task) { 1222179157Srrs UNUSED(db); 1223171572Srrs UNUSED(task); 1224163953Srrs} 1225163953Srrs 1226163953Srrs 1227163953Srrsstatic dns_dbmethods_t sdb_methods = { 1228163953Srrs attach, 1229163953Srrs detach, 1230163953Srrs beginload, 1231163953Srrs endload, 1232163953Srrs dump, 1233163953Srrs currentversion, 1234163953Srrs newversion, 1235163953Srrs attachversion, 1236216822Stuexen closeversion, 1237179157Srrs findnode, 1238179157Srrs find, 1239179157Srrs findzonecut, 1240179157Srrs attachnode, 1241179157Srrs detachnode, 1242179157Srrs expirenode, 1243179157Srrs printnode, 1244179157Srrs createiterator, 1245179157Srrs findrdataset, 1246224641Stuexen allrdatasets, 1247163953Srrs addrdataset, 1248163953Srrs subtractrdataset, 1249171572Srrs deleterdataset, 1250163953Srrs issecure, 1251212712Stuexen nodecount, 1252163953Srrs ispersistent, 1253163953Srrs overmem, 1254163953Srrs settask, 1255163953Srrs NULL, 1256163953Srrs NULL, 1257179157Srrs NULL, 1258179157Srrs NULL, 1259179157Srrs NULL, 1260163953Srrs NULL, 1261163953Srrs NULL, 1262163953Srrs NULL, 1263163953Srrs NULL 1264172091Srrs}; 1265172156Srrs 1266172091Srrsstatic isc_result_t 1267231038Stuexendns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, 1268172091Srrs dns_rdataclass_t rdclass, unsigned int argc, char *argv[], 1269172091Srrs void *driverarg, dns_db_t **dbp) 1270172091Srrs{ 1271172091Srrs dns_sdb_t *sdb; 1272172156Srrs isc_result_t result; 1273172091Srrs char zonestr[DNS_NAME_MAXTEXT + 1]; 1274172091Srrs isc_buffer_t b; 1275172091Srrs dns_sdbimplementation_t *imp; 1276172091Srrs 1277172091Srrs REQUIRE(driverarg != NULL); 1278172091Srrs 1279172156Srrs imp = driverarg; 1280172091Srrs 1281172091Srrs if (type != dns_dbtype_zone) 1282163953Srrs return (ISC_R_NOTIMPLEMENTED); 1283163953Srrs 1284163953Srrs sdb = isc_mem_get(mctx, sizeof(dns_sdb_t)); 1285163953Srrs if (sdb == NULL) 1286214928Stuexen return (ISC_R_NOMEMORY); 1287163953Srrs memset(sdb, 0, sizeof(dns_sdb_t)); 1288163953Srrs 1289163953Srrs dns_name_init(&sdb->common.origin, NULL); 1290163953Srrs sdb->common.attributes = 0; 1291163953Srrs sdb->common.methods = &sdb_methods; 1292163953Srrs sdb->common.rdclass = rdclass; 1293163953Srrs sdb->common.mctx = NULL; 1294163953Srrs sdb->implementation = imp; 1295163953Srrs 1296163953Srrs isc_mem_attach(mctx, &sdb->common.mctx); 1297163953Srrs 1298163953Srrs result = isc_mutex_init(&sdb->lock); 1299214928Stuexen if (result != ISC_R_SUCCESS) 1300163953Srrs goto cleanup_mctx; 1301163953Srrs 1302163953Srrs result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); 1303163953Srrs if (result != ISC_R_SUCCESS) 1304214928Stuexen goto cleanup_lock; 1305214928Stuexen 1306163953Srrs isc_buffer_init(&b, zonestr, sizeof(zonestr)); 1307163953Srrs result = dns_name_totext(origin, ISC_TRUE, &b); 1308163953Srrs if (result != ISC_R_SUCCESS) 1309163953Srrs goto cleanup_origin; 1310163953Srrs isc_buffer_putuint8(&b, 0); 1311163953Srrs 1312163953Srrs sdb->zone = isc_mem_strdup(mctx, zonestr); 1313163953Srrs if (sdb->zone == NULL) { 1314163953Srrs result = ISC_R_NOMEMORY; 1315163953Srrs goto cleanup_origin; 1316163953Srrs } 1317163953Srrs 1318163953Srrs sdb->dbdata = NULL; 1319163953Srrs if (imp->methods->create != NULL) { 1320163953Srrs MAYBE_LOCK(sdb); 1321163953Srrs result = imp->methods->create(sdb->zone, argc, argv, 1322214928Stuexen imp->driverdata, &sdb->dbdata); 1323163953Srrs MAYBE_UNLOCK(sdb); 1324163953Srrs if (result != ISC_R_SUCCESS) 1325163953Srrs goto cleanup_zonestr; 1326163953Srrs } 1327163953Srrs 1328163953Srrs sdb->references = 1; 1329163953Srrs 1330163953Srrs sdb->common.magic = DNS_DB_MAGIC; 1331163953Srrs sdb->common.impmagic = SDB_MAGIC; 1332163953Srrs 1333163953Srrs *dbp = (dns_db_t *)sdb; 1334163953Srrs 1335163953Srrs return (ISC_R_SUCCESS); 1336163953Srrs 1337163953Srrs cleanup_zonestr: 1338163953Srrs isc_mem_free(mctx, sdb->zone); 1339217760Stuexen cleanup_origin: 1340163953Srrs dns_name_free(&sdb->common.origin, mctx); 1341163953Srrs cleanup_lock: 1342163953Srrs isc_mutex_destroy(&sdb->lock); 1343163953Srrs cleanup_mctx: 1344163953Srrs isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); 1345163953Srrs isc_mem_detach(&mctx); 1346163953Srrs 1347163953Srrs return (result); 1348163953Srrs} 1349169420Srrs 1350163953Srrs 1351163953Srrs/* 1352163953Srrs * Rdataset Methods 1353217760Stuexen */ 1354218241Stuexen 1355218241Stuexenstatic void 1356218241Stuexendisassociate(dns_rdataset_t *rdataset) { 1357218241Stuexen dns_dbnode_t *node = rdataset->private5; 1358218241Stuexen dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1359163953Srrs dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1360218241Stuexen 1361163953Srrs detachnode(db, &node); 1362163953Srrs isc__rdatalist_disassociate(rdataset); 1363163953Srrs} 1364163953Srrs 1365217760Stuexenstatic void 1366217760Stuexenrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { 1367217760Stuexen dns_dbnode_t *node = source->private5; 1368163953Srrs dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; 1369163953Srrs dns_db_t *db = (dns_db_t *) sdbnode->sdb; 1370163953Srrs dns_dbnode_t *tempdb = NULL; 1371163953Srrs 1372163953Srrs isc__rdatalist_clone(source, target); 1373163953Srrs attachnode(db, node, &tempdb); 1374163953Srrs source->private5 = tempdb; 1375169420Srrs} 1376163953Srrs 1377163953Srrsstatic dns_rdatasetmethods_t methods = { 1378163953Srrs disassociate, 1379163953Srrs isc__rdatalist_first, 1380172090Srrs isc__rdatalist_next, 1381163953Srrs isc__rdatalist_current, 1382163953Srrs rdataset_clone, 1383163953Srrs isc__rdatalist_count, 1384163953Srrs isc__rdatalist_addnoqname, 1385163953Srrs isc__rdatalist_getnoqname, 1386163953Srrs NULL, 1387163953Srrs NULL, 1388169420Srrs NULL, 1389163953Srrs NULL, 1390163953Srrs NULL 1391163953Srrs}; 1392163953Srrs 1393169420Srrsstatic void 1394163953Srrslist_tordataset(dns_rdatalist_t *rdatalist, 1395163953Srrs dns_db_t *db, dns_dbnode_t *node, 1396163953Srrs dns_rdataset_t *rdataset) 1397163953Srrs{ 1398163953Srrs /* 1399163953Srrs * The sdb rdataset is an rdatalist with some additions. 1400163953Srrs * - private1 & private2 are used by the rdatalist. 1401224641Stuexen * - private3 & private 4 are unused. 1402163953Srrs * - private5 is the node. 1403224641Stuexen */ 1404171440Srrs 1405224641Stuexen /* This should never fail. */ 1406163953Srrs RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == 1407224641Stuexen ISC_R_SUCCESS); 1408224641Stuexen 1409224641Stuexen rdataset->methods = &methods; 1410163953Srrs dns_db_attachnode(db, node, &rdataset->private5); 1411167598Srrs} 1412167598Srrs 1413167598Srrs/* 1414167598Srrs * Database Iterator Methods 1415167598Srrs */ 1416167598Srrsstatic void 1417167598Srrsdbiterator_destroy(dns_dbiterator_t **iteratorp) { 1418167598Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp); 1419167598Srrs dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db; 1420210599Srrs 1421224641Stuexen while (!ISC_LIST_EMPTY(sdbiter->nodelist)) { 1422224641Stuexen dns_sdbnode_t *node; 1423224641Stuexen node = ISC_LIST_HEAD(sdbiter->nodelist); 1424224641Stuexen ISC_LIST_UNLINK(sdbiter->nodelist, node, link); 1425163953Srrs destroynode(node); 1426163953Srrs } 1427163953Srrs 1428163953Srrs dns_db_detach(&sdbiter->common.db); 1429163953Srrs isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t)); 1430163953Srrs 1431163953Srrs *iteratorp = NULL; 1432163953Srrs} 1433163953Srrs 1434163953Srrsstatic isc_result_t 1435163953Srrsdbiterator_first(dns_dbiterator_t *iterator) { 1436224641Stuexen sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1437224641Stuexen 1438163953Srrs sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1439224641Stuexen if (sdbiter->current == NULL) 1440224641Stuexen return (ISC_R_NOMORE); 1441163953Srrs else 1442224641Stuexen return (ISC_R_SUCCESS); 1443163953Srrs} 1444163953Srrs 1445163953Srrsstatic isc_result_t 1446163953Srrsdbiterator_last(dns_dbiterator_t *iterator) { 1447163953Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1448163953Srrs 1449163953Srrs sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist); 1450163953Srrs if (sdbiter->current == NULL) 1451163953Srrs return (ISC_R_NOMORE); 1452179157Srrs else 1453163953Srrs return (ISC_R_SUCCESS); 1454231038Stuexen} 1455169352Srrs 1456179157Srrsstatic isc_result_t 1457169352Srrsdbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { 1458169352Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1459169352Srrs 1460169420Srrs sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); 1461169352Srrs while (sdbiter->current != NULL) 1462169352Srrs if (dns_name_equal(sdbiter->current->name, name)) 1463169352Srrs return (ISC_R_SUCCESS); 1464169420Srrs return (ISC_R_NOTFOUND); 1465179157Srrs} 1466179157Srrs 1467179157Srrsstatic isc_result_t 1468179157Srrsdbiterator_prev(dns_dbiterator_t *iterator) { 1469179157Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1470197288Srrs 1471179157Srrs sdbiter->current = ISC_LIST_PREV(sdbiter->current, link); 1472179157Srrs if (sdbiter->current == NULL) 1473179157Srrs return (ISC_R_NOMORE); 1474169420Srrs else 1475169420Srrs return (ISC_R_SUCCESS); 1476169420Srrs} 1477169420Srrs 1478179157Srrsstatic isc_result_t 1479179157Srrsdbiterator_next(dns_dbiterator_t *iterator) { 1480179157Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1481179157Srrs 1482179157Srrs sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); 1483179157Srrs if (sdbiter->current == NULL) 1484179157Srrs return (ISC_R_NOMORE); 1485169352Srrs else 1486169352Srrs return (ISC_R_SUCCESS); 1487169352Srrs} 1488169352Srrs 1489169352Srrsstatic isc_result_t 1490169352Srrsdbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, 1491185694Srrs dns_name_t *name) 1492185694Srrs{ 1493185694Srrs sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; 1494169352Srrs 1495163953Srrs attachnode(iterator->db, sdbiter->current, nodep); 1496163953Srrs if (name != NULL) 1497163953Srrs return (dns_name_copy(sdbiter->current->name, name, NULL)); 1498163953Srrs return (ISC_R_SUCCESS); 1499163953Srrs} 1500163953Srrs 1501163953Srrsstatic isc_result_t 1502163953Srrsdbiterator_pause(dns_dbiterator_t *iterator) { 1503163953Srrs UNUSED(iterator); 1504163953Srrs return (ISC_R_SUCCESS); 1505163953Srrs} 1506163953Srrs 1507163953Srrsstatic isc_result_t 1508163953Srrsdbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { 1509163953Srrs UNUSED(iterator); 1510163953Srrs return (dns_name_copy(dns_rootname, name, NULL)); 1511163953Srrs} 1512169378Srrs 1513163953Srrs/* 1514163953Srrs * Rdataset Iterator Methods 1515163953Srrs */ 1516163953Srrs 1517163953Srrsstatic void 1518163953Srrsrdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { 1519163953Srrs sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp); 1520163953Srrs detachnode(sdbiterator->common.db, &sdbiterator->common.node); 1521163953Srrs isc_mem_put(sdbiterator->common.db->mctx, sdbiterator, 1522163953Srrs sizeof(sdb_rdatasetiter_t)); 1523163953Srrs *iteratorp = NULL; 1524163953Srrs} 1525163953Srrs 1526163953Srrsstatic isc_result_t 1527163953Srrsrdatasetiter_first(dns_rdatasetiter_t *iterator) { 1528163953Srrs sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1529163953Srrs dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node; 1530163953Srrs 1531163953Srrs if (ISC_LIST_EMPTY(sdbnode->lists)) 1532163953Srrs return (ISC_R_NOMORE); 1533163953Srrs sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists); 1534163953Srrs return (ISC_R_SUCCESS); 1535172090Srrs} 1536163953Srrs 1537163953Srrsstatic isc_result_t 1538163953Srrsrdatasetiter_next(dns_rdatasetiter_t *iterator) { 1539163953Srrs sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1540163953Srrs 1541163953Srrs sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link); 1542163953Srrs if (sdbiterator->current == NULL) 1543166675Srrs return (ISC_R_NOMORE); 1544163953Srrs else 1545224641Stuexen return (ISC_R_SUCCESS); 1546224641Stuexen} 1547224641Stuexen 1548224641Stuexenstatic void 1549224641Stuexenrdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { 1550224641Stuexen sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; 1551224641Stuexen 1552224641Stuexen list_tordataset(sdbiterator->current, iterator->db, iterator->node, 1553166675Srrs rdataset); 1554166675Srrs} 1555166675Srrs