00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <config.h>
00027
00028 #include <isc/buffer.h>
00029 #include <isc/mem.h>
00030 #include <isc/once.h>
00031 #include <isc/rwlock.h>
00032 #include <isc/string.h>
00033 #include <isc/util.h>
00034
00035 #include <dns/callbacks.h>
00036 #include <dns/clientinfo.h>
00037 #include <dns/db.h>
00038 #include <dns/dbiterator.h>
00039 #include <dns/log.h>
00040 #include <dns/master.h>
00041 #include <dns/rdata.h>
00042 #include <dns/rdataset.h>
00043 #include <dns/rdatasetiter.h>
00044 #include <dns/result.h>
00045
00046
00047
00048
00049
00050 struct dns_dbimplementation {
00051 const char * name;
00052 dns_dbcreatefunc_t create;
00053 isc_mem_t * mctx;
00054 void * driverarg;
00055 ISC_LINK(dns_dbimplementation_t) link;
00056 };
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include "rbtdb.h"
00067 #include "rbtdb64.h"
00068
00069 static ISC_LIST(dns_dbimplementation_t) implementations;
00070 static isc_rwlock_t implock;
00071 static isc_once_t once = ISC_ONCE_INIT;
00072
00073 static dns_dbimplementation_t rbtimp;
00074 static dns_dbimplementation_t rbt64imp;
00075
00076 static void
00077 initialize(void) {
00078 RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS);
00079
00080 rbtimp.name = "rbt";
00081 rbtimp.create = dns_rbtdb_create;
00082 rbtimp.mctx = NULL;
00083 rbtimp.driverarg = NULL;
00084 ISC_LINK_INIT(&rbtimp, link);
00085
00086 rbt64imp.name = "rbt64";
00087 rbt64imp.create = dns_rbtdb64_create;
00088 rbt64imp.mctx = NULL;
00089 rbt64imp.driverarg = NULL;
00090 ISC_LINK_INIT(&rbt64imp, link);
00091
00092 ISC_LIST_INIT(implementations);
00093 ISC_LIST_APPEND(implementations, &rbtimp, link);
00094 ISC_LIST_APPEND(implementations, &rbt64imp, link);
00095 }
00096
00097 static inline dns_dbimplementation_t *
00098 impfind(const char *name) {
00099 dns_dbimplementation_t *imp;
00100
00101 for (imp = ISC_LIST_HEAD(implementations);
00102 imp != NULL;
00103 imp = ISC_LIST_NEXT(imp, link))
00104 if (strcasecmp(name, imp->name) == 0)
00105 return (imp);
00106 return (NULL);
00107 }
00108
00109
00110
00111
00112
00113
00114 isc_result_t
00115 dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin,
00116 dns_dbtype_t type, dns_rdataclass_t rdclass,
00117 unsigned int argc, char *argv[], dns_db_t **dbp)
00118 {
00119 dns_dbimplementation_t *impinfo;
00120
00121 RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
00122
00123
00124
00125
00126
00127 REQUIRE(dbp != NULL && *dbp == NULL);
00128 REQUIRE(dns_name_isabsolute(origin));
00129
00130 RWLOCK(&implock, isc_rwlocktype_read);
00131 impinfo = impfind(db_type);
00132 if (impinfo != NULL) {
00133 isc_result_t result;
00134 result = ((impinfo->create)(mctx, origin, type,
00135 rdclass, argc, argv,
00136 impinfo->driverarg, dbp));
00137 RWUNLOCK(&implock, isc_rwlocktype_read);
00138 return (result);
00139 }
00140
00141 RWUNLOCK(&implock, isc_rwlocktype_read);
00142
00143 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
00144 DNS_LOGMODULE_DB, ISC_LOG_ERROR,
00145 "unsupported database type '%s'", db_type);
00146
00147 return (ISC_R_NOTFOUND);
00148 }
00149
00150 void
00151 dns_db_attach(dns_db_t *source, dns_db_t **targetp) {
00152
00153
00154
00155
00156
00157 REQUIRE(DNS_DB_VALID(source));
00158 REQUIRE(targetp != NULL && *targetp == NULL);
00159
00160 (source->methods->attach)(source, targetp);
00161
00162 ENSURE(*targetp == source);
00163 }
00164
00165 void
00166 dns_db_detach(dns_db_t **dbp) {
00167
00168
00169
00170
00171
00172 REQUIRE(dbp != NULL);
00173 REQUIRE(DNS_DB_VALID(*dbp));
00174
00175 ((*dbp)->methods->detach)(dbp);
00176
00177 ENSURE(*dbp == NULL);
00178 }
00179
00180 isc_result_t
00181 dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp)
00182 {
00183 REQUIRE(DNS_DB_VALID(db));
00184
00185 return (isc_ondestroy_register(&db->ondest, task, eventp));
00186 }
00187
00188
00189 isc_boolean_t
00190 dns_db_iscache(dns_db_t *db) {
00191
00192
00193
00194
00195
00196 REQUIRE(DNS_DB_VALID(db));
00197
00198 if ((db->attributes & DNS_DBATTR_CACHE) != 0)
00199 return (ISC_TRUE);
00200
00201 return (ISC_FALSE);
00202 }
00203
00204 isc_boolean_t
00205 dns_db_iszone(dns_db_t *db) {
00206
00207
00208
00209
00210
00211 REQUIRE(DNS_DB_VALID(db));
00212
00213 if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0)
00214 return (ISC_TRUE);
00215
00216 return (ISC_FALSE);
00217 }
00218
00219 isc_boolean_t
00220 dns_db_isstub(dns_db_t *db) {
00221
00222
00223
00224
00225
00226 REQUIRE(DNS_DB_VALID(db));
00227
00228 if ((db->attributes & DNS_DBATTR_STUB) != 0)
00229 return (ISC_TRUE);
00230
00231 return (ISC_FALSE);
00232 }
00233
00234 isc_boolean_t
00235 dns_db_isdnssec(dns_db_t *db) {
00236
00237
00238
00239
00240
00241 REQUIRE(DNS_DB_VALID(db));
00242 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00243
00244 if (db->methods->isdnssec != NULL)
00245 return ((db->methods->isdnssec)(db));
00246 return ((db->methods->issecure)(db));
00247 }
00248
00249 isc_boolean_t
00250 dns_db_issecure(dns_db_t *db) {
00251
00252
00253
00254
00255
00256 REQUIRE(DNS_DB_VALID(db));
00257 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00258
00259 return ((db->methods->issecure)(db));
00260 }
00261
00262 isc_boolean_t
00263 dns_db_ispersistent(dns_db_t *db) {
00264
00265
00266
00267
00268
00269 REQUIRE(DNS_DB_VALID(db));
00270
00271 return ((db->methods->ispersistent)(db));
00272 }
00273
00274 dns_name_t *
00275 dns_db_origin(dns_db_t *db) {
00276
00277
00278
00279
00280 REQUIRE(DNS_DB_VALID(db));
00281
00282 return (&db->origin);
00283 }
00284
00285 dns_rdataclass_t
00286 dns_db_class(dns_db_t *db) {
00287
00288
00289
00290
00291 REQUIRE(DNS_DB_VALID(db));
00292
00293 return (db->rdclass);
00294 }
00295
00296 isc_result_t
00297 dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00298
00299
00300
00301
00302 REQUIRE(DNS_DB_VALID(db));
00303 REQUIRE(DNS_CALLBACK_VALID(callbacks));
00304
00305 return ((db->methods->beginload)(db, callbacks));
00306 }
00307
00308 isc_result_t
00309 dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00310
00311
00312
00313
00314 REQUIRE(DNS_DB_VALID(db));
00315 REQUIRE(DNS_CALLBACK_VALID(callbacks));
00316 REQUIRE(callbacks->add_private != NULL);
00317
00318 return ((db->methods->endload)(db, callbacks));
00319 }
00320
00321 isc_result_t
00322 dns_db_load(dns_db_t *db, const char *filename) {
00323 return (dns_db_load3(db, filename, dns_masterformat_text, 0));
00324 }
00325
00326 isc_result_t
00327 dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) {
00328 return (dns_db_load3(db, filename, format, 0));
00329 }
00330
00331 isc_result_t
00332 dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
00333 unsigned int options) {
00334 isc_result_t result, eresult;
00335 dns_rdatacallbacks_t callbacks;
00336
00337
00338
00339
00340
00341 REQUIRE(DNS_DB_VALID(db));
00342
00343 if ((db->attributes & DNS_DBATTR_CACHE) != 0)
00344 options |= DNS_MASTER_AGETTL;
00345
00346 dns_rdatacallbacks_init(&callbacks);
00347 result = dns_db_beginload(db, &callbacks);
00348 if (result != ISC_R_SUCCESS)
00349 return (result);
00350 result = dns_master_loadfile2(filename, &db->origin, &db->origin,
00351 db->rdclass, options,
00352 &callbacks, db->mctx, format);
00353 eresult = dns_db_endload(db, &callbacks);
00354
00355
00356
00357
00358
00359 if (eresult != ISC_R_SUCCESS &&
00360 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
00361 result = eresult;
00362
00363 return (result);
00364 }
00365
00366 isc_result_t
00367 dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file) {
00368 REQUIRE(DNS_DB_VALID(db));
00369 if (db->methods->serialize == NULL)
00370 return (ISC_R_NOTIMPLEMENTED);
00371 return ((db->methods->serialize)(db, version, file));
00372 }
00373
00374 isc_result_t
00375 dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) {
00376 return ((db->methods->dump)(db, version, filename,
00377 dns_masterformat_text));
00378 }
00379
00380 isc_result_t
00381 dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
00382 dns_masterformat_t masterformat) {
00383
00384
00385
00386
00387
00388
00389 REQUIRE(DNS_DB_VALID(db));
00390
00391 return ((db->methods->dump)(db, version, filename, masterformat));
00392 }
00393
00394
00395
00396
00397
00398 void
00399 dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
00400
00401
00402
00403
00404
00405 REQUIRE(DNS_DB_VALID(db));
00406 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00407 REQUIRE(versionp != NULL && *versionp == NULL);
00408
00409 (db->methods->currentversion)(db, versionp);
00410 }
00411
00412 isc_result_t
00413 dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) {
00414
00415
00416
00417
00418
00419 REQUIRE(DNS_DB_VALID(db));
00420 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00421 REQUIRE(versionp != NULL && *versionp == NULL);
00422
00423 return ((db->methods->newversion)(db, versionp));
00424 }
00425
00426 void
00427 dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source,
00428 dns_dbversion_t **targetp)
00429 {
00430
00431
00432
00433
00434 REQUIRE(DNS_DB_VALID(db));
00435 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00436 REQUIRE(source != NULL);
00437 REQUIRE(targetp != NULL && *targetp == NULL);
00438
00439 (db->methods->attachversion)(db, source, targetp);
00440
00441 ENSURE(*targetp != NULL);
00442 }
00443
00444 void
00445 dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
00446 isc_boolean_t commit)
00447 {
00448
00449
00450
00451
00452
00453 REQUIRE(DNS_DB_VALID(db));
00454 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
00455 REQUIRE(versionp != NULL && *versionp != NULL);
00456
00457 (db->methods->closeversion)(db, versionp, commit);
00458
00459 ENSURE(*versionp == NULL);
00460 }
00461
00462
00463
00464
00465
00466 isc_result_t
00467 dns_db_findnode(dns_db_t *db, dns_name_t *name,
00468 isc_boolean_t create, dns_dbnode_t **nodep)
00469 {
00470
00471
00472
00473
00474
00475 REQUIRE(DNS_DB_VALID(db));
00476 REQUIRE(nodep != NULL && *nodep == NULL);
00477
00478 if (db->methods->findnode != NULL)
00479 return ((db->methods->findnode)(db, name, create, nodep));
00480 else
00481 return ((db->methods->findnodeext)(db, name, create,
00482 NULL, NULL, nodep));
00483 }
00484
00485 isc_result_t
00486 dns_db_findnodeext(dns_db_t *db, dns_name_t *name,
00487 isc_boolean_t create, dns_clientinfomethods_t *methods,
00488 dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
00489 {
00490
00491
00492
00493
00494
00495 REQUIRE(DNS_DB_VALID(db));
00496 REQUIRE(nodep != NULL && *nodep == NULL);
00497
00498 if (db->methods->findnodeext != NULL)
00499 return ((db->methods->findnodeext)(db, name, create,
00500 methods, clientinfo, nodep));
00501 else
00502 return ((db->methods->findnode)(db, name, create, nodep));
00503 }
00504
00505 isc_result_t
00506 dns_db_findnsec3node(dns_db_t *db, dns_name_t *name,
00507 isc_boolean_t create, dns_dbnode_t **nodep)
00508 {
00509
00510
00511
00512
00513
00514 REQUIRE(DNS_DB_VALID(db));
00515 REQUIRE(nodep != NULL && *nodep == NULL);
00516
00517 return ((db->methods->findnsec3node)(db, name, create, nodep));
00518 }
00519
00520 isc_result_t
00521 dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
00522 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
00523 dns_dbnode_t **nodep, dns_name_t *foundname,
00524 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00525 {
00526
00527
00528
00529
00530
00531 REQUIRE(DNS_DB_VALID(db));
00532 REQUIRE(type != dns_rdatatype_rrsig);
00533 REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
00534 REQUIRE(dns_name_hasbuffer(foundname));
00535 REQUIRE(rdataset == NULL ||
00536 (DNS_RDATASET_VALID(rdataset) &&
00537 ! dns_rdataset_isassociated(rdataset)));
00538 REQUIRE(sigrdataset == NULL ||
00539 (DNS_RDATASET_VALID(sigrdataset) &&
00540 ! dns_rdataset_isassociated(sigrdataset)));
00541
00542 if (db->methods->find != NULL)
00543 return ((db->methods->find)(db, name, version, type,
00544 options, now, nodep, foundname,
00545 rdataset, sigrdataset));
00546 else
00547 return ((db->methods->findext)(db, name, version, type,
00548 options, now, nodep, foundname,
00549 NULL, NULL,
00550 rdataset, sigrdataset));
00551 }
00552
00553 isc_result_t
00554 dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
00555 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
00556 dns_dbnode_t **nodep, dns_name_t *foundname,
00557 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
00558 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00559 {
00560
00561
00562
00563
00564
00565
00566 REQUIRE(DNS_DB_VALID(db));
00567 REQUIRE(type != dns_rdatatype_rrsig);
00568 REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
00569 REQUIRE(dns_name_hasbuffer(foundname));
00570 REQUIRE(rdataset == NULL ||
00571 (DNS_RDATASET_VALID(rdataset) &&
00572 ! dns_rdataset_isassociated(rdataset)));
00573 REQUIRE(sigrdataset == NULL ||
00574 (DNS_RDATASET_VALID(sigrdataset) &&
00575 ! dns_rdataset_isassociated(sigrdataset)));
00576
00577 if (db->methods->findext != NULL)
00578 return ((db->methods->findext)(db, name, version, type,
00579 options, now, nodep, foundname,
00580 methods, clientinfo,
00581 rdataset, sigrdataset));
00582 else
00583 return ((db->methods->find)(db, name, version, type,
00584 options, now, nodep, foundname,
00585 rdataset, sigrdataset));
00586 }
00587
00588 isc_result_t
00589 dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
00590 unsigned int options, isc_stdtime_t now,
00591 dns_dbnode_t **nodep, dns_name_t *foundname,
00592 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00593 {
00594
00595
00596
00597
00598 REQUIRE(DNS_DB_VALID(db));
00599 REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
00600 REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
00601 REQUIRE(dns_name_hasbuffer(foundname));
00602 REQUIRE(sigrdataset == NULL ||
00603 (DNS_RDATASET_VALID(sigrdataset) &&
00604 ! dns_rdataset_isassociated(sigrdataset)));
00605
00606 return ((db->methods->findzonecut)(db, name, options, now, nodep,
00607 foundname, rdataset, sigrdataset));
00608 }
00609
00610 void
00611 dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
00612
00613
00614
00615
00616
00617 REQUIRE(DNS_DB_VALID(db));
00618 REQUIRE(source != NULL);
00619 REQUIRE(targetp != NULL && *targetp == NULL);
00620
00621 (db->methods->attachnode)(db, source, targetp);
00622 }
00623
00624 void
00625 dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
00626
00627
00628
00629
00630
00631 REQUIRE(DNS_DB_VALID(db));
00632 REQUIRE(nodep != NULL && *nodep != NULL);
00633
00634 (db->methods->detachnode)(db, nodep);
00635
00636 ENSURE(*nodep == NULL);
00637 }
00638
00639 void
00640 dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
00641 dns_dbnode_t **targetp)
00642 {
00643 REQUIRE(DNS_DB_VALID(db));
00644 REQUIRE(targetp != NULL && *targetp == NULL);
00645
00646
00647
00648
00649
00650 REQUIRE(sourcep != NULL && *sourcep != NULL);
00651
00652 UNUSED(db);
00653
00654 if (db->methods->transfernode == NULL) {
00655 *targetp = *sourcep;
00656 *sourcep = NULL;
00657 } else
00658 (db->methods->transfernode)(db, sourcep, targetp);
00659
00660 ENSURE(*sourcep == NULL);
00661 }
00662
00663 isc_result_t
00664 dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
00665
00666
00667
00668
00669
00670 REQUIRE(DNS_DB_VALID(db));
00671 REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
00672 REQUIRE(node != NULL);
00673
00674 return ((db->methods->expirenode)(db, node, now));
00675 }
00676
00677 void
00678 dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
00679
00680
00681
00682
00683
00684 REQUIRE(DNS_DB_VALID(db));
00685 REQUIRE(node != NULL);
00686
00687 (db->methods->printnode)(db, node, out);
00688 }
00689
00690
00691
00692
00693
00694 isc_result_t
00695 dns_db_createiterator(dns_db_t *db, unsigned int flags,
00696 dns_dbiterator_t **iteratorp)
00697 {
00698
00699
00700
00701
00702 REQUIRE(DNS_DB_VALID(db));
00703 REQUIRE(iteratorp != NULL && *iteratorp == NULL);
00704
00705 return (db->methods->createiterator(db, flags, iteratorp));
00706 }
00707
00708
00709
00710
00711
00712 isc_result_t
00713 dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00714 dns_rdatatype_t type, dns_rdatatype_t covers,
00715 isc_stdtime_t now, dns_rdataset_t *rdataset,
00716 dns_rdataset_t *sigrdataset)
00717 {
00718 REQUIRE(DNS_DB_VALID(db));
00719 REQUIRE(node != NULL);
00720 REQUIRE(DNS_RDATASET_VALID(rdataset));
00721 REQUIRE(! dns_rdataset_isassociated(rdataset));
00722 REQUIRE(covers == 0 || type == dns_rdatatype_rrsig);
00723 REQUIRE(type != dns_rdatatype_any);
00724 REQUIRE(sigrdataset == NULL ||
00725 (DNS_RDATASET_VALID(sigrdataset) &&
00726 ! dns_rdataset_isassociated(sigrdataset)));
00727
00728 return ((db->methods->findrdataset)(db, node, version, type,
00729 covers, now, rdataset,
00730 sigrdataset));
00731 }
00732
00733 isc_result_t
00734 dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00735 isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
00736 {
00737
00738
00739
00740
00741
00742 REQUIRE(DNS_DB_VALID(db));
00743 REQUIRE(iteratorp != NULL && *iteratorp == NULL);
00744
00745 return ((db->methods->allrdatasets)(db, node, version, now,
00746 iteratorp));
00747 }
00748
00749 isc_result_t
00750 dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00751 isc_stdtime_t now, dns_rdataset_t *rdataset,
00752 unsigned int options, dns_rdataset_t *addedrdataset)
00753 {
00754
00755
00756
00757
00758 REQUIRE(DNS_DB_VALID(db));
00759 REQUIRE(node != NULL);
00760 REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
00761 ((db->attributes & DNS_DBATTR_CACHE) != 0 &&
00762 version == NULL && (options & DNS_DBADD_MERGE) == 0));
00763 REQUIRE((options & DNS_DBADD_EXACT) == 0 ||
00764 (options & DNS_DBADD_MERGE) != 0);
00765 REQUIRE(DNS_RDATASET_VALID(rdataset));
00766 REQUIRE(dns_rdataset_isassociated(rdataset));
00767 REQUIRE(rdataset->rdclass == db->rdclass);
00768 REQUIRE(addedrdataset == NULL ||
00769 (DNS_RDATASET_VALID(addedrdataset) &&
00770 ! dns_rdataset_isassociated(addedrdataset)));
00771
00772 return ((db->methods->addrdataset)(db, node, version, now, rdataset,
00773 options, addedrdataset));
00774 }
00775
00776 isc_result_t
00777 dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
00778 dns_dbversion_t *version, dns_rdataset_t *rdataset,
00779 unsigned int options, dns_rdataset_t *newrdataset)
00780 {
00781
00782
00783
00784
00785
00786 REQUIRE(DNS_DB_VALID(db));
00787 REQUIRE(node != NULL);
00788 REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL);
00789 REQUIRE(DNS_RDATASET_VALID(rdataset));
00790 REQUIRE(dns_rdataset_isassociated(rdataset));
00791 REQUIRE(rdataset->rdclass == db->rdclass);
00792 REQUIRE(newrdataset == NULL ||
00793 (DNS_RDATASET_VALID(newrdataset) &&
00794 ! dns_rdataset_isassociated(newrdataset)));
00795
00796 return ((db->methods->subtractrdataset)(db, node, version, rdataset,
00797 options, newrdataset));
00798 }
00799
00800 isc_result_t
00801 dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
00802 dns_dbversion_t *version, dns_rdatatype_t type,
00803 dns_rdatatype_t covers)
00804 {
00805
00806
00807
00808
00809
00810 REQUIRE(DNS_DB_VALID(db));
00811 REQUIRE(node != NULL);
00812 REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
00813 ((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL));
00814
00815 return ((db->methods->deleterdataset)(db, node, version,
00816 type, covers));
00817 }
00818
00819 void
00820 dns_db_overmem(dns_db_t *db, isc_boolean_t overmem) {
00821
00822 REQUIRE(DNS_DB_VALID(db));
00823
00824 (db->methods->overmem)(db, overmem);
00825 }
00826
00827 isc_result_t
00828 dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
00829 {
00830 isc_result_t result;
00831 dns_dbnode_t *node = NULL;
00832 dns_rdataset_t rdataset;
00833 dns_rdata_t rdata = DNS_RDATA_INIT;
00834 isc_buffer_t buffer;
00835
00836 REQUIRE(dns_db_iszone(db) || dns_db_isstub(db));
00837
00838 result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
00839 if (result != ISC_R_SUCCESS)
00840 return (result);
00841
00842 dns_rdataset_init(&rdataset);
00843 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
00844 (isc_stdtime_t)0, &rdataset, NULL);
00845 if (result != ISC_R_SUCCESS)
00846 goto freenode;
00847
00848 result = dns_rdataset_first(&rdataset);
00849 if (result != ISC_R_SUCCESS)
00850 goto freerdataset;
00851 dns_rdataset_current(&rdataset, &rdata);
00852 result = dns_rdataset_next(&rdataset);
00853 INSIST(result == ISC_R_NOMORE);
00854
00855 INSIST(rdata.length > 20);
00856 isc_buffer_init(&buffer, rdata.data, rdata.length);
00857 isc_buffer_add(&buffer, rdata.length);
00858 isc_buffer_forward(&buffer, rdata.length - 20);
00859 *serialp = isc_buffer_getuint32(&buffer);
00860
00861 result = ISC_R_SUCCESS;
00862
00863 freerdataset:
00864 dns_rdataset_disassociate(&rdataset);
00865
00866 freenode:
00867 dns_db_detachnode(db, &node);
00868 return (result);
00869 }
00870
00871 unsigned int
00872 dns_db_nodecount(dns_db_t *db) {
00873 REQUIRE(DNS_DB_VALID(db));
00874
00875 return ((db->methods->nodecount)(db));
00876 }
00877
00878 unsigned int
00879 dns_db_hashsize(dns_db_t *db) {
00880 REQUIRE(DNS_DB_VALID(db));
00881
00882 if (db->methods->hashsize == NULL)
00883 return (ISC_R_NOTIMPLEMENTED);
00884
00885 return ((db->methods->hashsize)(db));
00886 }
00887
00888 void
00889 dns_db_settask(dns_db_t *db, isc_task_t *task) {
00890 REQUIRE(DNS_DB_VALID(db));
00891
00892 (db->methods->settask)(db, task);
00893 }
00894
00895 isc_result_t
00896 dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
00897 isc_mem_t *mctx, dns_dbimplementation_t **dbimp)
00898 {
00899 dns_dbimplementation_t *imp;
00900
00901 REQUIRE(name != NULL);
00902 REQUIRE(dbimp != NULL && *dbimp == NULL);
00903
00904 RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
00905
00906 RWLOCK(&implock, isc_rwlocktype_write);
00907 imp = impfind(name);
00908 if (imp != NULL) {
00909 RWUNLOCK(&implock, isc_rwlocktype_write);
00910 return (ISC_R_EXISTS);
00911 }
00912
00913 imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t));
00914 if (imp == NULL) {
00915 RWUNLOCK(&implock, isc_rwlocktype_write);
00916 return (ISC_R_NOMEMORY);
00917 }
00918 imp->name = name;
00919 imp->create = create;
00920 imp->mctx = NULL;
00921 imp->driverarg = driverarg;
00922 isc_mem_attach(mctx, &imp->mctx);
00923 ISC_LINK_INIT(imp, link);
00924 ISC_LIST_APPEND(implementations, imp, link);
00925 RWUNLOCK(&implock, isc_rwlocktype_write);
00926
00927 *dbimp = imp;
00928
00929 return (ISC_R_SUCCESS);
00930 }
00931
00932 void
00933 dns_db_unregister(dns_dbimplementation_t **dbimp) {
00934 dns_dbimplementation_t *imp;
00935 isc_mem_t *mctx;
00936
00937 REQUIRE(dbimp != NULL && *dbimp != NULL);
00938
00939 RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
00940
00941 imp = *dbimp;
00942 *dbimp = NULL;
00943 RWLOCK(&implock, isc_rwlocktype_write);
00944 ISC_LIST_UNLINK(implementations, imp, link);
00945 mctx = imp->mctx;
00946 isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t));
00947 isc_mem_detach(&mctx);
00948 RWUNLOCK(&implock, isc_rwlocktype_write);
00949 ENSURE(*dbimp == NULL);
00950 }
00951
00952 isc_result_t
00953 dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
00954 REQUIRE(DNS_DB_VALID(db));
00955 REQUIRE(dns_db_iszone(db) == ISC_TRUE);
00956 REQUIRE(nodep != NULL && *nodep == NULL);
00957
00958 if (db->methods->getoriginnode != NULL)
00959 return ((db->methods->getoriginnode)(db, nodep));
00960
00961 return (ISC_R_NOTFOUND);
00962 }
00963
00964 dns_stats_t *
00965 dns_db_getrrsetstats(dns_db_t *db) {
00966 REQUIRE(DNS_DB_VALID(db));
00967
00968 if (db->methods->getrrsetstats != NULL)
00969 return ((db->methods->getrrsetstats)(db));
00970
00971 return (NULL);
00972 }
00973
00974 isc_result_t
00975 dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats) {
00976 REQUIRE(DNS_DB_VALID(db));
00977
00978 if (db->methods->setcachestats != NULL)
00979 return ((db->methods->setcachestats)(db, stats));
00980
00981 return (ISC_R_NOTIMPLEMENTED);
00982 }
00983
00984 isc_result_t
00985 dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
00986 dns_hash_t *hash, isc_uint8_t *flags,
00987 isc_uint16_t *iterations,
00988 unsigned char *salt, size_t *salt_length)
00989 {
00990 REQUIRE(DNS_DB_VALID(db));
00991 REQUIRE(dns_db_iszone(db) == ISC_TRUE);
00992
00993 if (db->methods->getnsec3parameters != NULL)
00994 return ((db->methods->getnsec3parameters)(db, version, hash,
00995 flags, iterations,
00996 salt, salt_length));
00997
00998 return (ISC_R_NOTFOUND);
00999 }
01000
01001 isc_result_t
01002 dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
01003 isc_stdtime_t resign)
01004 {
01005 if (db->methods->setsigningtime != NULL)
01006 return ((db->methods->setsigningtime)(db, rdataset, resign));
01007 return (ISC_R_NOTIMPLEMENTED);
01008 }
01009
01010 isc_result_t
01011 dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name)
01012 {
01013 if (db->methods->getsigningtime != NULL)
01014 return ((db->methods->getsigningtime)(db, rdataset, name));
01015 return (ISC_R_NOTFOUND);
01016 }
01017
01018 void
01019 dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
01020 dns_dbversion_t *version)
01021 {
01022 if (db->methods->resigned != NULL)
01023 (db->methods->resigned)(db, rdataset, version);
01024 }
01025
01026
01027
01028
01029
01030
01031 void
01032 dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
01033 REQUIRE(db->methods->rpz_attach != NULL);
01034 (db->methods->rpz_attach)(db, rpzs, rpz_num);
01035 }
01036
01037
01038
01039
01040 isc_result_t
01041 dns_db_rpz_ready(dns_db_t *db) {
01042 if (db->methods->rpz_ready == NULL)
01043 return (ISC_R_SUCCESS);
01044 return ((db->methods->rpz_ready)(db));
01045 }