00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <string.h>
00025
00026 #include <isc/buffer.h>
00027 #include <isc/lex.h>
00028 #include <isc/log.h>
00029 #include <isc/magic.h>
00030 #include <isc/mem.h>
00031 #include <isc/once.h>
00032 #include <isc/print.h>
00033 #include <isc/region.h>
00034 #include <isc/util.h>
00035
00036 #include <dns/callbacks.h>
00037 #include <dns/db.h>
00038 #include <dns/dbiterator.h>
00039 #include <dns/fixedname.h>
00040 #include <dns/log.h>
00041 #include <dns/rdata.h>
00042 #include <dns/rdatalist.h>
00043 #include <dns/rdataset.h>
00044 #include <dns/rdatasetiter.h>
00045 #include <dns/rdatatype.h>
00046 #include <dns/result.h>
00047 #include <dns/sdb.h>
00048 #include <dns/types.h>
00049
00050 #include "rdatalist_p.h"
00051
00052 struct dns_sdbimplementation {
00053 const dns_sdbmethods_t *methods;
00054 void *driverdata;
00055 unsigned int flags;
00056 isc_mem_t *mctx;
00057 isc_mutex_t driverlock;
00058 dns_dbimplementation_t *dbimp;
00059 };
00060
00061 struct dns_sdb {
00062
00063 dns_db_t common;
00064 char *zone;
00065 dns_sdbimplementation_t *implementation;
00066 void *dbdata;
00067 isc_mutex_t lock;
00068
00069 unsigned int references;
00070 };
00071
00072 struct dns_sdblookup {
00073
00074 unsigned int magic;
00075 dns_sdb_t *sdb;
00076 ISC_LIST(dns_rdatalist_t) lists;
00077 ISC_LIST(isc_buffer_t) buffers;
00078 dns_name_t *name;
00079 ISC_LINK(dns_sdblookup_t) link;
00080 isc_mutex_t lock;
00081 dns_rdatacallbacks_t callbacks;
00082
00083 unsigned int references;
00084 };
00085
00086 typedef struct dns_sdblookup dns_sdbnode_t;
00087
00088 struct dns_sdballnodes {
00089 dns_dbiterator_t common;
00090 ISC_LIST(dns_sdbnode_t) nodelist;
00091 dns_sdbnode_t *current;
00092 dns_sdbnode_t *origin;
00093 };
00094
00095 typedef dns_sdballnodes_t sdb_dbiterator_t;
00096
00097 typedef struct sdb_rdatasetiter {
00098 dns_rdatasetiter_t common;
00099 dns_rdatalist_t *current;
00100 } sdb_rdatasetiter_t;
00101
00102 #define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-')
00103
00104
00105
00106
00107
00108 #define VALID_SDB(sdb) ((sdb) != NULL && \
00109 (sdb)->common.impmagic == SDB_MAGIC)
00110
00111 #define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L')
00112 #define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC)
00113 #define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn)
00114
00115
00116 #define SDB_DEFAULT_REFRESH (60 * 60 * 8)
00117 #define SDB_DEFAULT_RETRY (60 * 60 * 2)
00118 #define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
00119 #define SDB_DEFAULT_MINIMUM (60 * 60 * 24)
00120
00121
00122 #define SDB_DEFAULT_TTL (60 * 60 * 24)
00123
00124 #ifdef __COVERITY__
00125 #define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock)
00126 #define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock)
00127 #else
00128 #define MAYBE_LOCK(sdb) \
00129 do { \
00130 unsigned int flags = sdb->implementation->flags; \
00131 if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
00132 LOCK(&sdb->implementation->driverlock); \
00133 } while (0)
00134
00135 #define MAYBE_UNLOCK(sdb) \
00136 do { \
00137 unsigned int flags = sdb->implementation->flags; \
00138 if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
00139 UNLOCK(&sdb->implementation->driverlock); \
00140 } while (0)
00141 #endif
00142
00143 static int dummy;
00144
00145 static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin,
00146 dns_dbtype_t type, dns_rdataclass_t rdclass,
00147 unsigned int argc, char *argv[],
00148 void *driverarg, dns_db_t **dbp);
00149
00150 static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node,
00151 dns_dbversion_t *version,
00152 dns_rdatatype_t type, dns_rdatatype_t covers,
00153 isc_stdtime_t now, dns_rdataset_t *rdataset,
00154 dns_rdataset_t *sigrdataset);
00155
00156 static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep);
00157
00158 static void destroynode(dns_sdbnode_t *node);
00159
00160 static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
00161
00162
00163 static void list_tordataset(dns_rdatalist_t *rdatalist,
00164 dns_db_t *db, dns_dbnode_t *node,
00165 dns_rdataset_t *rdataset);
00166
00167 static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
00168 static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
00169 static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
00170 static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
00171 dns_name_t *name);
00172 static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
00173 static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
00174 static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
00175 dns_dbnode_t **nodep,
00176 dns_name_t *name);
00177 static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
00178 static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
00179 dns_name_t *name);
00180
00181 static dns_dbiteratormethods_t dbiterator_methods = {
00182 dbiterator_destroy,
00183 dbiterator_first,
00184 dbiterator_last,
00185 dbiterator_seek,
00186 dbiterator_prev,
00187 dbiterator_next,
00188 dbiterator_current,
00189 dbiterator_pause,
00190 dbiterator_origin
00191 };
00192
00193 static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
00194 static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
00195 static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
00196 static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
00197 dns_rdataset_t *rdataset);
00198
00199 static dns_rdatasetitermethods_t rdatasetiter_methods = {
00200 rdatasetiter_destroy,
00201 rdatasetiter_first,
00202 rdatasetiter_next,
00203 rdatasetiter_current
00204 };
00205
00206
00207
00208
00209 isc_result_t
00210 dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
00211 void *driverdata, unsigned int flags, isc_mem_t *mctx,
00212 dns_sdbimplementation_t **sdbimp)
00213 {
00214 dns_sdbimplementation_t *imp;
00215 isc_result_t result;
00216
00217 REQUIRE(drivername != NULL);
00218 REQUIRE(methods != NULL);
00219 REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL);
00220 REQUIRE(mctx != NULL);
00221 REQUIRE(sdbimp != NULL && *sdbimp == NULL);
00222 REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER |
00223 DNS_SDBFLAG_RELATIVERDATA |
00224 DNS_SDBFLAG_THREADSAFE|
00225 DNS_SDBFLAG_DNS64)) == 0);
00226
00227 imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t));
00228 if (imp == NULL)
00229 return (ISC_R_NOMEMORY);
00230 imp->methods = methods;
00231 imp->driverdata = driverdata;
00232 imp->flags = flags;
00233 imp->mctx = NULL;
00234 isc_mem_attach(mctx, &imp->mctx);
00235 result = isc_mutex_init(&imp->driverlock);
00236 if (result != ISC_R_SUCCESS)
00237 goto cleanup_mctx;
00238
00239 imp->dbimp = NULL;
00240 result = dns_db_register(drivername, dns_sdb_create, imp, mctx,
00241 &imp->dbimp);
00242 if (result != ISC_R_SUCCESS)
00243 goto cleanup_mutex;
00244 *sdbimp = imp;
00245
00246 return (ISC_R_SUCCESS);
00247
00248 cleanup_mutex:
00249 DESTROYLOCK(&imp->driverlock);
00250 cleanup_mctx:
00251 isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
00252 return (result);
00253 }
00254
00255 void
00256 dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) {
00257 dns_sdbimplementation_t *imp;
00258 isc_mem_t *mctx;
00259
00260 REQUIRE(sdbimp != NULL && *sdbimp != NULL);
00261
00262 imp = *sdbimp;
00263 dns_db_unregister(&imp->dbimp);
00264 DESTROYLOCK(&imp->driverlock);
00265
00266 mctx = imp->mctx;
00267 isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
00268 isc_mem_detach(&mctx);
00269
00270 *sdbimp = NULL;
00271 }
00272
00273 static inline unsigned int
00274 initial_size(unsigned int len) {
00275 unsigned int size;
00276
00277 for (size = 1024; size < (64 * 1024); size *= 2)
00278 if (len < size)
00279 return (size);
00280 return (65535);
00281 }
00282
00283 isc_result_t
00284 dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval,
00285 dns_ttl_t ttl, const unsigned char *rdatap,
00286 unsigned int rdlen)
00287 {
00288 dns_rdatalist_t *rdatalist;
00289 dns_rdata_t *rdata;
00290 isc_buffer_t *rdatabuf = NULL;
00291 isc_result_t result;
00292 isc_mem_t *mctx;
00293 isc_region_t region;
00294
00295 mctx = lookup->sdb->common.mctx;
00296
00297 rdatalist = ISC_LIST_HEAD(lookup->lists);
00298 while (rdatalist != NULL) {
00299 if (rdatalist->type == typeval)
00300 break;
00301 rdatalist = ISC_LIST_NEXT(rdatalist, link);
00302 }
00303
00304 if (rdatalist == NULL) {
00305 rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
00306 if (rdatalist == NULL)
00307 return (ISC_R_NOMEMORY);
00308 dns_rdatalist_init(rdatalist);
00309 rdatalist->rdclass = lookup->sdb->common.rdclass;
00310 rdatalist->type = typeval;
00311 rdatalist->ttl = ttl;
00312 ISC_LIST_APPEND(lookup->lists, rdatalist, link);
00313 } else
00314 if (rdatalist->ttl != ttl)
00315 return (DNS_R_BADTTL);
00316
00317 rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
00318 if (rdata == NULL)
00319 return (ISC_R_NOMEMORY);
00320
00321 result = isc_buffer_allocate(mctx, &rdatabuf, rdlen);
00322 if (result != ISC_R_SUCCESS)
00323 goto failure;
00324 DE_CONST(rdatap, region.base);
00325 region.length = rdlen;
00326 isc_buffer_copyregion(rdatabuf, ®ion);
00327 isc_buffer_usedregion(rdatabuf, ®ion);
00328 dns_rdata_init(rdata);
00329 dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type,
00330 ®ion);
00331 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
00332 ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
00333 rdata = NULL;
00334
00335 failure:
00336 if (rdata != NULL)
00337 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
00338 return (result);
00339 }
00340
00341 isc_result_t
00342 dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
00343 const char *data)
00344 {
00345 unsigned int datalen;
00346 dns_rdatatype_t typeval;
00347 isc_textregion_t r;
00348 isc_lex_t *lex = NULL;
00349 isc_result_t result;
00350 unsigned char *p = NULL;
00351 unsigned int size = 0;
00352 isc_mem_t *mctx;
00353 dns_sdbimplementation_t *imp;
00354 dns_name_t *origin;
00355 isc_buffer_t b;
00356 isc_buffer_t rb;
00357
00358 REQUIRE(VALID_SDBLOOKUP(lookup));
00359 REQUIRE(type != NULL);
00360 REQUIRE(data != NULL);
00361
00362 mctx = lookup->sdb->common.mctx;
00363
00364 DE_CONST(type, r.base);
00365 r.length = strlen(type);
00366 result = dns_rdatatype_fromtext(&typeval, &r);
00367 if (result != ISC_R_SUCCESS)
00368 return (result);
00369
00370 imp = lookup->sdb->implementation;
00371 if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
00372 origin = &lookup->sdb->common.origin;
00373 else
00374 origin = dns_rootname;
00375
00376 result = isc_lex_create(mctx, 64, &lex);
00377 if (result != ISC_R_SUCCESS)
00378 goto failure;
00379
00380 datalen = strlen(data);
00381 size = initial_size(datalen);
00382 do {
00383 isc_buffer_constinit(&b, data, datalen);
00384 isc_buffer_add(&b, datalen);
00385 result = isc_lex_openbuffer(lex, &b);
00386 if (result != ISC_R_SUCCESS)
00387 goto failure;
00388
00389 if (size >= 65535)
00390 size = 65535;
00391 p = isc_mem_get(mctx, size);
00392 if (p == NULL) {
00393 result = ISC_R_NOMEMORY;
00394 goto failure;
00395 }
00396 isc_buffer_init(&rb, p, size);
00397 result = dns_rdata_fromtext(NULL,
00398 lookup->sdb->common.rdclass,
00399 typeval, lex,
00400 origin, 0,
00401 mctx, &rb,
00402 &lookup->callbacks);
00403 if (result != ISC_R_NOSPACE)
00404 break;
00405
00406
00407
00408
00409 if (size >= 65535)
00410 break;
00411 isc_mem_put(mctx, p, size);
00412 p = NULL;
00413 size *= 2;
00414 } while (result == ISC_R_NOSPACE);
00415
00416 if (result != ISC_R_SUCCESS)
00417 goto failure;
00418
00419 result = dns_sdb_putrdata(lookup, typeval, ttl,
00420 isc_buffer_base(&rb),
00421 isc_buffer_usedlength(&rb));
00422 failure:
00423 if (p != NULL)
00424 isc_mem_put(mctx, p, size);
00425 if (lex != NULL)
00426 isc_lex_destroy(&lex);
00427
00428 return (result);
00429 }
00430
00431 static isc_result_t
00432 getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
00433 dns_name_t *newname, *origin;
00434 dns_fixedname_t fnewname;
00435 dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db;
00436 dns_sdbimplementation_t *imp = sdb->implementation;
00437 dns_sdbnode_t *sdbnode;
00438 isc_mem_t *mctx = sdb->common.mctx;
00439 isc_buffer_t b;
00440 isc_result_t result;
00441
00442 dns_fixedname_init(&fnewname);
00443 newname = dns_fixedname_name(&fnewname);
00444
00445 if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
00446 origin = &sdb->common.origin;
00447 else
00448 origin = dns_rootname;
00449 isc_buffer_constinit(&b, name, strlen(name));
00450 isc_buffer_add(&b, strlen(name));
00451
00452 result = dns_name_fromtext(newname, &b, origin, 0, NULL);
00453 if (result != ISC_R_SUCCESS)
00454 return (result);
00455
00456 if (allnodes->common.relative_names) {
00457
00458 unsigned int nlabels = dns_name_countlabels(newname);
00459 dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
00460 }
00461
00462 sdbnode = ISC_LIST_HEAD(allnodes->nodelist);
00463 if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) {
00464 sdbnode = NULL;
00465 result = createnode(sdb, &sdbnode);
00466 if (result != ISC_R_SUCCESS)
00467 return (result);
00468 sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t));
00469 if (sdbnode->name == NULL) {
00470 destroynode(sdbnode);
00471 return (ISC_R_NOMEMORY);
00472 }
00473 dns_name_init(sdbnode->name, NULL);
00474 result = dns_name_dup(newname, mctx, sdbnode->name);
00475 if (result != ISC_R_SUCCESS) {
00476 isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t));
00477 destroynode(sdbnode);
00478 return (result);
00479 }
00480 ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link);
00481 if (allnodes->origin == NULL &&
00482 dns_name_equal(newname, &sdb->common.origin))
00483 allnodes->origin = sdbnode;
00484 }
00485 *nodep = sdbnode;
00486 return (ISC_R_SUCCESS);
00487 }
00488
00489 isc_result_t
00490 dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
00491 const char *type, dns_ttl_t ttl, const char *data)
00492 {
00493 isc_result_t result;
00494 dns_sdbnode_t *sdbnode = NULL;
00495 result = getnode(allnodes, name, &sdbnode);
00496 if (result != ISC_R_SUCCESS)
00497 return (result);
00498 return (dns_sdb_putrr(sdbnode, type, ttl, data));
00499 }
00500
00501 isc_result_t
00502 dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name,
00503 dns_rdatatype_t type, dns_ttl_t ttl,
00504 const void *rdata, unsigned int rdlen)
00505 {
00506 isc_result_t result;
00507 dns_sdbnode_t *sdbnode = NULL;
00508 result = getnode(allnodes, name, &sdbnode);
00509 if (result != ISC_R_SUCCESS)
00510 return (result);
00511 return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen));
00512 }
00513
00514 isc_result_t
00515 dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname,
00516 isc_uint32_t serial)
00517 {
00518 char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
00519 int n;
00520
00521 REQUIRE(mname != NULL);
00522 REQUIRE(rname != NULL);
00523
00524 n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u",
00525 mname, rname, serial,
00526 SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY,
00527 SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM);
00528 if (n >= (int)sizeof(str) || n < 0)
00529 return (ISC_R_NOSPACE);
00530 return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str));
00531 }
00532
00533
00534
00535
00536
00537 static void
00538 attach(dns_db_t *source, dns_db_t **targetp) {
00539 dns_sdb_t *sdb = (dns_sdb_t *) source;
00540
00541 REQUIRE(VALID_SDB(sdb));
00542
00543 LOCK(&sdb->lock);
00544 REQUIRE(sdb->references > 0);
00545 sdb->references++;
00546 UNLOCK(&sdb->lock);
00547
00548 *targetp = source;
00549 }
00550
00551 static void
00552 destroy(dns_sdb_t *sdb) {
00553 isc_mem_t *mctx;
00554 dns_sdbimplementation_t *imp = sdb->implementation;
00555
00556 mctx = sdb->common.mctx;
00557
00558 if (imp->methods->destroy != NULL) {
00559 MAYBE_LOCK(sdb);
00560 imp->methods->destroy(sdb->zone, imp->driverdata,
00561 &sdb->dbdata);
00562 MAYBE_UNLOCK(sdb);
00563 }
00564
00565 isc_mem_free(mctx, sdb->zone);
00566 DESTROYLOCK(&sdb->lock);
00567
00568 sdb->common.magic = 0;
00569 sdb->common.impmagic = 0;
00570
00571 dns_name_free(&sdb->common.origin, mctx);
00572
00573 isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
00574 isc_mem_detach(&mctx);
00575 }
00576
00577 static void
00578 detach(dns_db_t **dbp) {
00579 dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
00580 isc_boolean_t need_destroy = ISC_FALSE;
00581
00582 REQUIRE(VALID_SDB(sdb));
00583 LOCK(&sdb->lock);
00584 REQUIRE(sdb->references > 0);
00585 sdb->references--;
00586 if (sdb->references == 0)
00587 need_destroy = ISC_TRUE;
00588 UNLOCK(&sdb->lock);
00589
00590 if (need_destroy)
00591 destroy(sdb);
00592
00593 *dbp = NULL;
00594 }
00595
00596 static isc_result_t
00597 beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00598 UNUSED(db);
00599 UNUSED(callbacks);
00600 return (ISC_R_NOTIMPLEMENTED);
00601 }
00602
00603 static isc_result_t
00604 endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00605 UNUSED(db);
00606 UNUSED(callbacks);
00607 return (ISC_R_NOTIMPLEMENTED);
00608 }
00609
00610 static isc_result_t
00611 dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
00612 dns_masterformat_t masterformat) {
00613 UNUSED(db);
00614 UNUSED(version);
00615 UNUSED(filename);
00616 UNUSED(masterformat);
00617 return (ISC_R_NOTIMPLEMENTED);
00618 }
00619
00620 static void
00621 currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
00622 REQUIRE(versionp != NULL && *versionp == NULL);
00623
00624 UNUSED(db);
00625
00626 *versionp = (void *) &dummy;
00627 return;
00628 }
00629
00630 static isc_result_t
00631 newversion(dns_db_t *db, dns_dbversion_t **versionp) {
00632 UNUSED(db);
00633 UNUSED(versionp);
00634
00635 return (ISC_R_NOTIMPLEMENTED);
00636 }
00637
00638 static void
00639 attachversion(dns_db_t *db, dns_dbversion_t *source,
00640 dns_dbversion_t **targetp)
00641 {
00642 REQUIRE(source != NULL && source == (void *) &dummy);
00643 REQUIRE(targetp != NULL && *targetp == NULL);
00644
00645 UNUSED(db);
00646 *targetp = source;
00647 return;
00648 }
00649
00650 static void
00651 closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
00652 REQUIRE(versionp != NULL && *versionp == (void *) &dummy);
00653 REQUIRE(commit == ISC_FALSE);
00654
00655 UNUSED(db);
00656 UNUSED(commit);
00657
00658 *versionp = NULL;
00659 }
00660
00661 static isc_result_t
00662 createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) {
00663 dns_sdbnode_t *node;
00664 isc_result_t result;
00665
00666 node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t));
00667 if (node == NULL)
00668 return (ISC_R_NOMEMORY);
00669
00670 node->sdb = NULL;
00671 attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb);
00672 ISC_LIST_INIT(node->lists);
00673 ISC_LIST_INIT(node->buffers);
00674 ISC_LINK_INIT(node, link);
00675 node->name = NULL;
00676 result = isc_mutex_init(&node->lock);
00677 if (result != ISC_R_SUCCESS) {
00678 isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t));
00679 return (result);
00680 }
00681 dns_rdatacallbacks_init(&node->callbacks);
00682 node->references = 1;
00683 node->magic = SDBLOOKUP_MAGIC;
00684
00685 *nodep = node;
00686 return (ISC_R_SUCCESS);
00687 }
00688
00689 static void
00690 destroynode(dns_sdbnode_t *node) {
00691 dns_rdatalist_t *list;
00692 dns_rdata_t *rdata;
00693 isc_buffer_t *b;
00694 dns_sdb_t *sdb;
00695 isc_mem_t *mctx;
00696
00697 sdb = node->sdb;
00698 mctx = sdb->common.mctx;
00699
00700 while (!ISC_LIST_EMPTY(node->lists)) {
00701 list = ISC_LIST_HEAD(node->lists);
00702 while (!ISC_LIST_EMPTY(list->rdata)) {
00703 rdata = ISC_LIST_HEAD(list->rdata);
00704 ISC_LIST_UNLINK(list->rdata, rdata, link);
00705 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
00706 }
00707 ISC_LIST_UNLINK(node->lists, list, link);
00708 isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
00709 }
00710
00711 while (!ISC_LIST_EMPTY(node->buffers)) {
00712 b = ISC_LIST_HEAD(node->buffers);
00713 ISC_LIST_UNLINK(node->buffers, b, link);
00714 isc_buffer_free(&b);
00715 }
00716
00717 if (node->name != NULL) {
00718 dns_name_free(node->name, mctx);
00719 isc_mem_put(mctx, node->name, sizeof(dns_name_t));
00720 }
00721 DESTROYLOCK(&node->lock);
00722 node->magic = 0;
00723 isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
00724 detach((dns_db_t **) (void *)&sdb);
00725 }
00726
00727 static isc_result_t
00728 findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
00729 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
00730 dns_dbnode_t **nodep)
00731 {
00732 dns_sdb_t *sdb = (dns_sdb_t *)db;
00733 dns_sdbnode_t *node = NULL;
00734 isc_result_t result;
00735 isc_buffer_t b;
00736 char namestr[DNS_NAME_MAXTEXT + 1];
00737 isc_boolean_t isorigin;
00738 dns_sdbimplementation_t *imp;
00739 dns_name_t relname;
00740 unsigned int labels;
00741
00742 REQUIRE(VALID_SDB(sdb));
00743 REQUIRE(create == ISC_FALSE);
00744 REQUIRE(nodep != NULL && *nodep == NULL);
00745
00746 UNUSED(name);
00747 UNUSED(create);
00748
00749 imp = sdb->implementation;
00750
00751 isorigin = dns_name_equal(name, &sdb->common.origin);
00752
00753 if (imp->methods->lookup2 != NULL) {
00754 if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
00755 labels = dns_name_countlabels(name) -
00756 dns_name_countlabels(&db->origin);
00757 dns_name_init(&relname, NULL);
00758 dns_name_getlabelsequence(name, 0, labels, &relname);
00759 name = &relname;
00760 }
00761 } else {
00762 isc_buffer_init(&b, namestr, sizeof(namestr));
00763 if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
00764
00765 labels = dns_name_countlabels(name) -
00766 dns_name_countlabels(&db->origin);
00767 dns_name_init(&relname, NULL);
00768 dns_name_getlabelsequence(name, 0, labels, &relname);
00769 result = dns_name_totext(&relname, ISC_TRUE, &b);
00770 if (result != ISC_R_SUCCESS)
00771 return (result);
00772 } else {
00773 result = dns_name_totext(name, ISC_TRUE, &b);
00774 if (result != ISC_R_SUCCESS)
00775 return (result);
00776 }
00777 isc_buffer_putuint8(&b, 0);
00778 }
00779
00780 result = createnode(sdb, &node);
00781 if (result != ISC_R_SUCCESS)
00782 return (result);
00783
00784 MAYBE_LOCK(sdb);
00785 if (imp->methods->lookup2 != NULL)
00786 result = imp->methods->lookup2(&sdb->common.origin, name,
00787 sdb->dbdata, node, methods,
00788 clientinfo);
00789 else
00790 result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
00791 node, methods, clientinfo);
00792 MAYBE_UNLOCK(sdb);
00793 if (result != ISC_R_SUCCESS &&
00794 !(result == ISC_R_NOTFOUND &&
00795 isorigin && imp->methods->authority != NULL))
00796 {
00797 destroynode(node);
00798 return (result);
00799 }
00800
00801 if (isorigin && imp->methods->authority != NULL) {
00802 MAYBE_LOCK(sdb);
00803 result = imp->methods->authority(sdb->zone, sdb->dbdata, node);
00804 MAYBE_UNLOCK(sdb);
00805 if (result != ISC_R_SUCCESS) {
00806 destroynode(node);
00807 return (result);
00808 }
00809 }
00810
00811 *nodep = node;
00812 return (ISC_R_SUCCESS);
00813 }
00814
00815 static isc_result_t
00816 findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
00817 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
00818 dns_dbnode_t **nodep, dns_name_t *foundname,
00819 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
00820 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00821 {
00822 dns_sdb_t *sdb = (dns_sdb_t *)db;
00823 dns_dbnode_t *node = NULL;
00824 dns_fixedname_t fname;
00825 dns_rdataset_t xrdataset;
00826 dns_name_t *xname;
00827 unsigned int nlabels, olabels;
00828 isc_result_t result;
00829 unsigned int i;
00830 unsigned int flags;
00831
00832 REQUIRE(VALID_SDB(sdb));
00833 REQUIRE(nodep == NULL || *nodep == NULL);
00834 REQUIRE(version == NULL || version == (void *) &dummy);
00835
00836 UNUSED(options);
00837
00838 if (!dns_name_issubdomain(name, &db->origin))
00839 return (DNS_R_NXDOMAIN);
00840
00841 olabels = dns_name_countlabels(&db->origin);
00842 nlabels = dns_name_countlabels(name);
00843
00844 dns_fixedname_init(&fname);
00845 xname = dns_fixedname_name(&fname);
00846
00847 if (rdataset == NULL) {
00848 dns_rdataset_init(&xrdataset);
00849 rdataset = &xrdataset;
00850 }
00851
00852 result = DNS_R_NXDOMAIN;
00853 flags = sdb->implementation->flags;
00854 i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels;
00855 for (; i <= nlabels; i++) {
00856
00857
00858
00859 dns_name_getlabelsequence(name, nlabels - i, i, xname);
00860 result = findnodeext(db, xname, ISC_FALSE, methods,
00861 clientinfo, &node);
00862 if (result == ISC_R_NOTFOUND) {
00863
00864
00865
00866 if (i == olabels)
00867 return (DNS_R_BADDB);
00868 result = DNS_R_NXDOMAIN;
00869 continue;
00870 }
00871 if (result != ISC_R_SUCCESS)
00872 return (result);
00873
00874
00875
00876
00877 if ((flags & DNS_SDBFLAG_DNS64) != 0)
00878 goto skip;
00879
00880
00881
00882
00883 if ((flags & DNS_SDBFLAG_DNS64) != 0)
00884 goto skip;
00885
00886
00887
00888
00889
00890 if (i < nlabels) {
00891 result = findrdataset(db, node, version,
00892 dns_rdatatype_dname,
00893 0, now, rdataset, sigrdataset);
00894 if (result == ISC_R_SUCCESS) {
00895 result = DNS_R_DNAME;
00896 break;
00897 }
00898 }
00899
00900
00901
00902
00903
00904 if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
00905 result = findrdataset(db, node, version,
00906 dns_rdatatype_ns,
00907 0, now, rdataset, sigrdataset);
00908 if (result == ISC_R_SUCCESS) {
00909 if (i == nlabels && type == dns_rdatatype_any)
00910 {
00911 result = DNS_R_ZONECUT;
00912 dns_rdataset_disassociate(rdataset);
00913 if (sigrdataset != NULL &&
00914 dns_rdataset_isassociated
00915 (sigrdataset)) {
00916 dns_rdataset_disassociate
00917 (sigrdataset);
00918 }
00919 } else
00920 result = DNS_R_DELEGATION;
00921 break;
00922 }
00923 }
00924
00925
00926
00927
00928
00929 if (i < nlabels) {
00930 destroynode(node);
00931 node = NULL;
00932 continue;
00933 }
00934
00935 skip:
00936
00937
00938
00939 if (type == dns_rdatatype_any) {
00940 result = ISC_R_SUCCESS;
00941 break;
00942 }
00943
00944
00945
00946
00947 result = findrdataset(db, node, version, type,
00948 0, now, rdataset, sigrdataset);
00949 if (result == ISC_R_SUCCESS)
00950 break;
00951
00952
00953
00954
00955 if (type != dns_rdatatype_cname) {
00956 result = findrdataset(db, node, version,
00957 dns_rdatatype_cname,
00958 0, now, rdataset, sigrdataset);
00959 if (result == ISC_R_SUCCESS) {
00960 result = DNS_R_CNAME;
00961 break;
00962 }
00963 }
00964
00965 result = DNS_R_NXRRSET;
00966 break;
00967 }
00968
00969 if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
00970 dns_rdataset_disassociate(rdataset);
00971
00972 if (foundname != NULL) {
00973 isc_result_t xresult;
00974
00975 xresult = dns_name_copy(xname, foundname, NULL);
00976 if (xresult != ISC_R_SUCCESS) {
00977 if (node != NULL)
00978 destroynode(node);
00979 if (dns_rdataset_isassociated(rdataset))
00980 dns_rdataset_disassociate(rdataset);
00981 return (DNS_R_BADDB);
00982 }
00983 }
00984
00985 if (nodep != NULL)
00986 *nodep = node;
00987 else if (node != NULL)
00988 detachnode(db, &node);
00989
00990 return (result);
00991 }
00992
00993 static isc_result_t
00994 findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
00995 isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
00996 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00997 {
00998 UNUSED(db);
00999 UNUSED(name);
01000 UNUSED(options);
01001 UNUSED(now);
01002 UNUSED(nodep);
01003 UNUSED(foundname);
01004 UNUSED(rdataset);
01005 UNUSED(sigrdataset);
01006
01007 return (ISC_R_NOTIMPLEMENTED);
01008 }
01009
01010 static void
01011 attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
01012 dns_sdb_t *sdb = (dns_sdb_t *)db;
01013 dns_sdbnode_t *node = (dns_sdbnode_t *)source;
01014
01015 REQUIRE(VALID_SDB(sdb));
01016
01017 UNUSED(sdb);
01018
01019 LOCK(&node->lock);
01020 INSIST(node->references > 0);
01021 node->references++;
01022 INSIST(node->references != 0);
01023 UNLOCK(&node->lock);
01024
01025 *targetp = source;
01026 }
01027
01028 static void
01029 detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
01030 dns_sdb_t *sdb = (dns_sdb_t *)db;
01031 dns_sdbnode_t *node;
01032 isc_boolean_t need_destroy = ISC_FALSE;
01033
01034 REQUIRE(VALID_SDB(sdb));
01035 REQUIRE(targetp != NULL && *targetp != NULL);
01036
01037 UNUSED(sdb);
01038
01039 node = (dns_sdbnode_t *)(*targetp);
01040
01041 LOCK(&node->lock);
01042 INSIST(node->references > 0);
01043 node->references--;
01044 if (node->references == 0)
01045 need_destroy = ISC_TRUE;
01046 UNLOCK(&node->lock);
01047
01048 if (need_destroy)
01049 destroynode(node);
01050
01051 *targetp = NULL;
01052 }
01053
01054 static isc_result_t
01055 expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
01056 UNUSED(db);
01057 UNUSED(node);
01058 UNUSED(now);
01059 INSIST(0);
01060 return (ISC_R_UNEXPECTED);
01061 }
01062
01063 static void
01064 printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
01065 UNUSED(db);
01066 UNUSED(node);
01067 UNUSED(out);
01068 return;
01069 }
01070
01071 static isc_result_t
01072 createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
01073 {
01074 dns_sdb_t *sdb = (dns_sdb_t *)db;
01075 sdb_dbiterator_t *sdbiter;
01076 dns_sdbimplementation_t *imp = sdb->implementation;
01077 isc_result_t result;
01078
01079 REQUIRE(VALID_SDB(sdb));
01080
01081 if (imp->methods->allnodes == NULL)
01082 return (ISC_R_NOTIMPLEMENTED);
01083
01084 if ((options & DNS_DB_NSEC3ONLY) != 0 ||
01085 (options & DNS_DB_NONSEC3) != 0)
01086 return (ISC_R_NOTIMPLEMENTED);
01087
01088 sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t));
01089 if (sdbiter == NULL)
01090 return (ISC_R_NOMEMORY);
01091
01092 sdbiter->common.methods = &dbiterator_methods;
01093 sdbiter->common.db = NULL;
01094 dns_db_attach(db, &sdbiter->common.db);
01095 sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
01096 sdbiter->common.magic = DNS_DBITERATOR_MAGIC;
01097 ISC_LIST_INIT(sdbiter->nodelist);
01098 sdbiter->current = NULL;
01099 sdbiter->origin = NULL;
01100
01101 MAYBE_LOCK(sdb);
01102 result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter);
01103 MAYBE_UNLOCK(sdb);
01104 if (result != ISC_R_SUCCESS) {
01105 dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter);
01106 return (result);
01107 }
01108
01109 if (sdbiter->origin != NULL) {
01110 ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link);
01111 ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link);
01112 }
01113
01114 *iteratorp = (dns_dbiterator_t *)sdbiter;
01115
01116 return (ISC_R_SUCCESS);
01117 }
01118
01119 static isc_result_t
01120 findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01121 dns_rdatatype_t type, dns_rdatatype_t covers,
01122 isc_stdtime_t now, dns_rdataset_t *rdataset,
01123 dns_rdataset_t *sigrdataset)
01124 {
01125 dns_rdatalist_t *list;
01126 dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node;
01127
01128 REQUIRE(VALID_SDBNODE(node));
01129
01130 UNUSED(db);
01131 UNUSED(version);
01132 UNUSED(covers);
01133 UNUSED(now);
01134 UNUSED(sigrdataset);
01135
01136 if (type == dns_rdatatype_rrsig)
01137 return (ISC_R_NOTIMPLEMENTED);
01138
01139 list = ISC_LIST_HEAD(sdbnode->lists);
01140 while (list != NULL) {
01141 if (list->type == type)
01142 break;
01143 list = ISC_LIST_NEXT(list, link);
01144 }
01145 if (list == NULL)
01146 return (ISC_R_NOTFOUND);
01147
01148 list_tordataset(list, db, node, rdataset);
01149
01150 return (ISC_R_SUCCESS);
01151 }
01152
01153 static isc_result_t
01154 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01155 isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
01156 {
01157 sdb_rdatasetiter_t *iterator;
01158
01159 REQUIRE(version == NULL || version == &dummy);
01160
01161 UNUSED(version);
01162 UNUSED(now);
01163
01164 iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t));
01165 if (iterator == NULL)
01166 return (ISC_R_NOMEMORY);
01167
01168 iterator->common.magic = DNS_RDATASETITER_MAGIC;
01169 iterator->common.methods = &rdatasetiter_methods;
01170 iterator->common.db = db;
01171 iterator->common.node = NULL;
01172 attachnode(db, node, &iterator->common.node);
01173 iterator->common.version = version;
01174 iterator->common.now = now;
01175
01176 *iteratorp = (dns_rdatasetiter_t *)iterator;
01177
01178 return (ISC_R_SUCCESS);
01179 }
01180
01181 static isc_result_t
01182 addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01183 isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
01184 dns_rdataset_t *addedrdataset)
01185 {
01186 UNUSED(db);
01187 UNUSED(node);
01188 UNUSED(version);
01189 UNUSED(now);
01190 UNUSED(rdataset);
01191 UNUSED(options);
01192 UNUSED(addedrdataset);
01193
01194 return (ISC_R_NOTIMPLEMENTED);
01195 }
01196
01197 static isc_result_t
01198 subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01199 dns_rdataset_t *rdataset, unsigned int options,
01200 dns_rdataset_t *newrdataset)
01201 {
01202 UNUSED(db);
01203 UNUSED(node);
01204 UNUSED(version);
01205 UNUSED(rdataset);
01206 UNUSED(options);
01207 UNUSED(newrdataset);
01208
01209 return (ISC_R_NOTIMPLEMENTED);
01210 }
01211
01212 static isc_result_t
01213 deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01214 dns_rdatatype_t type, dns_rdatatype_t covers)
01215 {
01216 UNUSED(db);
01217 UNUSED(node);
01218 UNUSED(version);
01219 UNUSED(type);
01220 UNUSED(covers);
01221
01222 return (ISC_R_NOTIMPLEMENTED);
01223 }
01224
01225 static isc_boolean_t
01226 issecure(dns_db_t *db) {
01227 UNUSED(db);
01228
01229 return (ISC_FALSE);
01230 }
01231
01232 static unsigned int
01233 nodecount(dns_db_t *db) {
01234 UNUSED(db);
01235
01236 return (0);
01237 }
01238
01239 static isc_boolean_t
01240 ispersistent(dns_db_t *db) {
01241 UNUSED(db);
01242 return (ISC_TRUE);
01243 }
01244
01245 static void
01246 overmem(dns_db_t *db, isc_boolean_t over) {
01247 UNUSED(db);
01248 UNUSED(over);
01249 }
01250
01251 static void
01252 settask(dns_db_t *db, isc_task_t *task) {
01253 UNUSED(db);
01254 UNUSED(task);
01255 }
01256
01257
01258 static dns_dbmethods_t sdb_methods = {
01259 attach,
01260 detach,
01261 beginload,
01262 endload,
01263 NULL,
01264 dump,
01265 currentversion,
01266 newversion,
01267 attachversion,
01268 closeversion,
01269 NULL,
01270 NULL,
01271 findzonecut,
01272 attachnode,
01273 detachnode,
01274 expirenode,
01275 printnode,
01276 createiterator,
01277 findrdataset,
01278 allrdatasets,
01279 addrdataset,
01280 subtractrdataset,
01281 deleterdataset,
01282 issecure,
01283 nodecount,
01284 ispersistent,
01285 overmem,
01286 settask,
01287 NULL,
01288 NULL,
01289 NULL,
01290 NULL,
01291 NULL,
01292 NULL,
01293 NULL,
01294 NULL,
01295 NULL,
01296 NULL,
01297 NULL,
01298 findnodeext,
01299 findext,
01300 NULL,
01301 NULL
01302 };
01303
01304 static isc_result_t
01305 dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
01306 dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
01307 void *driverarg, dns_db_t **dbp)
01308 {
01309 dns_sdb_t *sdb;
01310 isc_result_t result;
01311 char zonestr[DNS_NAME_MAXTEXT + 1];
01312 isc_buffer_t b;
01313 dns_sdbimplementation_t *imp;
01314
01315 REQUIRE(driverarg != NULL);
01316
01317 imp = driverarg;
01318
01319 if (type != dns_dbtype_zone)
01320 return (ISC_R_NOTIMPLEMENTED);
01321
01322 sdb = isc_mem_get(mctx, sizeof(dns_sdb_t));
01323 if (sdb == NULL)
01324 return (ISC_R_NOMEMORY);
01325 memset(sdb, 0, sizeof(dns_sdb_t));
01326
01327 dns_name_init(&sdb->common.origin, NULL);
01328 sdb->common.attributes = 0;
01329 sdb->common.methods = &sdb_methods;
01330 sdb->common.rdclass = rdclass;
01331 sdb->common.mctx = NULL;
01332 sdb->implementation = imp;
01333
01334 isc_mem_attach(mctx, &sdb->common.mctx);
01335
01336 result = isc_mutex_init(&sdb->lock);
01337 if (result != ISC_R_SUCCESS)
01338 goto cleanup_mctx;
01339
01340 result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin);
01341 if (result != ISC_R_SUCCESS)
01342 goto cleanup_lock;
01343
01344 isc_buffer_init(&b, zonestr, sizeof(zonestr));
01345 result = dns_name_totext(origin, ISC_TRUE, &b);
01346 if (result != ISC_R_SUCCESS)
01347 goto cleanup_origin;
01348 isc_buffer_putuint8(&b, 0);
01349
01350 sdb->zone = isc_mem_strdup(mctx, zonestr);
01351 if (sdb->zone == NULL) {
01352 result = ISC_R_NOMEMORY;
01353 goto cleanup_origin;
01354 }
01355
01356 sdb->dbdata = NULL;
01357 if (imp->methods->create != NULL) {
01358 MAYBE_LOCK(sdb);
01359 result = imp->methods->create(sdb->zone, argc, argv,
01360 imp->driverdata, &sdb->dbdata);
01361 MAYBE_UNLOCK(sdb);
01362 if (result != ISC_R_SUCCESS)
01363 goto cleanup_zonestr;
01364 }
01365
01366 sdb->references = 1;
01367
01368 sdb->common.magic = DNS_DB_MAGIC;
01369 sdb->common.impmagic = SDB_MAGIC;
01370
01371 *dbp = (dns_db_t *)sdb;
01372
01373 return (ISC_R_SUCCESS);
01374
01375 cleanup_zonestr:
01376 isc_mem_free(mctx, sdb->zone);
01377 cleanup_origin:
01378 dns_name_free(&sdb->common.origin, mctx);
01379 cleanup_lock:
01380 (void)isc_mutex_destroy(&sdb->lock);
01381 cleanup_mctx:
01382 isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
01383 isc_mem_detach(&mctx);
01384
01385 return (result);
01386 }
01387
01388
01389
01390
01391
01392
01393 static void
01394 disassociate(dns_rdataset_t *rdataset) {
01395 dns_dbnode_t *node = rdataset->private5;
01396 dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
01397 dns_db_t *db = (dns_db_t *) sdbnode->sdb;
01398
01399 detachnode(db, &node);
01400 isc__rdatalist_disassociate(rdataset);
01401 }
01402
01403 static void
01404 rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
01405 dns_dbnode_t *node = source->private5;
01406 dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
01407 dns_db_t *db = (dns_db_t *) sdbnode->sdb;
01408 dns_dbnode_t *tempdb = NULL;
01409
01410 isc__rdatalist_clone(source, target);
01411 attachnode(db, node, &tempdb);
01412 source->private5 = tempdb;
01413 }
01414
01415 static dns_rdatasetmethods_t methods = {
01416 disassociate,
01417 isc__rdatalist_first,
01418 isc__rdatalist_next,
01419 isc__rdatalist_current,
01420 rdataset_clone,
01421 isc__rdatalist_count,
01422 isc__rdatalist_addnoqname,
01423 isc__rdatalist_getnoqname,
01424 NULL,
01425 NULL,
01426 NULL,
01427 NULL,
01428 NULL,
01429 NULL,
01430 NULL,
01431 NULL,
01432 NULL,
01433 NULL
01434 };
01435
01436 static void
01437 list_tordataset(dns_rdatalist_t *rdatalist,
01438 dns_db_t *db, dns_dbnode_t *node,
01439 dns_rdataset_t *rdataset)
01440 {
01441
01442
01443
01444
01445
01446
01447
01448
01449 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
01450 ISC_R_SUCCESS);
01451
01452 rdataset->methods = &methods;
01453 dns_db_attachnode(db, node, &rdataset->private5);
01454 }
01455
01456
01457
01458
01459 static void
01460 dbiterator_destroy(dns_dbiterator_t **iteratorp) {
01461 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp);
01462 dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db;
01463
01464 while (!ISC_LIST_EMPTY(sdbiter->nodelist)) {
01465 dns_sdbnode_t *node;
01466 node = ISC_LIST_HEAD(sdbiter->nodelist);
01467 ISC_LIST_UNLINK(sdbiter->nodelist, node, link);
01468 destroynode(node);
01469 }
01470
01471 dns_db_detach(&sdbiter->common.db);
01472 isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t));
01473
01474 *iteratorp = NULL;
01475 }
01476
01477 static isc_result_t
01478 dbiterator_first(dns_dbiterator_t *iterator) {
01479 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01480
01481 sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
01482 if (sdbiter->current == NULL)
01483 return (ISC_R_NOMORE);
01484 else
01485 return (ISC_R_SUCCESS);
01486 }
01487
01488 static isc_result_t
01489 dbiterator_last(dns_dbiterator_t *iterator) {
01490 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01491
01492 sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist);
01493 if (sdbiter->current == NULL)
01494 return (ISC_R_NOMORE);
01495 else
01496 return (ISC_R_SUCCESS);
01497 }
01498
01499 static isc_result_t
01500 dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
01501 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01502
01503 sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
01504 while (sdbiter->current != NULL) {
01505 if (dns_name_equal(sdbiter->current->name, name))
01506 return (ISC_R_SUCCESS);
01507 sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
01508 }
01509 return (ISC_R_NOTFOUND);
01510 }
01511
01512 static isc_result_t
01513 dbiterator_prev(dns_dbiterator_t *iterator) {
01514 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01515
01516 sdbiter->current = ISC_LIST_PREV(sdbiter->current, link);
01517 if (sdbiter->current == NULL)
01518 return (ISC_R_NOMORE);
01519 else
01520 return (ISC_R_SUCCESS);
01521 }
01522
01523 static isc_result_t
01524 dbiterator_next(dns_dbiterator_t *iterator) {
01525 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01526
01527 sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
01528 if (sdbiter->current == NULL)
01529 return (ISC_R_NOMORE);
01530 else
01531 return (ISC_R_SUCCESS);
01532 }
01533
01534 static isc_result_t
01535 dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
01536 dns_name_t *name)
01537 {
01538 sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
01539
01540 attachnode(iterator->db, sdbiter->current, nodep);
01541 if (name != NULL)
01542 return (dns_name_copy(sdbiter->current->name, name, NULL));
01543 return (ISC_R_SUCCESS);
01544 }
01545
01546 static isc_result_t
01547 dbiterator_pause(dns_dbiterator_t *iterator) {
01548 UNUSED(iterator);
01549 return (ISC_R_SUCCESS);
01550 }
01551
01552 static isc_result_t
01553 dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
01554 UNUSED(iterator);
01555 return (dns_name_copy(dns_rootname, name, NULL));
01556 }
01557
01558
01559
01560
01561
01562 static void
01563 rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
01564 sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp);
01565 detachnode(sdbiterator->common.db, &sdbiterator->common.node);
01566 isc_mem_put(sdbiterator->common.db->mctx, sdbiterator,
01567 sizeof(sdb_rdatasetiter_t));
01568 *iteratorp = NULL;
01569 }
01570
01571 static isc_result_t
01572 rdatasetiter_first(dns_rdatasetiter_t *iterator) {
01573 sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
01574 dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node;
01575
01576 if (ISC_LIST_EMPTY(sdbnode->lists))
01577 return (ISC_R_NOMORE);
01578 sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists);
01579 return (ISC_R_SUCCESS);
01580 }
01581
01582 static isc_result_t
01583 rdatasetiter_next(dns_rdatasetiter_t *iterator) {
01584 sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
01585
01586 sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link);
01587 if (sdbiterator->current == NULL)
01588 return (ISC_R_NOMORE);
01589 else
01590 return (ISC_R_SUCCESS);
01591 }
01592
01593 static void
01594 rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
01595 sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
01596
01597 list_tordataset(sdbiterator->current, iterator->db, iterator->node,
01598 rdataset);
01599 }