00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <stdlib.h>
00025
00026 #include <isc/buffer.h>
00027 #include <isc/mem.h>
00028 #include <isc/random.h>
00029 #include <isc/serial.h>
00030 #include <isc/util.h>
00031
00032 #include <dns/compress.h>
00033 #include <dns/fixedname.h>
00034 #include <dns/name.h>
00035 #include <dns/ncache.h>
00036 #include <dns/rdata.h>
00037 #include <dns/rdataset.h>
00038
00039 static const char *trustnames[] = {
00040 "none",
00041 "pending-additional",
00042 "pending-answer",
00043 "additional",
00044 "glue",
00045 "answer",
00046 "authauthority",
00047 "authanswer",
00048 "secure",
00049 "local"
00050 };
00051
00052 const char *
00053 dns_trust_totext(dns_trust_t trust) {
00054 if (trust >= sizeof(trustnames)/sizeof(*trustnames))
00055 return ("bad");
00056 return (trustnames[trust]);
00057 }
00058
00059 void
00060 dns_rdataset_init(dns_rdataset_t *rdataset) {
00061
00062
00063
00064
00065
00066 REQUIRE(rdataset != NULL);
00067
00068 rdataset->magic = DNS_RDATASET_MAGIC;
00069 rdataset->methods = NULL;
00070 ISC_LINK_INIT(rdataset, link);
00071 rdataset->rdclass = 0;
00072 rdataset->type = 0;
00073 rdataset->ttl = 0;
00074 rdataset->trust = 0;
00075 rdataset->covers = 0;
00076 rdataset->attributes = 0;
00077 rdataset->count = ISC_UINT32_MAX;
00078 rdataset->private1 = NULL;
00079 rdataset->private2 = NULL;
00080 rdataset->private3 = NULL;
00081 rdataset->privateuint4 = 0;
00082 rdataset->private5 = NULL;
00083 rdataset->private6 = NULL;
00084 rdataset->private7 = NULL;
00085 rdataset->resign = 0;
00086 }
00087
00088 void
00089 dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
00090
00091
00092
00093
00094
00095 REQUIRE(DNS_RDATASET_VALID(rdataset));
00096 REQUIRE(rdataset->methods == NULL);
00097
00098 rdataset->magic = 0;
00099 ISC_LINK_INIT(rdataset, link);
00100 rdataset->rdclass = 0;
00101 rdataset->type = 0;
00102 rdataset->ttl = 0;
00103 rdataset->trust = 0;
00104 rdataset->covers = 0;
00105 rdataset->attributes = 0;
00106 rdataset->count = ISC_UINT32_MAX;
00107 rdataset->private1 = NULL;
00108 rdataset->private2 = NULL;
00109 rdataset->private3 = NULL;
00110 rdataset->privateuint4 = 0;
00111 rdataset->private5 = NULL;
00112 }
00113
00114 void
00115 dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
00116
00117
00118
00119
00120
00121 REQUIRE(DNS_RDATASET_VALID(rdataset));
00122 REQUIRE(rdataset->methods != NULL);
00123
00124 (rdataset->methods->disassociate)(rdataset);
00125 rdataset->methods = NULL;
00126 ISC_LINK_INIT(rdataset, link);
00127 rdataset->rdclass = 0;
00128 rdataset->type = 0;
00129 rdataset->ttl = 0;
00130 rdataset->trust = 0;
00131 rdataset->covers = 0;
00132 rdataset->attributes = 0;
00133 rdataset->count = ISC_UINT32_MAX;
00134 rdataset->private1 = NULL;
00135 rdataset->private2 = NULL;
00136 rdataset->private3 = NULL;
00137 rdataset->privateuint4 = 0;
00138 rdataset->private5 = NULL;
00139 rdataset->private6 = NULL;
00140 }
00141
00142 isc_boolean_t
00143 dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
00144
00145
00146
00147
00148 REQUIRE(DNS_RDATASET_VALID(rdataset));
00149
00150 if (rdataset->methods != NULL)
00151 return (ISC_TRUE);
00152
00153 return (ISC_FALSE);
00154 }
00155
00156 static void
00157 question_disassociate(dns_rdataset_t *rdataset) {
00158 UNUSED(rdataset);
00159 }
00160
00161 static isc_result_t
00162 question_cursor(dns_rdataset_t *rdataset) {
00163 UNUSED(rdataset);
00164
00165 return (ISC_R_NOMORE);
00166 }
00167
00168 static void
00169 question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
00170
00171
00172
00173 UNUSED(rdataset);
00174 UNUSED(rdata);
00175
00176 REQUIRE(0);
00177 }
00178
00179 static void
00180 question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
00181 *target = *source;
00182 }
00183
00184 static unsigned int
00185 question_count(dns_rdataset_t *rdataset) {
00186
00187
00188
00189 UNUSED(rdataset);
00190 REQUIRE(0);
00191
00192 return (0);
00193 }
00194
00195 static dns_rdatasetmethods_t question_methods = {
00196 question_disassociate,
00197 question_cursor,
00198 question_cursor,
00199 question_current,
00200 question_clone,
00201 question_count,
00202 NULL,
00203 NULL,
00204 NULL,
00205 NULL,
00206 NULL,
00207 NULL,
00208 NULL,
00209 NULL,
00210 NULL,
00211 NULL,
00212 NULL,
00213 NULL
00214 };
00215
00216 void
00217 dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
00218 dns_rdatatype_t type)
00219 {
00220
00221
00222
00223
00224
00225
00226 REQUIRE(DNS_RDATASET_VALID(rdataset));
00227 REQUIRE(rdataset->methods == NULL);
00228
00229 rdataset->methods = &question_methods;
00230 rdataset->rdclass = rdclass;
00231 rdataset->type = type;
00232 rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
00233 }
00234
00235 unsigned int
00236 dns_rdataset_count(dns_rdataset_t *rdataset) {
00237
00238
00239
00240
00241
00242 REQUIRE(DNS_RDATASET_VALID(rdataset));
00243 REQUIRE(rdataset->methods != NULL);
00244
00245 return ((rdataset->methods->count)(rdataset));
00246 }
00247
00248 void
00249 dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
00250
00251
00252
00253
00254
00255 REQUIRE(DNS_RDATASET_VALID(source));
00256 REQUIRE(source->methods != NULL);
00257 REQUIRE(DNS_RDATASET_VALID(target));
00258 REQUIRE(target->methods == NULL);
00259
00260 (source->methods->clone)(source, target);
00261 }
00262
00263 isc_result_t
00264 dns_rdataset_first(dns_rdataset_t *rdataset) {
00265
00266
00267
00268
00269
00270 REQUIRE(DNS_RDATASET_VALID(rdataset));
00271 REQUIRE(rdataset->methods != NULL);
00272
00273 return ((rdataset->methods->first)(rdataset));
00274 }
00275
00276 isc_result_t
00277 dns_rdataset_next(dns_rdataset_t *rdataset) {
00278
00279
00280
00281
00282
00283 REQUIRE(DNS_RDATASET_VALID(rdataset));
00284 REQUIRE(rdataset->methods != NULL);
00285
00286 return ((rdataset->methods->next)(rdataset));
00287 }
00288
00289 void
00290 dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
00291
00292
00293
00294
00295
00296 REQUIRE(DNS_RDATASET_VALID(rdataset));
00297 REQUIRE(rdataset->methods != NULL);
00298
00299 (rdataset->methods->current)(rdataset, rdata);
00300 }
00301
00302 #define MAX_SHUFFLE 32
00303 #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
00304 #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
00305
00306 struct towire_sort {
00307 int key;
00308 dns_rdata_t *rdata;
00309 };
00310
00311 static int
00312 towire_compare(const void *av, const void *bv) {
00313 const struct towire_sort *a = (const struct towire_sort *) av;
00314 const struct towire_sort *b = (const struct towire_sort *) bv;
00315 return (a->key - b->key);
00316 }
00317
00318 static isc_result_t
00319 towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
00320 dns_compress_t *cctx, isc_buffer_t *target,
00321 dns_rdatasetorderfunc_t order, const void *order_arg,
00322 isc_boolean_t partial, unsigned int options,
00323 unsigned int *countp, void **state)
00324 {
00325 dns_rdata_t rdata = DNS_RDATA_INIT;
00326 isc_region_t r;
00327 isc_result_t result;
00328 unsigned int i, count = 0, added, choice;
00329 isc_buffer_t savedbuffer, rdlen, rrbuffer;
00330 unsigned int headlen;
00331 isc_boolean_t question = ISC_FALSE;
00332 isc_boolean_t shuffle = ISC_FALSE;
00333 dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
00334 struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
00335 dns_fixedname_t fixed;
00336 dns_name_t *name;
00337
00338 UNUSED(state);
00339
00340
00341
00342
00343
00344
00345 REQUIRE(DNS_RDATASET_VALID(rdataset));
00346 REQUIRE(countp != NULL);
00347 REQUIRE((order == NULL) == (order_arg == NULL));
00348 REQUIRE(cctx != NULL && cctx->mctx != NULL);
00349
00350 if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
00351 question = ISC_TRUE;
00352 count = 1;
00353 result = dns_rdataset_first(rdataset);
00354 INSIST(result == ISC_R_NOMORE);
00355 } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
00356
00357
00358
00359 unsigned int ncache_opts = 0;
00360 if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
00361 ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
00362 return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
00363 countp));
00364 } else {
00365 count = (rdataset->methods->count)(rdataset);
00366 result = dns_rdataset_first(rdataset);
00367 if (result == ISC_R_NOMORE)
00368 return (ISC_R_SUCCESS);
00369 if (result != ISC_R_SUCCESS)
00370 return (result);
00371 }
00372
00373
00374
00375
00376 if (!question && count > 1 &&
00377 (!WANT_FIXED(rdataset) || order != NULL) &&
00378 rdataset->type != dns_rdatatype_rrsig)
00379 shuffle = ISC_TRUE;
00380
00381 if (shuffle && count > MAX_SHUFFLE) {
00382 shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
00383 sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
00384 if (shuffled == NULL || sorted == NULL)
00385 shuffle = ISC_FALSE;
00386 } else {
00387 shuffled = shuffled_fixed;
00388 sorted = sorted_fixed;
00389 }
00390
00391 if (shuffle) {
00392
00393
00394
00395 i = 0;
00396 do {
00397 INSIST(i < count);
00398 dns_rdata_init(&shuffled[i]);
00399 dns_rdataset_current(rdataset, &shuffled[i]);
00400 i++;
00401 result = dns_rdataset_next(rdataset);
00402 } while (result == ISC_R_SUCCESS);
00403 if (result != ISC_R_NOMORE)
00404 goto cleanup;
00405 INSIST(i == count);
00406
00407
00408
00409
00410 if (WANT_FIXED(rdataset)) {
00411
00412
00413
00414 INSIST(order != NULL);
00415 for (i = 0; i < count; i++) {
00416 sorted[i].key = (*order)(&shuffled[i],
00417 order_arg);
00418 sorted[i].rdata = &shuffled[i];
00419 }
00420 } else if (WANT_RANDOM(rdataset)) {
00421
00422
00423
00424 for (i = 0; i < count; i++) {
00425 isc_uint32_t val;
00426
00427 isc_random_get(&val);
00428 choice = i + (val % (count - i));
00429 rdata = shuffled[i];
00430 shuffled[i] = shuffled[choice];
00431 shuffled[choice] = rdata;
00432 if (order != NULL)
00433 sorted[i].key = (*order)(&shuffled[i],
00434 order_arg);
00435 else
00436 sorted[i].key = 0;
00437 sorted[i].rdata = &shuffled[i];
00438 }
00439 } else {
00440
00441
00442
00443 isc_uint32_t val;
00444 unsigned int j;
00445
00446 val = rdataset->count;
00447 if (val == ISC_UINT32_MAX)
00448 isc_random_get(&val);
00449 j = val % count;
00450 for (i = 0; i < count; i++) {
00451 if (order != NULL)
00452 sorted[i].key = (*order)(&shuffled[j],
00453 order_arg);
00454 else
00455 sorted[i].key = 0;
00456 sorted[i].rdata = &shuffled[j];
00457 j++;
00458 if (j == count)
00459 j = 0;
00460 }
00461 }
00462
00463
00464
00465
00466 if (order != NULL)
00467 qsort(sorted, count, sizeof(sorted[0]),
00468 towire_compare);
00469 }
00470
00471 savedbuffer = *target;
00472 i = 0;
00473 added = 0;
00474
00475 dns_fixedname_init(&fixed);
00476 name = dns_fixedname_name(&fixed);
00477 dns_name_copy(owner_name, name, NULL);
00478 dns_rdataset_getownercase(rdataset, name);
00479
00480 do {
00481
00482
00483
00484
00485 rrbuffer = *target;
00486 dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
00487 result = dns_name_towire(name, cctx, target);
00488 if (result != ISC_R_SUCCESS)
00489 goto rollback;
00490 headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
00491 if (!question)
00492 headlen += sizeof(dns_ttl_t)
00493 + 2;
00494 isc_buffer_availableregion(target, &r);
00495 if (r.length < headlen) {
00496 result = ISC_R_NOSPACE;
00497 goto rollback;
00498 }
00499 isc_buffer_putuint16(target, rdataset->type);
00500 isc_buffer_putuint16(target, rdataset->rdclass);
00501 if (!question) {
00502 isc_buffer_putuint32(target, rdataset->ttl);
00503
00504
00505
00506
00507 rdlen = *target;
00508 isc_buffer_add(target, 2);
00509
00510
00511
00512
00513 if (shuffle)
00514 rdata = *(sorted[i].rdata);
00515 else {
00516 dns_rdata_reset(&rdata);
00517 dns_rdataset_current(rdataset, &rdata);
00518 }
00519 result = dns_rdata_towire(&rdata, cctx, target);
00520 if (result != ISC_R_SUCCESS)
00521 goto rollback;
00522 INSIST((target->used >= rdlen.used + 2) &&
00523 (target->used - rdlen.used - 2 < 65536));
00524 isc_buffer_putuint16(&rdlen,
00525 (isc_uint16_t)(target->used -
00526 rdlen.used - 2));
00527 added++;
00528 }
00529
00530 if (shuffle) {
00531 i++;
00532 if (i == count)
00533 result = ISC_R_NOMORE;
00534 else
00535 result = ISC_R_SUCCESS;
00536 } else {
00537 result = dns_rdataset_next(rdataset);
00538 }
00539 } while (result == ISC_R_SUCCESS);
00540
00541 if (result != ISC_R_NOMORE)
00542 goto rollback;
00543
00544 *countp += count;
00545
00546 result = ISC_R_SUCCESS;
00547 goto cleanup;
00548
00549 rollback:
00550 if (partial && result == ISC_R_NOSPACE) {
00551 INSIST(rrbuffer.used < 65536);
00552 dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
00553 *countp += added;
00554 *target = rrbuffer;
00555 goto cleanup;
00556 }
00557 INSIST(savedbuffer.used < 65536);
00558 dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
00559 *countp = 0;
00560 *target = savedbuffer;
00561
00562 cleanup:
00563 if (sorted != NULL && sorted != sorted_fixed)
00564 isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
00565 if (shuffled != NULL && shuffled != shuffled_fixed)
00566 isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
00567 return (result);
00568 }
00569
00570 isc_result_t
00571 dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
00572 const dns_name_t *owner_name,
00573 dns_compress_t *cctx,
00574 isc_buffer_t *target,
00575 dns_rdatasetorderfunc_t order,
00576 const void *order_arg,
00577 unsigned int options,
00578 unsigned int *countp)
00579 {
00580 return (towiresorted(rdataset, owner_name, cctx, target,
00581 order, order_arg, ISC_FALSE, options,
00582 countp, NULL));
00583 }
00584
00585 isc_result_t
00586 dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
00587 const dns_name_t *owner_name,
00588 dns_compress_t *cctx,
00589 isc_buffer_t *target,
00590 dns_rdatasetorderfunc_t order,
00591 const void *order_arg,
00592 unsigned int options,
00593 unsigned int *countp,
00594 void **state)
00595 {
00596 REQUIRE(state == NULL);
00597 return (towiresorted(rdataset, owner_name, cctx, target,
00598 order, order_arg, ISC_TRUE, options,
00599 countp, state));
00600 }
00601
00602 isc_result_t
00603 dns_rdataset_towire(dns_rdataset_t *rdataset,
00604 dns_name_t *owner_name,
00605 dns_compress_t *cctx,
00606 isc_buffer_t *target,
00607 unsigned int options,
00608 unsigned int *countp)
00609 {
00610 return (towiresorted(rdataset, owner_name, cctx, target,
00611 NULL, NULL, ISC_FALSE, options, countp, NULL));
00612 }
00613
00614 isc_result_t
00615 dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
00616 dns_additionaldatafunc_t add, void *arg)
00617 {
00618 dns_rdata_t rdata = DNS_RDATA_INIT;
00619 isc_result_t result;
00620
00621
00622
00623
00624
00625
00626 REQUIRE(DNS_RDATASET_VALID(rdataset));
00627 REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
00628
00629 result = dns_rdataset_first(rdataset);
00630 if (result != ISC_R_SUCCESS)
00631 return (result);
00632
00633 do {
00634 dns_rdataset_current(rdataset, &rdata);
00635 result = dns_rdata_additionaldata(&rdata, add, arg);
00636 if (result == ISC_R_SUCCESS)
00637 result = dns_rdataset_next(rdataset);
00638 dns_rdata_reset(&rdata);
00639 } while (result == ISC_R_SUCCESS);
00640
00641 if (result != ISC_R_NOMORE)
00642 return (result);
00643
00644 return (ISC_R_SUCCESS);
00645 }
00646
00647 isc_result_t
00648 dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
00649
00650 REQUIRE(DNS_RDATASET_VALID(rdataset));
00651 REQUIRE(rdataset->methods != NULL);
00652 if (rdataset->methods->addnoqname == NULL)
00653 return (ISC_R_NOTIMPLEMENTED);
00654 return((rdataset->methods->addnoqname)(rdataset, name));
00655 }
00656
00657 isc_result_t
00658 dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
00659 dns_rdataset_t *neg, dns_rdataset_t *negsig)
00660 {
00661 REQUIRE(DNS_RDATASET_VALID(rdataset));
00662 REQUIRE(rdataset->methods != NULL);
00663
00664 if (rdataset->methods->getnoqname == NULL)
00665 return (ISC_R_NOTIMPLEMENTED);
00666 return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
00667 }
00668
00669 isc_result_t
00670 dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
00671
00672 REQUIRE(DNS_RDATASET_VALID(rdataset));
00673 REQUIRE(rdataset->methods != NULL);
00674 if (rdataset->methods->addclosest == NULL)
00675 return (ISC_R_NOTIMPLEMENTED);
00676 return((rdataset->methods->addclosest)(rdataset, name));
00677 }
00678
00679 isc_result_t
00680 dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
00681 dns_rdataset_t *neg, dns_rdataset_t *negsig)
00682 {
00683 REQUIRE(DNS_RDATASET_VALID(rdataset));
00684 REQUIRE(rdataset->methods != NULL);
00685
00686 if (rdataset->methods->getclosest == NULL)
00687 return (ISC_R_NOTIMPLEMENTED);
00688 return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
00689 }
00690
00691
00692
00693
00694 isc_result_t
00695 dns_rdataset_getadditional(dns_rdataset_t *rdataset,
00696 dns_rdatasetadditional_t type,
00697 dns_rdatatype_t qtype,
00698 dns_acache_t *acache,
00699 dns_zone_t **zonep,
00700 dns_db_t **dbp,
00701 dns_dbversion_t **versionp,
00702 dns_dbnode_t **nodep,
00703 dns_name_t *fname,
00704 dns_message_t *msg,
00705 isc_stdtime_t now)
00706 {
00707 REQUIRE(DNS_RDATASET_VALID(rdataset));
00708 REQUIRE(rdataset->methods != NULL);
00709 REQUIRE(zonep == NULL || *zonep == NULL);
00710 REQUIRE(dbp != NULL && *dbp == NULL);
00711 REQUIRE(versionp != NULL && *versionp == NULL);
00712 REQUIRE(nodep != NULL && *nodep == NULL);
00713 REQUIRE(fname != NULL);
00714 REQUIRE(msg != NULL);
00715
00716 if (acache != NULL && rdataset->methods->getadditional != NULL) {
00717 return ((rdataset->methods->getadditional)(rdataset, type,
00718 qtype, acache,
00719 zonep, dbp,
00720 versionp, nodep,
00721 fname, msg, now));
00722 }
00723
00724 return (ISC_R_FAILURE);
00725 }
00726
00727 isc_result_t
00728 dns_rdataset_setadditional(dns_rdataset_t *rdataset,
00729 dns_rdatasetadditional_t type,
00730 dns_rdatatype_t qtype,
00731 dns_acache_t *acache,
00732 dns_zone_t *zone,
00733 dns_db_t *db,
00734 dns_dbversion_t *version,
00735 dns_dbnode_t *node,
00736 dns_name_t *fname)
00737 {
00738 REQUIRE(DNS_RDATASET_VALID(rdataset));
00739 REQUIRE(rdataset->methods != NULL);
00740
00741 if (acache != NULL && rdataset->methods->setadditional != NULL) {
00742 return ((rdataset->methods->setadditional)(rdataset, type,
00743 qtype, acache, zone,
00744 db, version,
00745 node, fname));
00746 }
00747
00748 return (ISC_R_FAILURE);
00749 }
00750
00751 isc_result_t
00752 dns_rdataset_putadditional(dns_acache_t *acache,
00753 dns_rdataset_t *rdataset,
00754 dns_rdatasetadditional_t type,
00755 dns_rdatatype_t qtype)
00756 {
00757 REQUIRE(DNS_RDATASET_VALID(rdataset));
00758 REQUIRE(rdataset->methods != NULL);
00759
00760 if (acache != NULL && rdataset->methods->putadditional != NULL) {
00761 return ((rdataset->methods->putadditional)(acache, rdataset,
00762 type, qtype));
00763 }
00764
00765 return (ISC_R_FAILURE);
00766 }
00767
00768 void
00769 dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
00770 REQUIRE(DNS_RDATASET_VALID(rdataset));
00771 REQUIRE(rdataset->methods != NULL);
00772
00773 if (rdataset->methods->settrust != NULL)
00774 (rdataset->methods->settrust)(rdataset, trust);
00775 else
00776 rdataset->trust = trust;
00777 }
00778
00779 void
00780 dns_rdataset_expire(dns_rdataset_t *rdataset) {
00781 REQUIRE(DNS_RDATASET_VALID(rdataset));
00782 REQUIRE(rdataset->methods != NULL);
00783
00784 if (rdataset->methods->expire != NULL)
00785 (rdataset->methods->expire)(rdataset);
00786 }
00787
00788 void
00789 dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
00790 REQUIRE(DNS_RDATASET_VALID(rdataset));
00791 REQUIRE(rdataset->methods != NULL);
00792
00793 if (rdataset->methods->clearprefetch != NULL)
00794 (rdataset->methods->clearprefetch)(rdataset);
00795 }
00796
00797 void
00798 dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
00799 REQUIRE(DNS_RDATASET_VALID(rdataset));
00800 REQUIRE(rdataset->methods != NULL);
00801
00802 if (rdataset->methods->setownercase != NULL)
00803 (rdataset->methods->setownercase)(rdataset, name);
00804 }
00805
00806 void
00807 dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
00808 REQUIRE(DNS_RDATASET_VALID(rdataset));
00809 REQUIRE(rdataset->methods != NULL);
00810
00811 if (rdataset->methods->getownercase != NULL)
00812 (rdataset->methods->getownercase)(rdataset, name);
00813 }
00814
00815 void
00816 dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
00817 dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
00818 isc_boolean_t acceptexpired)
00819 {
00820 isc_uint32_t ttl = 0;
00821
00822 REQUIRE(DNS_RDATASET_VALID(rdataset));
00823 REQUIRE(DNS_RDATASET_VALID(sigrdataset));
00824 REQUIRE(rrsig != NULL);
00825
00826
00827
00828
00829 if (acceptexpired &&
00830 (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
00831 isc_serial_le(rrsig->timeexpire, now)))
00832 ttl = 120;
00833 else if (isc_serial_ge(rrsig->timeexpire, now))
00834 ttl = rrsig->timeexpire - now;
00835
00836 ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
00837 ISC_MIN(rrsig->originalttl, ttl));
00838 rdataset->ttl = ttl;
00839 sigrdataset->ttl = ttl;
00840 }