00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "config.h"
00018
00019 #include <isc/result.h>
00020 #include <isc/util.h>
00021 #include <isc/mutex.h>
00022 #include <isc/mem.h>
00023
00024 #include <dns/db.h>
00025 #include <dns/ecdb.h>
00026 #include <dns/rdata.h>
00027 #include <dns/rdataset.h>
00028 #include <dns/rdatasetiter.h>
00029 #include <dns/rdataslab.h>
00030
00031 #define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B')
00032 #define VALID_ECDB(db) ((db) != NULL && \
00033 (db)->common.impmagic == ECDB_MAGIC)
00034
00035 #define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N')
00036 #define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC)
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 typedef struct dns_ecdb {
00047
00048 dns_db_t common;
00049 isc_mutex_t lock;
00050
00051
00052 unsigned int references;
00053 ISC_LIST(struct dns_ecdbnode) nodes;
00054 } dns_ecdb_t;
00055
00056 typedef struct dns_ecdbnode {
00057
00058 unsigned int magic;
00059 isc_mutex_t lock;
00060 dns_ecdb_t *ecdb;
00061 dns_name_t name;
00062 ISC_LINK(struct dns_ecdbnode) link;
00063
00064
00065 ISC_LIST(struct rdatasetheader) rdatasets;
00066 unsigned int references;
00067 } dns_ecdbnode_t;
00068
00069 typedef struct rdatasetheader {
00070 dns_rdatatype_t type;
00071 dns_ttl_t ttl;
00072 dns_trust_t trust;
00073 dns_rdatatype_t covers;
00074 unsigned int attributes;
00075
00076 ISC_LINK(struct rdatasetheader) link;
00077 } rdatasetheader_t;
00078
00079
00080 #define RDATASET_ATTR_NXDOMAIN 0x0010
00081 #define RDATASET_ATTR_NEGATIVE 0x0100
00082 #define NXDOMAIN(header) \
00083 (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
00084 #define NEGATIVE(header) \
00085 (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
00086
00087 static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
00088 dns_dbtype_t type,
00089 dns_rdataclass_t rdclass,
00090 unsigned int argc, char *argv[],
00091 void *driverarg, dns_db_t **dbp);
00092
00093 static void rdataset_disassociate(dns_rdataset_t *rdataset);
00094 static isc_result_t rdataset_first(dns_rdataset_t *rdataset);
00095 static isc_result_t rdataset_next(dns_rdataset_t *rdataset);
00096 static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
00097 static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
00098 static unsigned int rdataset_count(dns_rdataset_t *rdataset);
00099 static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
00100
00101 static dns_rdatasetmethods_t rdataset_methods = {
00102 rdataset_disassociate,
00103 rdataset_first,
00104 rdataset_next,
00105 rdataset_current,
00106 rdataset_clone,
00107 rdataset_count,
00108 NULL,
00109 NULL,
00110 NULL,
00111 NULL,
00112 NULL,
00113 NULL,
00114 NULL,
00115 rdataset_settrust,
00116 NULL,
00117 NULL,
00118 NULL,
00119 NULL
00120 };
00121
00122 typedef struct ecdb_rdatasetiter {
00123 dns_rdatasetiter_t common;
00124 rdatasetheader_t *current;
00125 } ecdb_rdatasetiter_t;
00126
00127 static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
00128 static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
00129 static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
00130 static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
00131 dns_rdataset_t *rdataset);
00132
00133 static dns_rdatasetitermethods_t rdatasetiter_methods = {
00134 rdatasetiter_destroy,
00135 rdatasetiter_first,
00136 rdatasetiter_next,
00137 rdatasetiter_current
00138 };
00139
00140 isc_result_t
00141 dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) {
00142 REQUIRE(mctx != NULL);
00143 REQUIRE(dbimp != NULL && *dbimp == NULL);
00144
00145 return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp));
00146 }
00147
00148 void
00149 dns_ecdb_unregister(dns_dbimplementation_t **dbimp) {
00150 REQUIRE(dbimp != NULL && *dbimp != NULL);
00151
00152 dns_db_unregister(dbimp);
00153 }
00154
00155
00156
00157
00158
00159 static void
00160 attach(dns_db_t *source, dns_db_t **targetp) {
00161 dns_ecdb_t *ecdb = (dns_ecdb_t *)source;
00162
00163 REQUIRE(VALID_ECDB(ecdb));
00164 REQUIRE(targetp != NULL && *targetp == NULL);
00165
00166 LOCK(&ecdb->lock);
00167 ecdb->references++;
00168 UNLOCK(&ecdb->lock);
00169
00170 *targetp = source;
00171 }
00172
00173 static void
00174 destroy_ecdb(dns_ecdb_t **ecdbp) {
00175 dns_ecdb_t *ecdb = *ecdbp;
00176 isc_mem_t *mctx = ecdb->common.mctx;
00177
00178 if (dns_name_dynamic(&ecdb->common.origin))
00179 dns_name_free(&ecdb->common.origin, mctx);
00180
00181 DESTROYLOCK(&ecdb->lock);
00182
00183 ecdb->common.impmagic = 0;
00184 ecdb->common.magic = 0;
00185
00186 isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb));
00187
00188 *ecdbp = NULL;
00189 }
00190
00191 static void
00192 detach(dns_db_t **dbp) {
00193 dns_ecdb_t *ecdb;
00194 isc_boolean_t need_destroy = ISC_FALSE;
00195
00196 REQUIRE(dbp != NULL);
00197 ecdb = (dns_ecdb_t *)*dbp;
00198 REQUIRE(VALID_ECDB(ecdb));
00199
00200 LOCK(&ecdb->lock);
00201 ecdb->references--;
00202 if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
00203 need_destroy = ISC_TRUE;
00204 UNLOCK(&ecdb->lock);
00205
00206 if (need_destroy)
00207 destroy_ecdb(&ecdb);
00208
00209 *dbp = NULL;
00210 }
00211
00212 static void
00213 attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
00214 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00215 dns_ecdbnode_t *node = (dns_ecdbnode_t *)source;
00216
00217 REQUIRE(VALID_ECDB(ecdb));
00218 REQUIRE(VALID_ECDBNODE(node));
00219 REQUIRE(targetp != NULL && *targetp == NULL);
00220
00221 LOCK(&node->lock);
00222 INSIST(node->references > 0);
00223 node->references++;
00224 INSIST(node->references != 0);
00225 UNLOCK(&node->lock);
00226
00227 *targetp = node;
00228 }
00229
00230 static void
00231 destroynode(dns_ecdbnode_t *node) {
00232 isc_mem_t *mctx;
00233 dns_ecdb_t *ecdb = node->ecdb;
00234 isc_boolean_t need_destroydb = ISC_FALSE;
00235 rdatasetheader_t *header;
00236
00237 mctx = ecdb->common.mctx;
00238
00239 LOCK(&ecdb->lock);
00240 ISC_LIST_UNLINK(ecdb->nodes, node, link);
00241 if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
00242 need_destroydb = ISC_TRUE;
00243 UNLOCK(&ecdb->lock);
00244
00245 dns_name_free(&node->name, mctx);
00246
00247 while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) {
00248 unsigned int headersize;
00249
00250 ISC_LIST_UNLINK(node->rdatasets, header, link);
00251 headersize =
00252 dns_rdataslab_size((unsigned char *)header,
00253 sizeof(*header));
00254 isc_mem_put(mctx, header, headersize);
00255 }
00256
00257 DESTROYLOCK(&node->lock);
00258
00259 node->magic = 0;
00260 isc_mem_put(mctx, node, sizeof(*node));
00261
00262 if (need_destroydb)
00263 destroy_ecdb(&ecdb);
00264 }
00265
00266 static void
00267 detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
00268 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00269 dns_ecdbnode_t *node;
00270 isc_boolean_t need_destroy = ISC_FALSE;
00271
00272 REQUIRE(VALID_ECDB(ecdb));
00273 REQUIRE(nodep != NULL);
00274 node = (dns_ecdbnode_t *)*nodep;
00275 REQUIRE(VALID_ECDBNODE(node));
00276
00277 UNUSED(ecdb);
00278
00279 LOCK(&node->lock);
00280 INSIST(node->references > 0);
00281 node->references--;
00282 if (node->references == 0)
00283 need_destroy = ISC_TRUE;
00284 UNLOCK(&node->lock);
00285
00286 if (need_destroy)
00287 destroynode(node);
00288
00289 *nodep = NULL;
00290 }
00291
00292 static isc_result_t
00293 find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
00294 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
00295 dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset,
00296 dns_rdataset_t *sigrdataset)
00297 {
00298 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00299
00300 REQUIRE(VALID_ECDB(ecdb));
00301
00302 UNUSED(name);
00303 UNUSED(version);
00304 UNUSED(type);
00305 UNUSED(options);
00306 UNUSED(now);
00307 UNUSED(nodep);
00308 UNUSED(foundname);
00309 UNUSED(rdataset);
00310 UNUSED(sigrdataset);
00311
00312 return (ISC_R_NOTFOUND);
00313 }
00314
00315 static isc_result_t
00316 findzonecut(dns_db_t *db, dns_name_t *name,
00317 unsigned int options, isc_stdtime_t now,
00318 dns_dbnode_t **nodep, dns_name_t *foundname,
00319 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
00320 {
00321 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00322
00323 REQUIRE(VALID_ECDB(ecdb));
00324
00325 UNUSED(name);
00326 UNUSED(options);
00327 UNUSED(now);
00328 UNUSED(nodep);
00329 UNUSED(foundname);
00330 UNUSED(rdataset);
00331 UNUSED(sigrdataset);
00332
00333 return (ISC_R_NOTFOUND);
00334 }
00335
00336 static isc_result_t
00337 findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
00338 dns_dbnode_t **nodep)
00339 {
00340 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00341 isc_mem_t *mctx;
00342 dns_ecdbnode_t *node;
00343 isc_result_t result;
00344
00345 REQUIRE(VALID_ECDB(ecdb));
00346 REQUIRE(nodep != NULL && *nodep == NULL);
00347
00348 UNUSED(name);
00349
00350 if (create != ISC_TRUE) {
00351
00352 return (ISC_R_NOTFOUND);
00353 }
00354
00355 mctx = ecdb->common.mctx;
00356 node = isc_mem_get(mctx, sizeof(*node));
00357 if (node == NULL)
00358 return (ISC_R_NOMEMORY);
00359
00360 result = isc_mutex_init(&node->lock);
00361 if (result != ISC_R_SUCCESS) {
00362 UNEXPECTED_ERROR(__FILE__, __LINE__,
00363 "isc_mutex_init() failed: %s",
00364 isc_result_totext(result));
00365 isc_mem_put(mctx, node, sizeof(*node));
00366 return (ISC_R_UNEXPECTED);
00367 }
00368
00369 dns_name_init(&node->name, NULL);
00370 result = dns_name_dup(name, mctx, &node->name);
00371 if (result != ISC_R_SUCCESS) {
00372 DESTROYLOCK(&node->lock);
00373 isc_mem_put(mctx, node, sizeof(*node));
00374 return (result);
00375 }
00376 node->ecdb= ecdb;
00377 node->references = 1;
00378 ISC_LIST_INIT(node->rdatasets);
00379
00380 ISC_LINK_INIT(node, link);
00381
00382 LOCK(&ecdb->lock);
00383 ISC_LIST_APPEND(ecdb->nodes, node, link);
00384 UNLOCK(&ecdb->lock);
00385
00386 node->magic = ECDBNODE_MAGIC;
00387
00388 *nodep = node;
00389
00390 return (ISC_R_SUCCESS);
00391 }
00392
00393 static void
00394 bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
00395 rdatasetheader_t *header, dns_rdataset_t *rdataset)
00396 {
00397 unsigned char *raw;
00398
00399
00400
00401
00402
00403 REQUIRE(!dns_rdataset_isassociated(rdataset));
00404
00405 rdataset->methods = &rdataset_methods;
00406 rdataset->rdclass = ecdb->common.rdclass;
00407 rdataset->type = header->type;
00408 rdataset->covers = header->covers;
00409 rdataset->ttl = header->ttl;
00410 rdataset->trust = header->trust;
00411 if (NXDOMAIN(header))
00412 rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
00413 if (NEGATIVE(header))
00414 rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
00415
00416 rdataset->private1 = ecdb;
00417 rdataset->private2 = node;
00418 raw = (unsigned char *)header + sizeof(*header);
00419 rdataset->private3 = raw;
00420 rdataset->count = 0;
00421
00422
00423
00424
00425 rdataset->privateuint4 = 0;
00426 rdataset->private5 = NULL;
00427
00428 INSIST(node->references > 0);
00429 node->references++;
00430 }
00431
00432 static isc_result_t
00433 addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00434 isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
00435 dns_rdataset_t *addedrdataset)
00436 {
00437 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00438 isc_region_t r;
00439 isc_result_t result = ISC_R_SUCCESS;
00440 isc_mem_t *mctx;
00441 dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
00442 rdatasetheader_t *header;
00443
00444 REQUIRE(VALID_ECDB(ecdb));
00445 REQUIRE(VALID_ECDBNODE(ecdbnode));
00446
00447 UNUSED(version);
00448 UNUSED(now);
00449 UNUSED(options);
00450
00451 mctx = ecdb->common.mctx;
00452
00453 LOCK(&ecdbnode->lock);
00454
00455
00456
00457
00458
00459 for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL;
00460 header = ISC_LIST_NEXT(header, link)) {
00461 INSIST(header->type != rdataset->type ||
00462 header->covers != rdataset->covers);
00463 }
00464
00465 result = dns_rdataslab_fromrdataset(rdataset, mctx,
00466 &r, sizeof(rdatasetheader_t));
00467 if (result != ISC_R_SUCCESS)
00468 goto unlock;
00469
00470 header = (rdatasetheader_t *)r.base;
00471 header->type = rdataset->type;
00472 header->ttl = rdataset->ttl;
00473 header->trust = rdataset->trust;
00474 header->covers = rdataset->covers;
00475 header->attributes = 0;
00476 if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
00477 header->attributes |= RDATASET_ATTR_NXDOMAIN;
00478 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
00479 header->attributes |= RDATASET_ATTR_NEGATIVE;
00480 ISC_LINK_INIT(header, link);
00481 ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
00482
00483 if (addedrdataset == NULL)
00484 goto unlock;
00485
00486 bind_rdataset(ecdb, ecdbnode, header, addedrdataset);
00487
00488 unlock:
00489 UNLOCK(&ecdbnode->lock);
00490
00491 return (result);
00492 }
00493
00494 static isc_result_t
00495 deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00496 dns_rdatatype_t type, dns_rdatatype_t covers)
00497 {
00498 UNUSED(db);
00499 UNUSED(node);
00500 UNUSED(version);
00501 UNUSED(type);
00502 UNUSED(covers);
00503
00504 return (ISC_R_NOTIMPLEMENTED);
00505 }
00506
00507 static isc_result_t
00508 createiterator(dns_db_t *db, unsigned int options,
00509 dns_dbiterator_t **iteratorp)
00510 {
00511 UNUSED(db);
00512 UNUSED(options);
00513 UNUSED(iteratorp);
00514
00515 return (ISC_R_NOTIMPLEMENTED);
00516 }
00517
00518 static isc_result_t
00519 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
00520 isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
00521 {
00522 dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
00523 dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
00524 isc_mem_t *mctx;
00525 ecdb_rdatasetiter_t *iterator;
00526
00527 REQUIRE(VALID_ECDB(ecdb));
00528 REQUIRE(VALID_ECDBNODE(ecdbnode));
00529
00530 mctx = ecdb->common.mctx;
00531
00532 iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t));
00533 if (iterator == NULL)
00534 return (ISC_R_NOMEMORY);
00535
00536 iterator->common.magic = DNS_RDATASETITER_MAGIC;
00537 iterator->common.methods = &rdatasetiter_methods;
00538 iterator->common.db = db;
00539 iterator->common.node = NULL;
00540 attachnode(db, node, &iterator->common.node);
00541 iterator->common.version = version;
00542 iterator->common.now = now;
00543
00544 *iteratorp = (dns_rdatasetiter_t *)iterator;
00545
00546 return (ISC_R_SUCCESS);
00547 }
00548
00549 static dns_dbmethods_t ecdb_methods = {
00550 attach,
00551 detach,
00552 NULL,
00553 NULL,
00554 NULL,
00555 NULL,
00556 NULL,
00557 NULL,
00558 NULL,
00559 NULL,
00560 findnode,
00561 find,
00562 findzonecut,
00563 attachnode,
00564 detachnode,
00565 NULL,
00566 NULL,
00567 createiterator,
00568 NULL,
00569 allrdatasets,
00570 addrdataset,
00571 NULL,
00572 deleterdataset,
00573 NULL,
00574 NULL,
00575 NULL,
00576 NULL,
00577 NULL,
00578 NULL,
00579 NULL,
00580 NULL,
00581 NULL,
00582 NULL,
00583 NULL,
00584 NULL,
00585 NULL,
00586 NULL,
00587 NULL,
00588 NULL,
00589 NULL,
00590 NULL,
00591 NULL,
00592 NULL
00593 };
00594
00595 static isc_result_t
00596 dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
00597 dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
00598 void *driverarg, dns_db_t **dbp)
00599 {
00600 dns_ecdb_t *ecdb;
00601 isc_result_t result;
00602
00603 REQUIRE(mctx != NULL);
00604 REQUIRE(origin == dns_rootname);
00605 REQUIRE(type == dns_dbtype_cache);
00606 REQUIRE(dbp != NULL && *dbp == NULL);
00607
00608 UNUSED(argc);
00609 UNUSED(argv);
00610 UNUSED(driverarg);
00611
00612 ecdb = isc_mem_get(mctx, sizeof(*ecdb));
00613 if (ecdb == NULL)
00614 return (ISC_R_NOMEMORY);
00615
00616 ecdb->common.attributes = DNS_DBATTR_CACHE;
00617 ecdb->common.rdclass = rdclass;
00618 ecdb->common.methods = &ecdb_methods;
00619 dns_name_init(&ecdb->common.origin, NULL);
00620 result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin);
00621 if (result != ISC_R_SUCCESS) {
00622 isc_mem_put(mctx, ecdb, sizeof(*ecdb));
00623 return (result);
00624 }
00625
00626 result = isc_mutex_init(&ecdb->lock);
00627 if (result != ISC_R_SUCCESS) {
00628 UNEXPECTED_ERROR(__FILE__, __LINE__,
00629 "isc_mutex_init() failed: %s",
00630 isc_result_totext(result));
00631 if (dns_name_dynamic(&ecdb->common.origin))
00632 dns_name_free(&ecdb->common.origin, mctx);
00633 isc_mem_put(mctx, ecdb, sizeof(*ecdb));
00634 return (ISC_R_UNEXPECTED);
00635 }
00636
00637 ecdb->references = 1;
00638 ISC_LIST_INIT(ecdb->nodes);
00639
00640 ecdb->common.mctx = NULL;
00641 isc_mem_attach(mctx, &ecdb->common.mctx);
00642 ecdb->common.impmagic = ECDB_MAGIC;
00643 ecdb->common.magic = DNS_DB_MAGIC;
00644
00645 *dbp = (dns_db_t *)ecdb;
00646
00647 return (ISC_R_SUCCESS);
00648 }
00649
00650
00651
00652
00653
00654 static void
00655 rdataset_disassociate(dns_rdataset_t *rdataset) {
00656 dns_db_t *db = rdataset->private1;
00657 dns_dbnode_t *node = rdataset->private2;
00658
00659 dns_db_detachnode(db, &node);
00660 }
00661
00662 static isc_result_t
00663 rdataset_first(dns_rdataset_t *rdataset) {
00664 unsigned char *raw = rdataset->private3;
00665 unsigned int count;
00666
00667 count = raw[0] * 256 + raw[1];
00668 if (count == 0) {
00669 rdataset->private5 = NULL;
00670 return (ISC_R_NOMORE);
00671 }
00672 #if DNS_RDATASET_FIXED
00673 raw += 2 + (4 * count);
00674 #else
00675 raw += 2;
00676 #endif
00677
00678
00679
00680
00681
00682 count--;
00683 rdataset->privateuint4 = count;
00684 rdataset->private5 = raw;
00685
00686 return (ISC_R_SUCCESS);
00687 }
00688
00689 static isc_result_t
00690 rdataset_next(dns_rdataset_t *rdataset) {
00691 unsigned int count;
00692 unsigned int length;
00693 unsigned char *raw;
00694
00695 count = rdataset->privateuint4;
00696 if (count == 0)
00697 return (ISC_R_NOMORE);
00698 count--;
00699 rdataset->privateuint4 = count;
00700 raw = rdataset->private5;
00701 length = raw[0] * 256 + raw[1];
00702 #if DNS_RDATASET_FIXED
00703 raw += length + 4;
00704 #else
00705 raw += length + 2;
00706 #endif
00707 rdataset->private5 = raw;
00708
00709 return (ISC_R_SUCCESS);
00710 }
00711
00712 static void
00713 rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
00714 unsigned char *raw = rdataset->private5;
00715 isc_region_t r;
00716 unsigned int length;
00717 unsigned int flags = 0;
00718
00719 REQUIRE(raw != NULL);
00720
00721 length = raw[0] * 256 + raw[1];
00722 #if DNS_RDATASET_FIXED
00723 raw += 4;
00724 #else
00725 raw += 2;
00726 #endif
00727 if (rdataset->type == dns_rdatatype_rrsig) {
00728 if (*raw & DNS_RDATASLAB_OFFLINE)
00729 flags |= DNS_RDATA_OFFLINE;
00730 length--;
00731 raw++;
00732 }
00733 r.length = length;
00734 r.base = raw;
00735 dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
00736 rdata->flags |= flags;
00737 }
00738
00739 static void
00740 rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
00741 dns_db_t *db = source->private1;
00742 dns_dbnode_t *node = source->private2;
00743 dns_dbnode_t *cloned_node = NULL;
00744
00745 attachnode(db, node, &cloned_node);
00746 *target = *source;
00747
00748
00749
00750
00751 target->privateuint4 = 0;
00752 target->private5 = NULL;
00753 }
00754
00755 static unsigned int
00756 rdataset_count(dns_rdataset_t *rdataset) {
00757 unsigned char *raw = rdataset->private3;
00758 unsigned int count;
00759
00760 count = raw[0] * 256 + raw[1];
00761
00762 return (count);
00763 }
00764
00765 static void
00766 rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
00767 rdatasetheader_t *header = rdataset->private3;
00768
00769 header--;
00770 header->trust = rdataset->trust = trust;
00771 }
00772
00773
00774
00775
00776
00777 static void
00778 rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
00779 isc_mem_t *mctx;
00780 union {
00781 dns_rdatasetiter_t *rdatasetiterator;
00782 ecdb_rdatasetiter_t *ecdbiterator;
00783 } u;
00784
00785 REQUIRE(iteratorp != NULL);
00786 REQUIRE(DNS_RDATASETITER_VALID(*iteratorp));
00787
00788 u.rdatasetiterator = *iteratorp;
00789
00790 mctx = u.ecdbiterator->common.db->mctx;
00791 u.ecdbiterator->common.magic = 0;
00792
00793 dns_db_detachnode(u.ecdbiterator->common.db,
00794 &u.ecdbiterator->common.node);
00795 isc_mem_put(mctx, u.ecdbiterator,
00796 sizeof(ecdb_rdatasetiter_t));
00797
00798 *iteratorp = NULL;
00799 }
00800
00801 static isc_result_t
00802 rdatasetiter_first(dns_rdatasetiter_t *iterator) {
00803 ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
00804 dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node;
00805
00806 REQUIRE(DNS_RDATASETITER_VALID(iterator));
00807
00808 if (ISC_LIST_EMPTY(ecdbnode->rdatasets))
00809 return (ISC_R_NOMORE);
00810 ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets);
00811 return (ISC_R_SUCCESS);
00812 }
00813
00814 static isc_result_t
00815 rdatasetiter_next(dns_rdatasetiter_t *iterator) {
00816 ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
00817
00818 REQUIRE(DNS_RDATASETITER_VALID(iterator));
00819
00820 ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link);
00821 if (ecdbiterator->current == NULL)
00822 return (ISC_R_NOMORE);
00823 else
00824 return (ISC_R_SUCCESS);
00825 }
00826
00827 static void
00828 rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
00829 ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
00830 dns_ecdb_t *ecdb;
00831
00832 ecdb = (dns_ecdb_t *)iterator->db;
00833 REQUIRE(VALID_ECDB(ecdb));
00834
00835 bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset);
00836 }