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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <config.h>
00058 #include <string.h>
00059
00060 #include <isc/buffer.h>
00061 #include <isc/lex.h>
00062 #include <isc/log.h>
00063 #include <isc/rwlock.h>
00064 #include <isc/string.h>
00065 #include <isc/util.h>
00066 #include <isc/magic.h>
00067 #include <isc/mem.h>
00068 #include <isc/once.h>
00069 #include <isc/print.h>
00070 #include <isc/region.h>
00071
00072 #include <dns/callbacks.h>
00073 #include <dns/db.h>
00074 #include <dns/dbiterator.h>
00075 #include <dns/dlz.h>
00076 #include <dns/fixedname.h>
00077 #include <dns/log.h>
00078 #include <dns/rdata.h>
00079 #include <dns/rdatalist.h>
00080 #include <dns/rdataset.h>
00081 #include <dns/rdatasetiter.h>
00082 #include <dns/rdatatype.h>
00083 #include <dns/result.h>
00084 #include <dns/master.h>
00085 #include <dns/sdlz.h>
00086 #include <dns/types.h>
00087
00088 #include "rdatalist_p.h"
00089
00090
00091
00092
00093
00094 struct dns_sdlzimplementation {
00095 const dns_sdlzmethods_t *methods;
00096 isc_mem_t *mctx;
00097 void *driverarg;
00098 unsigned int flags;
00099 isc_mutex_t driverlock;
00100 dns_dlzimplementation_t *dlz_imp;
00101 };
00102
00103 struct dns_sdlz_db {
00104
00105 dns_db_t common;
00106 void *dbdata;
00107 dns_sdlzimplementation_t *dlzimp;
00108 isc_mutex_t refcnt_lock;
00109
00110 unsigned int references;
00111 dns_dbversion_t *future_version;
00112 int dummy_version;
00113 };
00114
00115 struct dns_sdlzlookup {
00116
00117 unsigned int magic;
00118 dns_sdlz_db_t *sdlz;
00119 ISC_LIST(dns_rdatalist_t) lists;
00120 ISC_LIST(isc_buffer_t) buffers;
00121 dns_name_t *name;
00122 ISC_LINK(dns_sdlzlookup_t) link;
00123 isc_mutex_t lock;
00124 dns_rdatacallbacks_t callbacks;
00125
00126 unsigned int references;
00127 };
00128
00129 typedef struct dns_sdlzlookup dns_sdlznode_t;
00130
00131 struct dns_sdlzallnodes {
00132 dns_dbiterator_t common;
00133 ISC_LIST(dns_sdlznode_t) nodelist;
00134 dns_sdlznode_t *current;
00135 dns_sdlznode_t *origin;
00136 };
00137
00138 typedef dns_sdlzallnodes_t sdlz_dbiterator_t;
00139
00140 typedef struct sdlz_rdatasetiter {
00141 dns_rdatasetiter_t common;
00142 dns_rdatalist_t *current;
00143 } sdlz_rdatasetiter_t;
00144
00145
00146 #define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S')
00147
00148
00149
00150
00151
00152
00153 #define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \
00154 (sdlzdb)->common.impmagic == SDLZDB_MAGIC)
00155
00156 #define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L')
00157 #define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)
00158 #define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn)
00159
00160
00161 #define SDLZ_DEFAULT_REFRESH (60 * 60 * 8)
00162 #define SDLZ_DEFAULT_RETRY (60 * 60 * 2)
00163 #define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
00164 #define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24)
00165
00166
00167 #define SDLZ_DEFAULT_TTL (60 * 60 * 24)
00168
00169 #ifdef __COVERITY__
00170 #define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
00171 #define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
00172 #else
00173 #define MAYBE_LOCK(imp) \
00174 do { \
00175 unsigned int flags = imp->flags; \
00176 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
00177 LOCK(&imp->driverlock); \
00178 } while (0)
00179
00180 #define MAYBE_UNLOCK(imp) \
00181 do { \
00182 unsigned int flags = imp->flags; \
00183 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
00184 UNLOCK(&imp->driverlock); \
00185 } while (0)
00186 #endif
00187
00188
00189
00190
00191 static isc_result_t getnodedata(dns_db_t *db, dns_name_t *name,
00192 isc_boolean_t create, unsigned int options,
00193 dns_clientinfomethods_t *methods,
00194 dns_clientinfo_t *clientinfo,
00195 dns_dbnode_t **nodep);
00196
00197 static void list_tordataset(dns_rdatalist_t *rdatalist,
00198 dns_db_t *db, dns_dbnode_t *node,
00199 dns_rdataset_t *rdataset);
00200
00201 static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
00202
00203 static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
00204 static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
00205 static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
00206 static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
00207 dns_name_t *name);
00208 static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
00209 static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
00210 static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
00211 dns_dbnode_t **nodep,
00212 dns_name_t *name);
00213 static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
00214 static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
00215 dns_name_t *name);
00216
00217 static dns_dbiteratormethods_t dbiterator_methods = {
00218 dbiterator_destroy,
00219 dbiterator_first,
00220 dbiterator_last,
00221 dbiterator_seek,
00222 dbiterator_prev,
00223 dbiterator_next,
00224 dbiterator_current,
00225 dbiterator_pause,
00226 dbiterator_origin
00227 };
00228
00229
00230
00231
00232
00233
00234
00235
00236 static void
00237 sdlz_log(int level, const char *fmt, ...) {
00238 va_list ap;
00239 va_start(ap, fmt);
00240 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
00241 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
00242 fmt, ap);
00243 va_end(ap);
00244 }
00245
00246
00247 static void
00248 dns_sdlz_tolower(char *str) {
00249 unsigned int len = strlen(str);
00250 unsigned int i;
00251
00252 for (i = 0; i < len; i++) {
00253 if (str[i] >= 'A' && str[i] <= 'Z')
00254 str[i] += 32;
00255 }
00256 }
00257
00258 static inline unsigned int
00259 initial_size(const char *data) {
00260 unsigned int len = (strlen(data) / 64) + 1;
00261 return (len * 64 + 64);
00262 }
00263
00264
00265
00266
00267
00268
00269 static void
00270 rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
00271 sdlz_rdatasetiter_t *sdlziterator =
00272 (sdlz_rdatasetiter_t *)(*iteratorp);
00273
00274 detachnode(sdlziterator->common.db, &sdlziterator->common.node);
00275 isc_mem_put(sdlziterator->common.db->mctx, sdlziterator,
00276 sizeof(sdlz_rdatasetiter_t));
00277 *iteratorp = NULL;
00278 }
00279
00280 static isc_result_t
00281 rdatasetiter_first(dns_rdatasetiter_t *iterator) {
00282 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
00283 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node;
00284
00285 if (ISC_LIST_EMPTY(sdlznode->lists))
00286 return (ISC_R_NOMORE);
00287 sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists);
00288 return (ISC_R_SUCCESS);
00289 }
00290
00291 static isc_result_t
00292 rdatasetiter_next(dns_rdatasetiter_t *iterator) {
00293 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
00294
00295 sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link);
00296 if (sdlziterator->current == NULL)
00297 return (ISC_R_NOMORE);
00298 else
00299 return (ISC_R_SUCCESS);
00300 }
00301
00302 static void
00303 rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
00304 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
00305
00306 list_tordataset(sdlziterator->current, iterator->db, iterator->node,
00307 rdataset);
00308 }
00309
00310 static dns_rdatasetitermethods_t rdatasetiter_methods = {
00311 rdatasetiter_destroy,
00312 rdatasetiter_first,
00313 rdatasetiter_next,
00314 rdatasetiter_current
00315 };
00316
00317
00318
00319
00320
00321
00322 static void
00323 attach(dns_db_t *source, dns_db_t **targetp) {
00324 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source;
00325
00326 REQUIRE(VALID_SDLZDB(sdlz));
00327
00328 LOCK(&sdlz->refcnt_lock);
00329 REQUIRE(sdlz->references > 0);
00330 sdlz->references++;
00331 UNLOCK(&sdlz->refcnt_lock);
00332
00333 *targetp = source;
00334 }
00335
00336 static void
00337 destroy(dns_sdlz_db_t *sdlz) {
00338 isc_mem_t *mctx;
00339 mctx = sdlz->common.mctx;
00340
00341 sdlz->common.magic = 0;
00342 sdlz->common.impmagic = 0;
00343
00344 (void)isc_mutex_destroy(&sdlz->refcnt_lock);
00345
00346 dns_name_free(&sdlz->common.origin, mctx);
00347
00348 isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
00349 isc_mem_detach(&mctx);
00350 }
00351
00352 static void
00353 detach(dns_db_t **dbp) {
00354 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
00355 isc_boolean_t need_destroy = ISC_FALSE;
00356
00357 REQUIRE(VALID_SDLZDB(sdlz));
00358 LOCK(&sdlz->refcnt_lock);
00359 REQUIRE(sdlz->references > 0);
00360 sdlz->references--;
00361 if (sdlz->references == 0)
00362 need_destroy = ISC_TRUE;
00363 UNLOCK(&sdlz->refcnt_lock);
00364
00365 if (need_destroy)
00366 destroy(sdlz);
00367
00368 *dbp = NULL;
00369 }
00370
00371 static isc_result_t
00372 beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00373 UNUSED(db);
00374 UNUSED(callbacks);
00375 return (ISC_R_NOTIMPLEMENTED);
00376 }
00377
00378 static isc_result_t
00379 endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
00380 UNUSED(db);
00381 UNUSED(callbacks);
00382 return (ISC_R_NOTIMPLEMENTED);
00383 }
00384
00385 static isc_result_t
00386 dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
00387 dns_masterformat_t masterformat)
00388 {
00389 UNUSED(db);
00390 UNUSED(version);
00391 UNUSED(filename);
00392 UNUSED(masterformat);
00393 return (ISC_R_NOTIMPLEMENTED);
00394 }
00395
00396 static void
00397 currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
00398 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00399 REQUIRE(VALID_SDLZDB(sdlz));
00400 REQUIRE(versionp != NULL && *versionp == NULL);
00401
00402 *versionp = (void *) &sdlz->dummy_version;
00403 return;
00404 }
00405
00406 static isc_result_t
00407 newversion(dns_db_t *db, dns_dbversion_t **versionp) {
00408 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00409 char origin[DNS_NAME_MAXTEXT + 1];
00410 isc_result_t result;
00411
00412 REQUIRE(VALID_SDLZDB(sdlz));
00413
00414 if (sdlz->dlzimp->methods->newversion == NULL)
00415 return (ISC_R_NOTIMPLEMENTED);
00416
00417 dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
00418
00419 result = sdlz->dlzimp->methods->newversion(origin,
00420 sdlz->dlzimp->driverarg,
00421 sdlz->dbdata, versionp);
00422 if (result != ISC_R_SUCCESS) {
00423 sdlz_log(ISC_LOG_ERROR,
00424 "sdlz newversion on origin %s failed : %s",
00425 origin, isc_result_totext(result));
00426 return (result);
00427 }
00428
00429 sdlz->future_version = *versionp;
00430 return (ISC_R_SUCCESS);
00431 }
00432
00433 static void
00434 attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp)
00435 {
00436 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00437
00438 REQUIRE(VALID_SDLZDB(sdlz));
00439 REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version);
00440
00441 *targetp = source;
00442 }
00443
00444 static void
00445 closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
00446 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00447 char origin[DNS_NAME_MAXTEXT + 1];
00448
00449 REQUIRE(VALID_SDLZDB(sdlz));
00450 REQUIRE(versionp != NULL);
00451
00452 if (*versionp == (void *)&sdlz->dummy_version) {
00453 *versionp = NULL;
00454 return;
00455 }
00456
00457 REQUIRE(*versionp == sdlz->future_version);
00458 REQUIRE(sdlz->dlzimp->methods->closeversion != NULL);
00459
00460 dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
00461
00462 sdlz->dlzimp->methods->closeversion(origin, commit,
00463 sdlz->dlzimp->driverarg,
00464 sdlz->dbdata, versionp);
00465 if (*versionp != NULL)
00466 sdlz_log(ISC_LOG_ERROR,
00467 "sdlz closeversion on origin %s failed", origin);
00468
00469 sdlz->future_version = NULL;
00470 }
00471
00472 static isc_result_t
00473 createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {
00474 dns_sdlznode_t *node;
00475 isc_result_t result;
00476
00477 node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));
00478 if (node == NULL)
00479 return (ISC_R_NOMEMORY);
00480
00481 node->sdlz = NULL;
00482 attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz);
00483 ISC_LIST_INIT(node->lists);
00484 ISC_LIST_INIT(node->buffers);
00485 ISC_LINK_INIT(node, link);
00486 node->name = NULL;
00487 result = isc_mutex_init(&node->lock);
00488 if (result != ISC_R_SUCCESS) {
00489 UNEXPECTED_ERROR(__FILE__, __LINE__,
00490 "isc_mutex_init() failed: %s",
00491 isc_result_totext(result));
00492 isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t));
00493 return (ISC_R_UNEXPECTED);
00494 }
00495 dns_rdatacallbacks_init(&node->callbacks);
00496 node->references = 1;
00497 node->magic = SDLZLOOKUP_MAGIC;
00498
00499 *nodep = node;
00500 return (ISC_R_SUCCESS);
00501 }
00502
00503 static void
00504 destroynode(dns_sdlznode_t *node) {
00505 dns_rdatalist_t *list;
00506 dns_rdata_t *rdata;
00507 isc_buffer_t *b;
00508 dns_sdlz_db_t *sdlz;
00509 dns_db_t *db;
00510 isc_mem_t *mctx;
00511
00512 sdlz = node->sdlz;
00513 mctx = sdlz->common.mctx;
00514
00515 while (!ISC_LIST_EMPTY(node->lists)) {
00516 list = ISC_LIST_HEAD(node->lists);
00517 while (!ISC_LIST_EMPTY(list->rdata)) {
00518 rdata = ISC_LIST_HEAD(list->rdata);
00519 ISC_LIST_UNLINK(list->rdata, rdata, link);
00520 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
00521 }
00522 ISC_LIST_UNLINK(node->lists, list, link);
00523 isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
00524 }
00525
00526 while (!ISC_LIST_EMPTY(node->buffers)) {
00527 b = ISC_LIST_HEAD(node->buffers);
00528 ISC_LIST_UNLINK(node->buffers, b, link);
00529 isc_buffer_free(&b);
00530 }
00531
00532 if (node->name != NULL) {
00533 dns_name_free(node->name, mctx);
00534 isc_mem_put(mctx, node->name, sizeof(dns_name_t));
00535 }
00536 DESTROYLOCK(&node->lock);
00537 node->magic = 0;
00538 isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
00539 db = &sdlz->common;
00540 detach(&db);
00541 }
00542
00543 static isc_result_t
00544 getnodedata(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
00545 unsigned int options, dns_clientinfomethods_t *methods,
00546 dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
00547 {
00548 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00549 dns_sdlznode_t *node = NULL;
00550 isc_result_t result;
00551 isc_buffer_t b;
00552 char namestr[DNS_NAME_MAXTEXT + 1];
00553 isc_buffer_t b2;
00554 char zonestr[DNS_NAME_MAXTEXT + 1];
00555 isc_boolean_t isorigin;
00556 dns_sdlzauthorityfunc_t authority;
00557
00558 REQUIRE(VALID_SDLZDB(sdlz));
00559 REQUIRE(nodep != NULL && *nodep == NULL);
00560
00561 if (sdlz->dlzimp->methods->newversion == NULL) {
00562 REQUIRE(create == ISC_FALSE);
00563 }
00564
00565 isc_buffer_init(&b, namestr, sizeof(namestr));
00566 if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) {
00567 dns_name_t relname;
00568 unsigned int labels;
00569
00570 labels = dns_name_countlabels(name) -
00571 dns_name_countlabels(&sdlz->common.origin);
00572 dns_name_init(&relname, NULL);
00573 dns_name_getlabelsequence(name, 0, labels, &relname);
00574 result = dns_name_totext(&relname, ISC_TRUE, &b);
00575 if (result != ISC_R_SUCCESS)
00576 return (result);
00577 } else {
00578 result = dns_name_totext(name, ISC_TRUE, &b);
00579 if (result != ISC_R_SUCCESS)
00580 return (result);
00581 }
00582 isc_buffer_putuint8(&b, 0);
00583
00584 isc_buffer_init(&b2, zonestr, sizeof(zonestr));
00585 result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2);
00586 if (result != ISC_R_SUCCESS)
00587 return (result);
00588 isc_buffer_putuint8(&b2, 0);
00589
00590 result = createnode(sdlz, &node);
00591 if (result != ISC_R_SUCCESS)
00592 return (result);
00593
00594 isorigin = dns_name_equal(name, &sdlz->common.origin);
00595
00596
00597 dns_sdlz_tolower(zonestr);
00598 dns_sdlz_tolower(namestr);
00599
00600 MAYBE_LOCK(sdlz->dlzimp);
00601
00602
00603 result = sdlz->dlzimp->methods->lookup(zonestr, namestr,
00604 sdlz->dlzimp->driverarg,
00605 sdlz->dbdata, node,
00606 methods, clientinfo);
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 if (result == ISC_R_NOTFOUND && !create &&
00617 (options & DNS_DBFIND_NOWILD) == 0)
00618 {
00619 unsigned int i, dlabels, nlabels;
00620
00621 nlabels = dns_name_countlabels(name);
00622 dlabels = nlabels - dns_name_countlabels(&sdlz->common.origin);
00623 for (i = 0; i < dlabels; i++) {
00624 char wildstr[DNS_NAME_MAXTEXT + 1];
00625 dns_fixedname_t fixed;
00626 dns_name_t *wild;
00627
00628 dns_fixedname_init(&fixed);
00629 if (i == dlabels)
00630 wild = dns_wildcardname;
00631 else {
00632 wild = dns_fixedname_name(&fixed);
00633 dns_name_getlabelsequence(name, i + 1,
00634 dlabels - i - 1,
00635 wild);
00636 result = dns_name_concatenate(dns_wildcardname,
00637 wild, wild, NULL);
00638 if (result != ISC_R_SUCCESS)
00639 return (result);
00640 }
00641
00642 isc_buffer_init(&b, wildstr, sizeof(wildstr));
00643 result = dns_name_totext(wild, ISC_TRUE, &b);
00644 if (result != ISC_R_SUCCESS)
00645 return (result);
00646 isc_buffer_putuint8(&b, 0);
00647
00648 result = sdlz->dlzimp->methods->lookup(zonestr, wildstr,
00649 sdlz->dlzimp->driverarg,
00650 sdlz->dbdata, node,
00651 methods, clientinfo);
00652 if (result == ISC_R_SUCCESS)
00653 break;
00654 }
00655 }
00656
00657 MAYBE_UNLOCK(sdlz->dlzimp);
00658
00659 if (result == ISC_R_NOTFOUND && (isorigin || create))
00660 result = ISC_R_SUCCESS;
00661
00662 if (result != ISC_R_SUCCESS) {
00663 destroynode(node);
00664 return (result);
00665 }
00666
00667 if (isorigin && sdlz->dlzimp->methods->authority != NULL) {
00668 MAYBE_LOCK(sdlz->dlzimp);
00669 authority = sdlz->dlzimp->methods->authority;
00670 result = (*authority)(zonestr, sdlz->dlzimp->driverarg,
00671 sdlz->dbdata, node);
00672 MAYBE_UNLOCK(sdlz->dlzimp);
00673 if (result != ISC_R_SUCCESS &&
00674 result != ISC_R_NOTIMPLEMENTED)
00675 {
00676 destroynode(node);
00677 return (result);
00678 }
00679 }
00680
00681 if (node->name == NULL) {
00682 node->name = isc_mem_get(sdlz->common.mctx,
00683 sizeof(dns_name_t));
00684 if (node->name == NULL) {
00685 destroynode(node);
00686 return (ISC_R_NOMEMORY);
00687 }
00688 dns_name_init(node->name, NULL);
00689 result = dns_name_dup(name, sdlz->common.mctx, node->name);
00690 if (result != ISC_R_SUCCESS) {
00691 isc_mem_put(sdlz->common.mctx, node->name,
00692 sizeof(dns_name_t));
00693 destroynode(node);
00694 return (result);
00695 }
00696 }
00697
00698 *nodep = node;
00699 return (ISC_R_SUCCESS);
00700 }
00701
00702 static isc_result_t
00703 findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
00704 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
00705 dns_dbnode_t **nodep)
00706 {
00707 return (getnodedata(db, name, create, 0, methods, clientinfo, nodep));
00708 }
00709
00710 static isc_result_t
00711 findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
00712 dns_dbnode_t **nodep)
00713 {
00714 return (getnodedata(db, name, create, 0, NULL, NULL, nodep));
00715 }
00716
00717 static isc_result_t
00718 findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
00719 isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
00720 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00721 {
00722 UNUSED(db);
00723 UNUSED(name);
00724 UNUSED(options);
00725 UNUSED(now);
00726 UNUSED(nodep);
00727 UNUSED(foundname);
00728 UNUSED(rdataset);
00729 UNUSED(sigrdataset);
00730
00731 return (ISC_R_NOTIMPLEMENTED);
00732 }
00733
00734 static void
00735 attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
00736 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00737 dns_sdlznode_t *node = (dns_sdlznode_t *)source;
00738
00739 REQUIRE(VALID_SDLZDB(sdlz));
00740
00741 UNUSED(sdlz);
00742
00743 LOCK(&node->lock);
00744 INSIST(node->references > 0);
00745 node->references++;
00746 INSIST(node->references != 0);
00747 UNLOCK(&node->lock);
00748
00749 *targetp = source;
00750 }
00751
00752 static void
00753 detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
00754 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00755 dns_sdlznode_t *node;
00756 isc_boolean_t need_destroy = ISC_FALSE;
00757
00758 REQUIRE(VALID_SDLZDB(sdlz));
00759 REQUIRE(targetp != NULL && *targetp != NULL);
00760
00761 UNUSED(sdlz);
00762
00763 node = (dns_sdlznode_t *)(*targetp);
00764
00765 LOCK(&node->lock);
00766 INSIST(node->references > 0);
00767 node->references--;
00768 if (node->references == 0)
00769 need_destroy = ISC_TRUE;
00770 UNLOCK(&node->lock);
00771
00772 if (need_destroy)
00773 destroynode(node);
00774
00775 *targetp = NULL;
00776 }
00777
00778 static isc_result_t
00779 expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
00780 UNUSED(db);
00781 UNUSED(node);
00782 UNUSED(now);
00783 INSIST(0);
00784 return (ISC_R_UNEXPECTED);
00785 }
00786
00787 static void
00788 printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
00789 UNUSED(db);
00790 UNUSED(node);
00791 UNUSED(out);
00792 return;
00793 }
00794
00795 static isc_result_t
00796 createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
00797 {
00798 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00799 sdlz_dbiterator_t *sdlziter;
00800 isc_result_t result;
00801 isc_buffer_t b;
00802 char zonestr[DNS_NAME_MAXTEXT + 1];
00803
00804 REQUIRE(VALID_SDLZDB(sdlz));
00805
00806 if (sdlz->dlzimp->methods->allnodes == NULL)
00807 return (ISC_R_NOTIMPLEMENTED);
00808
00809 if ((options & DNS_DB_NSEC3ONLY) != 0 ||
00810 (options & DNS_DB_NONSEC3) != 0)
00811 return (ISC_R_NOTIMPLEMENTED);
00812
00813 isc_buffer_init(&b, zonestr, sizeof(zonestr));
00814 result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b);
00815 if (result != ISC_R_SUCCESS)
00816 return (result);
00817 isc_buffer_putuint8(&b, 0);
00818
00819 sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t));
00820 if (sdlziter == NULL)
00821 return (ISC_R_NOMEMORY);
00822
00823 sdlziter->common.methods = &dbiterator_methods;
00824 sdlziter->common.db = NULL;
00825 dns_db_attach(db, &sdlziter->common.db);
00826 sdlziter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
00827 sdlziter->common.magic = DNS_DBITERATOR_MAGIC;
00828 ISC_LIST_INIT(sdlziter->nodelist);
00829 sdlziter->current = NULL;
00830 sdlziter->origin = NULL;
00831
00832
00833 dns_sdlz_tolower(zonestr);
00834
00835 MAYBE_LOCK(sdlz->dlzimp);
00836 result = sdlz->dlzimp->methods->allnodes(zonestr,
00837 sdlz->dlzimp->driverarg,
00838 sdlz->dbdata, sdlziter);
00839 MAYBE_UNLOCK(sdlz->dlzimp);
00840 if (result != ISC_R_SUCCESS) {
00841 dns_dbiterator_t *iter = &sdlziter->common;
00842 dbiterator_destroy(&iter);
00843 return (result);
00844 }
00845
00846 if (sdlziter->origin != NULL) {
00847 ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link);
00848 ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link);
00849 }
00850
00851 *iteratorp = (dns_dbiterator_t *)sdlziter;
00852
00853 return (ISC_R_SUCCESS);
00854 }
00855
00856 static isc_result_t
00857 findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00858 dns_rdatatype_t type, dns_rdatatype_t covers,
00859 isc_stdtime_t now, dns_rdataset_t *rdataset,
00860 dns_rdataset_t *sigrdataset)
00861 {
00862 dns_rdatalist_t *list;
00863 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node;
00864
00865 REQUIRE(VALID_SDLZNODE(node));
00866
00867 UNUSED(db);
00868 UNUSED(version);
00869 UNUSED(covers);
00870 UNUSED(now);
00871 UNUSED(sigrdataset);
00872
00873 if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig)
00874 return (ISC_R_NOTIMPLEMENTED);
00875
00876 list = ISC_LIST_HEAD(sdlznode->lists);
00877 while (list != NULL) {
00878 if (list->type == type)
00879 break;
00880 list = ISC_LIST_NEXT(list, link);
00881 }
00882 if (list == NULL)
00883 return (ISC_R_NOTFOUND);
00884
00885 list_tordataset(list, db, node, rdataset);
00886
00887 return (ISC_R_SUCCESS);
00888 }
00889
00890 static isc_result_t
00891 findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
00892 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
00893 dns_dbnode_t **nodep, dns_name_t *foundname,
00894 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
00895 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00896 {
00897 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
00898 dns_dbnode_t *node = NULL;
00899 dns_fixedname_t fname;
00900 dns_rdataset_t xrdataset;
00901 dns_name_t *xname;
00902 unsigned int nlabels, olabels;
00903 isc_result_t result;
00904 unsigned int i;
00905
00906 REQUIRE(VALID_SDLZDB(sdlz));
00907 REQUIRE(nodep == NULL || *nodep == NULL);
00908 REQUIRE(version == NULL ||
00909 version == (void*)&sdlz->dummy_version ||
00910 version == sdlz->future_version);
00911
00912 UNUSED(sdlz);
00913
00914 if (!dns_name_issubdomain(name, &db->origin))
00915 return (DNS_R_NXDOMAIN);
00916
00917 olabels = dns_name_countlabels(&db->origin);
00918 nlabels = dns_name_countlabels(name);
00919
00920 dns_fixedname_init(&fname);
00921 xname = dns_fixedname_name(&fname);
00922
00923 if (rdataset == NULL) {
00924 dns_rdataset_init(&xrdataset);
00925 rdataset = &xrdataset;
00926 }
00927
00928 result = DNS_R_NXDOMAIN;
00929
00930
00931
00932
00933
00934 if ((options & DNS_DBFIND_NOZONECUT) != 0) {
00935 i = nlabels;
00936 goto search;
00937 }
00938
00939 for (i = olabels; i <= nlabels; i++) {
00940 search:
00941
00942
00943
00944 dns_name_getlabelsequence(name, nlabels - i, i, xname);
00945 result = getnodedata(db, xname, ISC_FALSE, options,
00946 methods, clientinfo, &node);
00947 if (result == ISC_R_NOTFOUND) {
00948 result = DNS_R_NXDOMAIN;
00949 continue;
00950 } else if (result != ISC_R_SUCCESS)
00951 break;
00952
00953
00954
00955
00956
00957 if (i < nlabels) {
00958 result = findrdataset(db, node, version,
00959 dns_rdatatype_dname, 0, now,
00960 rdataset, sigrdataset);
00961 if (result == ISC_R_SUCCESS) {
00962 result = DNS_R_DNAME;
00963 break;
00964 }
00965 }
00966
00967
00968
00969
00970
00971 if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0 &&
00972 (options & DNS_DBFIND_NOZONECUT) == 0)
00973 {
00974 result = findrdataset(db, node, version,
00975 dns_rdatatype_ns, 0, now,
00976 rdataset, sigrdataset);
00977
00978 if (result == ISC_R_SUCCESS &&
00979 i == nlabels && type == dns_rdatatype_any)
00980 {
00981 result = DNS_R_ZONECUT;
00982 dns_rdataset_disassociate(rdataset);
00983 if (sigrdataset != NULL &&
00984 dns_rdataset_isassociated(sigrdataset))
00985 dns_rdataset_disassociate(sigrdataset);
00986 break;
00987 } else if (result == ISC_R_SUCCESS) {
00988 result = DNS_R_DELEGATION;
00989 break;
00990 }
00991 }
00992
00993
00994
00995
00996
00997 if (i < nlabels) {
00998 destroynode(node);
00999 node = NULL;
01000 continue;
01001 }
01002
01003
01004
01005
01006 if (type == dns_rdatatype_any) {
01007 result = ISC_R_SUCCESS;
01008 break;
01009 }
01010
01011
01012
01013
01014 result = findrdataset(db, node, version, type, 0, now,
01015 rdataset, sigrdataset);
01016 if (result == ISC_R_SUCCESS)
01017 break;
01018
01019
01020
01021
01022 if (type != dns_rdatatype_cname) {
01023 result = findrdataset(db, node, version,
01024 dns_rdatatype_cname, 0, now,
01025 rdataset, sigrdataset);
01026 if (result == ISC_R_SUCCESS) {
01027 result = DNS_R_CNAME;
01028 break;
01029 }
01030 }
01031
01032 result = DNS_R_NXRRSET;
01033 break;
01034 }
01035
01036 if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
01037 dns_rdataset_disassociate(rdataset);
01038
01039 if (foundname != NULL) {
01040 isc_result_t xresult;
01041
01042 xresult = dns_name_copy(xname, foundname, NULL);
01043 if (xresult != ISC_R_SUCCESS) {
01044 if (node != NULL)
01045 destroynode(node);
01046 if (dns_rdataset_isassociated(rdataset))
01047 dns_rdataset_disassociate(rdataset);
01048 return (DNS_R_BADDB);
01049 }
01050 }
01051
01052 if (nodep != NULL)
01053 *nodep = node;
01054 else if (node != NULL)
01055 detachnode(db, &node);
01056
01057 return (result);
01058 }
01059
01060 static isc_result_t
01061 find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
01062 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
01063 dns_dbnode_t **nodep, dns_name_t *foundname,
01064 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
01065 {
01066 return (findext(db, name, version, type, options, now, nodep,
01067 foundname, NULL, NULL, rdataset, sigrdataset));
01068 }
01069
01070 static isc_result_t
01071 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01072 isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
01073 {
01074 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db;
01075 sdlz_rdatasetiter_t *iterator;
01076
01077 REQUIRE(VALID_SDLZDB(sdlz));
01078
01079 REQUIRE(version == NULL ||
01080 version == (void*)&sdlz->dummy_version ||
01081 version == sdlz->future_version);
01082
01083 UNUSED(version);
01084 UNUSED(now);
01085
01086 iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t));
01087 if (iterator == NULL)
01088 return (ISC_R_NOMEMORY);
01089
01090 iterator->common.magic = DNS_RDATASETITER_MAGIC;
01091 iterator->common.methods = &rdatasetiter_methods;
01092 iterator->common.db = db;
01093 iterator->common.node = NULL;
01094 attachnode(db, node, &iterator->common.node);
01095 iterator->common.version = version;
01096 iterator->common.now = now;
01097
01098 *iteratorp = (dns_rdatasetiter_t *)iterator;
01099
01100 return (ISC_R_SUCCESS);
01101 }
01102
01103 static isc_result_t
01104 modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01105 dns_rdataset_t *rdataset, unsigned int options,
01106 dns_sdlzmodrdataset_t mod_function)
01107 {
01108 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
01109 dns_master_style_t *style = NULL;
01110 isc_result_t result;
01111 isc_buffer_t *buffer = NULL;
01112 isc_mem_t *mctx;
01113 dns_sdlznode_t *sdlznode;
01114 char *rdatastr = NULL;
01115 char name[DNS_NAME_MAXTEXT + 1];
01116
01117 REQUIRE(VALID_SDLZDB(sdlz));
01118
01119 if (mod_function == NULL)
01120 return (ISC_R_NOTIMPLEMENTED);
01121
01122 sdlznode = (dns_sdlznode_t *)node;
01123
01124 UNUSED(options);
01125
01126 dns_name_format(sdlznode->name, name, sizeof(name));
01127
01128 mctx = sdlz->common.mctx;
01129
01130 result = isc_buffer_allocate(mctx, &buffer, 1024);
01131 if (result != ISC_R_SUCCESS)
01132 return (result);
01133
01134 result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx);
01135 if (result != ISC_R_SUCCESS)
01136 goto cleanup;
01137
01138 result = dns_master_rdatasettotext(sdlznode->name, rdataset,
01139 style, buffer);
01140 if (result != ISC_R_SUCCESS)
01141 goto cleanup;
01142
01143 if (isc_buffer_usedlength(buffer) < 1) {
01144 result = ISC_R_BADADDRESSFORM;
01145 goto cleanup;
01146 }
01147
01148 rdatastr = isc_buffer_base(buffer);
01149 if (rdatastr == NULL) {
01150 result = ISC_R_NOMEMORY;
01151 goto cleanup;
01152 }
01153 rdatastr[isc_buffer_usedlength(buffer) - 1] = 0;
01154
01155 MAYBE_LOCK(sdlz->dlzimp);
01156 result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg,
01157 sdlz->dbdata, version);
01158 MAYBE_UNLOCK(sdlz->dlzimp);
01159
01160 cleanup:
01161 isc_buffer_free(&buffer);
01162 if (style != NULL)
01163 dns_master_styledestroy(&style, mctx);
01164
01165 return (result);
01166 }
01167
01168 static isc_result_t
01169 addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01170 isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
01171 dns_rdataset_t *addedrdataset)
01172 {
01173 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
01174 isc_result_t result;
01175
01176 UNUSED(now);
01177 UNUSED(addedrdataset);
01178 REQUIRE(VALID_SDLZDB(sdlz));
01179
01180 if (sdlz->dlzimp->methods->addrdataset == NULL)
01181 return (ISC_R_NOTIMPLEMENTED);
01182
01183 result = modrdataset(db, node, version, rdataset, options,
01184 sdlz->dlzimp->methods->addrdataset);
01185 return (result);
01186 }
01187
01188
01189 static isc_result_t
01190 subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01191 dns_rdataset_t *rdataset, unsigned int options,
01192 dns_rdataset_t *newrdataset)
01193 {
01194 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
01195 isc_result_t result;
01196
01197 UNUSED(newrdataset);
01198 REQUIRE(VALID_SDLZDB(sdlz));
01199
01200 if (sdlz->dlzimp->methods->subtractrdataset == NULL) {
01201 return (ISC_R_NOTIMPLEMENTED);
01202 }
01203
01204 result = modrdataset(db, node, version, rdataset, options,
01205 sdlz->dlzimp->methods->subtractrdataset);
01206 return (result);
01207 }
01208
01209 static isc_result_t
01210 deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
01211 dns_rdatatype_t type, dns_rdatatype_t covers)
01212 {
01213 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
01214 char name[DNS_NAME_MAXTEXT + 1];
01215 char b_type[DNS_RDATATYPE_FORMATSIZE];
01216 dns_sdlznode_t *sdlznode;
01217 isc_result_t result;
01218
01219 UNUSED(covers);
01220
01221 REQUIRE(VALID_SDLZDB(sdlz));
01222
01223 if (sdlz->dlzimp->methods->delrdataset == NULL)
01224 return (ISC_R_NOTIMPLEMENTED);
01225
01226 sdlznode = (dns_sdlznode_t *)node;
01227 dns_name_format(sdlznode->name, name, sizeof(name));
01228 dns_rdatatype_format(type, b_type, sizeof(b_type));
01229
01230 MAYBE_LOCK(sdlz->dlzimp);
01231 result = sdlz->dlzimp->methods->delrdataset(name, b_type,
01232 sdlz->dlzimp->driverarg,
01233 sdlz->dbdata, version);
01234 MAYBE_UNLOCK(sdlz->dlzimp);
01235
01236 return (result);
01237 }
01238
01239 static isc_boolean_t
01240 issecure(dns_db_t *db) {
01241 UNUSED(db);
01242
01243 return (ISC_FALSE);
01244 }
01245
01246 static unsigned int
01247 nodecount(dns_db_t *db) {
01248 UNUSED(db);
01249
01250 return (0);
01251 }
01252
01253 static isc_boolean_t
01254 ispersistent(dns_db_t *db) {
01255 UNUSED(db);
01256 return (ISC_TRUE);
01257 }
01258
01259 static void
01260 overmem(dns_db_t *db, isc_boolean_t over) {
01261 UNUSED(db);
01262 UNUSED(over);
01263 }
01264
01265 static void
01266 settask(dns_db_t *db, isc_task_t *task) {
01267 UNUSED(db);
01268 UNUSED(task);
01269 }
01270
01271
01272
01273
01274
01275 static isc_result_t
01276 getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
01277 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
01278 isc_result_t result;
01279
01280 REQUIRE(VALID_SDLZDB(sdlz));
01281 if (sdlz->dlzimp->methods->newversion == NULL)
01282 return (ISC_R_NOTIMPLEMENTED);
01283
01284 result = getnodedata(db, &sdlz->common.origin, ISC_FALSE,
01285 0, NULL, NULL, nodep);
01286 if (result != ISC_R_SUCCESS)
01287 sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s",
01288 isc_result_totext(result));
01289 return (result);
01290 }
01291
01292 static dns_dbmethods_t sdlzdb_methods = {
01293 attach,
01294 detach,
01295 beginload,
01296 endload,
01297 NULL,
01298 dump,
01299 currentversion,
01300 newversion,
01301 attachversion,
01302 closeversion,
01303 findnode,
01304 find,
01305 findzonecut,
01306 attachnode,
01307 detachnode,
01308 expirenode,
01309 printnode,
01310 createiterator,
01311 findrdataset,
01312 allrdatasets,
01313 addrdataset,
01314 subtractrdataset,
01315 deleterdataset,
01316 issecure,
01317 nodecount,
01318 ispersistent,
01319 overmem,
01320 settask,
01321 getoriginnode,
01322 NULL,
01323 NULL,
01324 NULL,
01325 NULL,
01326 NULL,
01327 NULL,
01328 NULL,
01329 NULL,
01330 NULL,
01331 NULL,
01332 findnodeext,
01333 findext,
01334 NULL,
01335 NULL
01336 };
01337
01338
01339
01340
01341
01342
01343 static void
01344 dbiterator_destroy(dns_dbiterator_t **iteratorp) {
01345 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp);
01346 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db;
01347
01348 while (!ISC_LIST_EMPTY(sdlziter->nodelist)) {
01349 dns_sdlznode_t *node;
01350 node = ISC_LIST_HEAD(sdlziter->nodelist);
01351 ISC_LIST_UNLINK(sdlziter->nodelist, node, link);
01352 destroynode(node);
01353 }
01354
01355 dns_db_detach(&sdlziter->common.db);
01356 isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t));
01357
01358 *iteratorp = NULL;
01359 }
01360
01361 static isc_result_t
01362 dbiterator_first(dns_dbiterator_t *iterator) {
01363 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01364
01365 sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
01366 if (sdlziter->current == NULL)
01367 return (ISC_R_NOMORE);
01368 else
01369 return (ISC_R_SUCCESS);
01370 }
01371
01372 static isc_result_t
01373 dbiterator_last(dns_dbiterator_t *iterator) {
01374 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01375
01376 sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist);
01377 if (sdlziter->current == NULL)
01378 return (ISC_R_NOMORE);
01379 else
01380 return (ISC_R_SUCCESS);
01381 }
01382
01383 static isc_result_t
01384 dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
01385 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01386
01387 sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
01388 while (sdlziter->current != NULL) {
01389 if (dns_name_equal(sdlziter->current->name, name))
01390 return (ISC_R_SUCCESS);
01391 sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
01392 }
01393 return (ISC_R_NOTFOUND);
01394 }
01395
01396 static isc_result_t
01397 dbiterator_prev(dns_dbiterator_t *iterator) {
01398 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01399
01400 sdlziter->current = ISC_LIST_PREV(sdlziter->current, link);
01401 if (sdlziter->current == NULL)
01402 return (ISC_R_NOMORE);
01403 else
01404 return (ISC_R_SUCCESS);
01405 }
01406
01407 static isc_result_t
01408 dbiterator_next(dns_dbiterator_t *iterator) {
01409 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01410
01411 sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
01412 if (sdlziter->current == NULL)
01413 return (ISC_R_NOMORE);
01414 else
01415 return (ISC_R_SUCCESS);
01416 }
01417
01418 static isc_result_t
01419 dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
01420 dns_name_t *name)
01421 {
01422 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
01423
01424 attachnode(iterator->db, sdlziter->current, nodep);
01425 if (name != NULL)
01426 return (dns_name_copy(sdlziter->current->name, name, NULL));
01427 return (ISC_R_SUCCESS);
01428 }
01429
01430 static isc_result_t
01431 dbiterator_pause(dns_dbiterator_t *iterator) {
01432 UNUSED(iterator);
01433 return (ISC_R_SUCCESS);
01434 }
01435
01436 static isc_result_t
01437 dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
01438 UNUSED(iterator);
01439 return (dns_name_copy(dns_rootname, name, NULL));
01440 }
01441
01442
01443
01444
01445
01446
01447 static void
01448 disassociate(dns_rdataset_t *rdataset) {
01449 dns_dbnode_t *node = rdataset->private5;
01450 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
01451 dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
01452
01453 detachnode(db, &node);
01454 isc__rdatalist_disassociate(rdataset);
01455 }
01456
01457 static void
01458 rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
01459 dns_dbnode_t *node = source->private5;
01460 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
01461 dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
01462 dns_dbnode_t *tempdb = NULL;
01463
01464 isc__rdatalist_clone(source, target);
01465 attachnode(db, node, &tempdb);
01466 source->private5 = tempdb;
01467 }
01468
01469 static dns_rdatasetmethods_t rdataset_methods = {
01470 disassociate,
01471 isc__rdatalist_first,
01472 isc__rdatalist_next,
01473 isc__rdatalist_current,
01474 rdataset_clone,
01475 isc__rdatalist_count,
01476 isc__rdatalist_addnoqname,
01477 isc__rdatalist_getnoqname,
01478 NULL,
01479 NULL,
01480 NULL,
01481 NULL,
01482 NULL,
01483 NULL,
01484 NULL,
01485 NULL,
01486 NULL,
01487 NULL
01488 };
01489
01490 static void
01491 list_tordataset(dns_rdatalist_t *rdatalist,
01492 dns_db_t *db, dns_dbnode_t *node,
01493 dns_rdataset_t *rdataset)
01494 {
01495
01496
01497
01498
01499
01500
01501
01502
01503 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
01504 ISC_R_SUCCESS);
01505
01506 rdataset->methods = &rdataset_methods;
01507 dns_db_attachnode(db, node, &rdataset->private5);
01508 }
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521 static isc_result_t
01522 dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
01523 dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp)
01524 {
01525 isc_result_t result;
01526 dns_sdlz_db_t *sdlzdb;
01527 dns_sdlzimplementation_t *imp;
01528
01529
01530 REQUIRE(dbp != NULL && *dbp == NULL);
01531 REQUIRE(name != NULL);
01532
01533 imp = (dns_sdlzimplementation_t *) driverarg;
01534
01535
01536 sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t));
01537 if (sdlzdb == NULL)
01538 return (ISC_R_NOMEMORY);
01539 memset(sdlzdb, 0, sizeof(dns_sdlz_db_t));
01540
01541
01542 dns_name_init(&sdlzdb->common.origin, NULL);
01543 result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin);
01544 if (result != ISC_R_SUCCESS)
01545 goto mem_cleanup;
01546
01547
01548 result = isc_mutex_init(&sdlzdb->refcnt_lock);
01549 if (result != ISC_R_SUCCESS)
01550 goto name_cleanup;
01551
01552
01553 sdlzdb->dlzimp = imp;
01554 sdlzdb->common.methods = &sdlzdb_methods;
01555 sdlzdb->common.attributes = 0;
01556 sdlzdb->common.rdclass = rdclass;
01557 sdlzdb->common.mctx = NULL;
01558 sdlzdb->dbdata = dbdata;
01559 sdlzdb->references = 1;
01560
01561
01562 isc_mem_attach(mctx, &sdlzdb->common.mctx);
01563
01564
01565 sdlzdb->common.magic = DNS_DB_MAGIC;
01566 sdlzdb->common.impmagic = SDLZDB_MAGIC;
01567 *dbp = (dns_db_t *) sdlzdb;
01568
01569 return (result);
01570
01571
01572
01573
01574
01575 name_cleanup:
01576 dns_name_free(&sdlzdb->common.origin, mctx);
01577 mem_cleanup:
01578 isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t));
01579 return (result);
01580 }
01581
01582 static isc_result_t
01583 dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
01584 dns_rdataclass_t rdclass, dns_name_t *name,
01585 isc_sockaddr_t *clientaddr, dns_db_t **dbp)
01586 {
01587 isc_buffer_t b;
01588 isc_buffer_t b2;
01589 char namestr[DNS_NAME_MAXTEXT + 1];
01590 char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")
01591 + 1];
01592 isc_netaddr_t netaddr;
01593 isc_result_t result;
01594 dns_sdlzimplementation_t *imp;
01595
01596
01597
01598
01599 REQUIRE(driverarg != NULL);
01600 REQUIRE(name != NULL);
01601 REQUIRE(clientaddr != NULL);
01602 REQUIRE(dbp != NULL && *dbp == NULL);
01603
01604 imp = (dns_sdlzimplementation_t *) driverarg;
01605
01606
01607 isc_buffer_init(&b, namestr, sizeof(namestr));
01608 result = dns_name_totext(name, ISC_TRUE, &b);
01609 if (result != ISC_R_SUCCESS)
01610 return (result);
01611 isc_buffer_putuint8(&b, 0);
01612
01613
01614 isc_buffer_init(&b2, clientstr, sizeof(clientstr));
01615 isc_netaddr_fromsockaddr(&netaddr, clientaddr);
01616 result = isc_netaddr_totext(&netaddr, &b2);
01617 if (result != ISC_R_SUCCESS)
01618 return (result);
01619 isc_buffer_putuint8(&b2, 0);
01620
01621
01622 dns_sdlz_tolower(namestr);
01623 dns_sdlz_tolower(clientstr);
01624
01625
01626 if (imp->methods->allowzonexfr != NULL) {
01627 MAYBE_LOCK(imp);
01628 result = imp->methods->allowzonexfr(imp->driverarg, dbdata,
01629 namestr, clientstr);
01630 MAYBE_UNLOCK(imp);
01631
01632
01633
01634
01635 if (result == ISC_R_SUCCESS)
01636 result = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
01637 name, rdclass, dbp);
01638 return (result);
01639 }
01640
01641 return (ISC_R_NOTIMPLEMENTED);
01642 }
01643
01644 static isc_result_t
01645 dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
01646 char *argv[], void *driverarg, void **dbdata)
01647 {
01648 dns_sdlzimplementation_t *imp;
01649 isc_result_t result = ISC_R_NOTFOUND;
01650
01651
01652 sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver.");
01653
01654
01655
01656
01657 REQUIRE(driverarg != NULL);
01658 REQUIRE(dlzname != NULL);
01659 REQUIRE(dbdata != NULL);
01660 UNUSED(mctx);
01661
01662 imp = driverarg;
01663
01664
01665 if (imp->methods->create != NULL) {
01666 MAYBE_LOCK(imp);
01667 result = imp->methods->create(dlzname, argc, argv,
01668 imp->driverarg, dbdata);
01669 MAYBE_UNLOCK(imp);
01670 }
01671
01672
01673 if (result == ISC_R_SUCCESS) {
01674 sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully.");
01675 } else {
01676 sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load.");
01677 }
01678
01679 return (result);
01680 }
01681
01682 static void
01683 dns_sdlzdestroy(void *driverdata, void **dbdata) {
01684 dns_sdlzimplementation_t *imp;
01685
01686
01687 sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver.");
01688
01689 imp = driverdata;
01690
01691
01692 if (imp->methods->destroy != NULL) {
01693 MAYBE_LOCK(imp);
01694 imp->methods->destroy(imp->driverarg, dbdata);
01695 MAYBE_UNLOCK(imp);
01696 }
01697 }
01698
01699 static isc_result_t
01700 dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
01701 dns_rdataclass_t rdclass, dns_name_t *name,
01702 dns_clientinfomethods_t *methods,
01703 dns_clientinfo_t *clientinfo,
01704 dns_db_t **dbp)
01705 {
01706 isc_buffer_t b;
01707 char namestr[DNS_NAME_MAXTEXT + 1];
01708 isc_result_t result;
01709 dns_sdlzimplementation_t *imp;
01710
01711
01712
01713
01714 REQUIRE(driverarg != NULL);
01715 REQUIRE(name != NULL);
01716 REQUIRE(dbp != NULL && *dbp == NULL);
01717
01718 imp = (dns_sdlzimplementation_t *) driverarg;
01719
01720
01721 isc_buffer_init(&b, namestr, sizeof(namestr));
01722 result = dns_name_totext(name, ISC_TRUE, &b);
01723 if (result != ISC_R_SUCCESS)
01724 return (result);
01725 isc_buffer_putuint8(&b, 0);
01726
01727
01728 dns_sdlz_tolower(namestr);
01729
01730
01731 MAYBE_LOCK(imp);
01732 result = imp->methods->findzone(imp->driverarg, dbdata, namestr,
01733 methods, clientinfo);
01734 MAYBE_UNLOCK(imp);
01735
01736
01737
01738
01739
01740 if (result == ISC_R_SUCCESS)
01741 result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name,
01742 rdclass, dbp);
01743
01744 return (result);
01745 }
01746
01747
01748 static isc_result_t
01749 dns_sdlzconfigure(void *driverarg, void *dbdata,
01750 dns_view_t *view, dns_dlzdb_t *dlzdb)
01751 {
01752 isc_result_t result;
01753 dns_sdlzimplementation_t *imp;
01754
01755 REQUIRE(driverarg != NULL);
01756
01757 imp = (dns_sdlzimplementation_t *) driverarg;
01758
01759
01760 if (imp->methods->configure != NULL) {
01761 MAYBE_LOCK(imp);
01762 result = imp->methods->configure(view, dlzdb,
01763 imp->driverarg, dbdata);
01764 MAYBE_UNLOCK(imp);
01765 } else {
01766 result = ISC_R_SUCCESS;
01767 }
01768
01769 return (result);
01770 }
01771
01772 static isc_boolean_t
01773 dns_sdlzssumatch(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
01774 dns_rdatatype_t type, const dst_key_t *key, void *driverarg,
01775 void *dbdata)
01776 {
01777 dns_sdlzimplementation_t *imp;
01778 char b_signer[DNS_NAME_FORMATSIZE];
01779 char b_name[DNS_NAME_FORMATSIZE];
01780 char b_addr[ISC_NETADDR_FORMATSIZE];
01781 char b_type[DNS_RDATATYPE_FORMATSIZE];
01782 char b_key[DST_KEY_FORMATSIZE];
01783 isc_buffer_t *tkey_token = NULL;
01784 isc_region_t token_region;
01785 isc_uint32_t token_len = 0;
01786 isc_boolean_t ret;
01787
01788 REQUIRE(driverarg != NULL);
01789
01790 imp = (dns_sdlzimplementation_t *) driverarg;
01791 if (imp->methods->ssumatch == NULL)
01792 return (ISC_FALSE);
01793
01794
01795
01796
01797
01798 if (signer != NULL)
01799 dns_name_format(signer, b_signer, sizeof(b_signer));
01800 else
01801 b_signer[0] = 0;
01802
01803 dns_name_format(name, b_name, sizeof(b_name));
01804
01805 if (tcpaddr != NULL)
01806 isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
01807 else
01808 b_addr[0] = 0;
01809
01810 dns_rdatatype_format(type, b_type, sizeof(b_type));
01811
01812 if (key != NULL) {
01813 dst_key_format(key, b_key, sizeof(b_key));
01814 tkey_token = dst_key_tkeytoken(key);
01815 } else
01816 b_key[0] = 0;
01817
01818 if (tkey_token != NULL) {
01819 isc_buffer_region(tkey_token, &token_region);
01820 token_len = token_region.length;
01821 }
01822
01823 MAYBE_LOCK(imp);
01824 ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key,
01825 token_len,
01826 token_len != 0 ? token_region.base : NULL,
01827 imp->driverarg, dbdata);
01828 MAYBE_UNLOCK(imp);
01829 return (ret);
01830 }
01831
01832 static dns_dlzmethods_t sdlzmethods = {
01833 dns_sdlzcreate,
01834 dns_sdlzdestroy,
01835 dns_sdlzfindzone,
01836 dns_sdlzallowzonexfr,
01837 dns_sdlzconfigure,
01838 dns_sdlzssumatch
01839 };
01840
01841
01842
01843
01844
01845 isc_result_t
01846 dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
01847 const char *data)
01848 {
01849 dns_rdatalist_t *rdatalist;
01850 dns_rdata_t *rdata;
01851 dns_rdatatype_t typeval;
01852 isc_consttextregion_t r;
01853 isc_buffer_t b;
01854 isc_buffer_t *rdatabuf = NULL;
01855 isc_lex_t *lex;
01856 isc_result_t result;
01857 unsigned int size;
01858 isc_mem_t *mctx;
01859 dns_name_t *origin;
01860
01861 REQUIRE(VALID_SDLZLOOKUP(lookup));
01862 REQUIRE(type != NULL);
01863 REQUIRE(data != NULL);
01864
01865 mctx = lookup->sdlz->common.mctx;
01866
01867 r.base = type;
01868 r.length = strlen(type);
01869 result = dns_rdatatype_fromtext(&typeval, (void *) &r);
01870 if (result != ISC_R_SUCCESS)
01871 return (result);
01872
01873 rdatalist = ISC_LIST_HEAD(lookup->lists);
01874 while (rdatalist != NULL) {
01875 if (rdatalist->type == typeval)
01876 break;
01877 rdatalist = ISC_LIST_NEXT(rdatalist, link);
01878 }
01879
01880 if (rdatalist == NULL) {
01881 rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
01882 if (rdatalist == NULL)
01883 return (ISC_R_NOMEMORY);
01884 dns_rdatalist_init(rdatalist);
01885 rdatalist->rdclass = lookup->sdlz->common.rdclass;
01886 rdatalist->type = typeval;
01887 rdatalist->ttl = ttl;
01888 ISC_LIST_APPEND(lookup->lists, rdatalist, link);
01889 } else
01890 if (rdatalist->ttl > ttl) {
01891
01892
01893
01894
01895
01896
01897
01898 rdatalist->ttl = ttl;
01899 }
01900
01901 rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
01902 if (rdata == NULL)
01903 return (ISC_R_NOMEMORY);
01904 dns_rdata_init(rdata);
01905
01906 if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
01907 origin = &lookup->sdlz->common.origin;
01908 else
01909 origin = dns_rootname;
01910
01911 lex = NULL;
01912 result = isc_lex_create(mctx, 64, &lex);
01913 if (result != ISC_R_SUCCESS)
01914 goto failure;
01915
01916 size = initial_size(data);
01917 do {
01918 isc_buffer_constinit(&b, data, strlen(data));
01919 isc_buffer_add(&b, strlen(data));
01920
01921 result = isc_lex_openbuffer(lex, &b);
01922 if (result != ISC_R_SUCCESS)
01923 goto failure;
01924
01925 rdatabuf = NULL;
01926 result = isc_buffer_allocate(mctx, &rdatabuf, size);
01927 if (result != ISC_R_SUCCESS)
01928 goto failure;
01929
01930 result = dns_rdata_fromtext(rdata, rdatalist->rdclass,
01931 rdatalist->type, lex,
01932 origin, ISC_FALSE,
01933 mctx, rdatabuf,
01934 &lookup->callbacks);
01935 if (result != ISC_R_SUCCESS)
01936 isc_buffer_free(&rdatabuf);
01937 if (size >= 65535)
01938 break;
01939 size *= 2;
01940 if (size >= 65535)
01941 size = 65535;
01942 } while (result == ISC_R_NOSPACE);
01943
01944 if (result != ISC_R_SUCCESS)
01945 goto failure;
01946
01947 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
01948 ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
01949
01950 if (lex != NULL)
01951 isc_lex_destroy(&lex);
01952
01953 return (ISC_R_SUCCESS);
01954
01955 failure:
01956 if (rdatabuf != NULL)
01957 isc_buffer_free(&rdatabuf);
01958 if (lex != NULL)
01959 isc_lex_destroy(&lex);
01960 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
01961
01962 return (result);
01963 }
01964
01965 isc_result_t
01966 dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
01967 const char *type, dns_ttl_t ttl, const char *data)
01968 {
01969 dns_name_t *newname, *origin;
01970 dns_fixedname_t fnewname;
01971 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db;
01972 dns_sdlznode_t *sdlznode;
01973 isc_mem_t *mctx = sdlz->common.mctx;
01974 isc_buffer_t b;
01975 isc_result_t result;
01976
01977 dns_fixedname_init(&fnewname);
01978 newname = dns_fixedname_name(&fnewname);
01979
01980 if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
01981 origin = &sdlz->common.origin;
01982 else
01983 origin = dns_rootname;
01984 isc_buffer_constinit(&b, name, strlen(name));
01985 isc_buffer_add(&b, strlen(name));
01986
01987 result = dns_name_fromtext(newname, &b, origin, 0, NULL);
01988 if (result != ISC_R_SUCCESS)
01989 return (result);
01990
01991 if (allnodes->common.relative_names) {
01992
01993 unsigned int nlabels = dns_name_countlabels(newname);
01994 dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
01995 }
01996
01997 sdlznode = ISC_LIST_HEAD(allnodes->nodelist);
01998 if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) {
01999 sdlznode = NULL;
02000 result = createnode(sdlz, &sdlznode);
02001 if (result != ISC_R_SUCCESS)
02002 return (result);
02003 sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t));
02004 if (sdlznode->name == NULL) {
02005 destroynode(sdlznode);
02006 return (ISC_R_NOMEMORY);
02007 }
02008 dns_name_init(sdlznode->name, NULL);
02009 result = dns_name_dup(newname, mctx, sdlznode->name);
02010 if (result != ISC_R_SUCCESS) {
02011 isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t));
02012 destroynode(sdlznode);
02013 return (result);
02014 }
02015 ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link);
02016 if (allnodes->origin == NULL &&
02017 dns_name_equal(newname, &sdlz->common.origin))
02018 allnodes->origin = sdlznode;
02019 }
02020 return (dns_sdlz_putrr(sdlznode, type, ttl, data));
02021
02022 }
02023
02024 isc_result_t
02025 dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname,
02026 isc_uint32_t serial)
02027 {
02028 char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
02029 int n;
02030
02031 REQUIRE(mname != NULL);
02032 REQUIRE(rname != NULL);
02033
02034 n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u",
02035 mname, rname, serial,
02036 SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY,
02037 SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM);
02038 if (n >= (int)sizeof(str) || n < 0)
02039 return (ISC_R_NOSPACE);
02040 return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str));
02041 }
02042
02043 isc_result_t
02044 dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
02045 void *driverarg, unsigned int flags, isc_mem_t *mctx,
02046 dns_sdlzimplementation_t **sdlzimp)
02047 {
02048
02049 dns_sdlzimplementation_t *imp;
02050 isc_result_t result;
02051
02052
02053
02054
02055 REQUIRE(drivername != NULL);
02056 REQUIRE(methods != NULL);
02057 REQUIRE(methods->findzone != NULL);
02058 REQUIRE(methods->lookup != NULL);
02059 REQUIRE(mctx != NULL);
02060 REQUIRE(sdlzimp != NULL && *sdlzimp == NULL);
02061 REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER |
02062 DNS_SDLZFLAG_RELATIVERDATA |
02063 DNS_SDLZFLAG_THREADSAFE)) == 0);
02064
02065
02066 sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername);
02067
02068
02069
02070
02071
02072 imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t));
02073 if (imp == NULL)
02074 return (ISC_R_NOMEMORY);
02075
02076
02077 memset(imp, 0, sizeof(dns_sdlzimplementation_t));
02078
02079
02080 imp->methods = methods;
02081 imp->driverarg = driverarg;
02082 imp->flags = flags;
02083 imp->mctx = NULL;
02084
02085
02086 isc_mem_attach(mctx, &imp->mctx);
02087
02088
02089
02090
02091
02092 result = isc_mutex_init(&imp->driverlock);
02093 if (result != ISC_R_SUCCESS) {
02094 UNEXPECTED_ERROR(__FILE__, __LINE__,
02095 "isc_mutex_init() failed: %s",
02096 isc_result_totext(result));
02097 goto cleanup_mctx;
02098 }
02099
02100 imp->dlz_imp = NULL;
02101
02102
02103
02104
02105
02106
02107
02108 result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx,
02109 &imp->dlz_imp);
02110
02111
02112 if (result != ISC_R_SUCCESS)
02113 goto cleanup_mutex;
02114
02115 *sdlzimp = imp;
02116
02117 return (ISC_R_SUCCESS);
02118
02119 cleanup_mutex:
02120
02121 DESTROYLOCK(&imp->driverlock);
02122
02123 cleanup_mctx:
02124
02125
02126
02127
02128 isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
02129 isc_mem_detach(&mctx);
02130 return (result);
02131 }
02132
02133 void
02134 dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
02135 dns_sdlzimplementation_t *imp;
02136 isc_mem_t *mctx;
02137
02138
02139 sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver.");
02140
02141
02142
02143
02144 REQUIRE(sdlzimp != NULL && *sdlzimp != NULL);
02145
02146 imp = *sdlzimp;
02147
02148
02149 dns_dlzunregister(&imp->dlz_imp);
02150
02151
02152 DESTROYLOCK(&imp->driverlock);
02153
02154 mctx = imp->mctx;
02155
02156
02157
02158
02159
02160 isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
02161 isc_mem_detach(&mctx);
02162
02163 *sdlzimp = NULL;
02164 }
02165
02166
02167 isc_result_t
02168 dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass,
02169 dns_name_t *name, dns_db_t **dbp)
02170 {
02171 isc_result_t result;
02172
02173 result = dns_sdlzcreateDBP(dlzdatabase->mctx,
02174 dlzdatabase->implementation->driverarg,
02175 dlzdatabase->dbdata, name, rdclass, dbp);
02176 return (result);
02177 }