Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / rdataset.c
blobb57b19e0a14aca6d29aa8539089de73a7f48457b
1 /* $NetBSD: rdataset.c,v 1.8 2015/07/08 17:28:59 christos Exp $ */
3 /*
4 * Copyright (C) 2004-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id */
22 /*! \file */
24 #include <config.h>
26 #include <stdlib.h>
28 #include <isc/buffer.h>
29 #include <isc/mem.h>
30 #include <isc/random.h>
31 #include <isc/serial.h>
32 #include <isc/util.h>
34 #include <dns/name.h>
35 #include <dns/ncache.h>
36 #include <dns/rdata.h>
37 #include <dns/rdataset.h>
38 #include <dns/compress.h>
40 static const char *trustnames[] = {
41 "none",
42 "pending-additional",
43 "pending-answer",
44 "additional",
45 "glue",
46 "answer",
47 "authauthority",
48 "authanswer",
49 "secure",
50 "local" /* aka ultimate */
53 const char *
54 dns_trust_totext(dns_trust_t trust) {
55 if (trust >= sizeof(trustnames)/sizeof(*trustnames))
56 return ("bad");
57 return (trustnames[trust]);
60 void
61 dns_rdataset_init(dns_rdataset_t *rdataset) {
64 * Make 'rdataset' a valid, disassociated rdataset.
67 REQUIRE(rdataset != NULL);
69 rdataset->magic = DNS_RDATASET_MAGIC;
70 rdataset->methods = NULL;
71 ISC_LINK_INIT(rdataset, link);
72 rdataset->rdclass = 0;
73 rdataset->type = 0;
74 rdataset->ttl = 0;
75 rdataset->trust = 0;
76 rdataset->covers = 0;
77 rdataset->attributes = 0;
78 rdataset->count = ISC_UINT32_MAX;
79 rdataset->private1 = NULL;
80 rdataset->private2 = NULL;
81 rdataset->private3 = NULL;
82 rdataset->privateuint4 = 0;
83 rdataset->private5 = NULL;
84 rdataset->private6 = NULL;
85 rdataset->private7 = NULL;
86 rdataset->resign = 0;
89 void
90 dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
93 * Invalidate 'rdataset'.
96 REQUIRE(DNS_RDATASET_VALID(rdataset));
97 REQUIRE(rdataset->methods == NULL);
99 rdataset->magic = 0;
100 ISC_LINK_INIT(rdataset, link);
101 rdataset->rdclass = 0;
102 rdataset->type = 0;
103 rdataset->ttl = 0;
104 rdataset->trust = 0;
105 rdataset->covers = 0;
106 rdataset->attributes = 0;
107 rdataset->count = ISC_UINT32_MAX;
108 rdataset->private1 = NULL;
109 rdataset->private2 = NULL;
110 rdataset->private3 = NULL;
111 rdataset->privateuint4 = 0;
112 rdataset->private5 = NULL;
115 void
116 dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
119 * Disassociate 'rdataset' from its rdata, allowing it to be reused.
122 REQUIRE(DNS_RDATASET_VALID(rdataset));
123 REQUIRE(rdataset->methods != NULL);
125 (rdataset->methods->disassociate)(rdataset);
126 rdataset->methods = NULL;
127 ISC_LINK_INIT(rdataset, link);
128 rdataset->rdclass = 0;
129 rdataset->type = 0;
130 rdataset->ttl = 0;
131 rdataset->trust = 0;
132 rdataset->covers = 0;
133 rdataset->attributes = 0;
134 rdataset->count = ISC_UINT32_MAX;
135 rdataset->private1 = NULL;
136 rdataset->private2 = NULL;
137 rdataset->private3 = NULL;
138 rdataset->privateuint4 = 0;
139 rdataset->private5 = NULL;
140 rdataset->private6 = NULL;
143 isc_boolean_t
144 dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
146 * Is 'rdataset' associated?
149 REQUIRE(DNS_RDATASET_VALID(rdataset));
151 if (rdataset->methods != NULL)
152 return (ISC_TRUE);
154 return (ISC_FALSE);
157 static void
158 question_disassociate(dns_rdataset_t *rdataset) {
159 UNUSED(rdataset);
162 static isc_result_t
163 question_cursor(dns_rdataset_t *rdataset) {
164 UNUSED(rdataset);
166 return (ISC_R_NOMORE);
169 static void
170 question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
172 * This routine should never be called.
174 UNUSED(rdataset);
175 UNUSED(rdata);
177 REQUIRE(0);
180 static void
181 question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
182 *target = *source;
185 static unsigned int
186 question_count(dns_rdataset_t *rdataset) {
188 * This routine should never be called.
190 UNUSED(rdataset);
191 REQUIRE(0);
193 return (0);
196 static dns_rdatasetmethods_t question_methods = {
197 question_disassociate,
198 question_cursor,
199 question_cursor,
200 question_current,
201 question_clone,
202 question_count,
203 NULL,
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
210 NULL,
211 NULL,
212 NULL
215 void
216 dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
217 dns_rdatatype_t type)
221 * Make 'rdataset' a valid, associated, question rdataset, with a
222 * question class of 'rdclass' and type 'type'.
225 REQUIRE(DNS_RDATASET_VALID(rdataset));
226 REQUIRE(rdataset->methods == NULL);
228 rdataset->methods = &question_methods;
229 rdataset->rdclass = rdclass;
230 rdataset->type = type;
231 rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
234 unsigned int
235 dns_rdataset_count(dns_rdataset_t *rdataset) {
238 * Return the number of records in 'rdataset'.
241 REQUIRE(DNS_RDATASET_VALID(rdataset));
242 REQUIRE(rdataset->methods != NULL);
244 return ((rdataset->methods->count)(rdataset));
247 void
248 dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
251 * Make 'target' refer to the same rdataset as 'source'.
254 REQUIRE(DNS_RDATASET_VALID(source));
255 REQUIRE(source->methods != NULL);
256 REQUIRE(DNS_RDATASET_VALID(target));
257 REQUIRE(target->methods == NULL);
259 (source->methods->clone)(source, target);
262 isc_result_t
263 dns_rdataset_first(dns_rdataset_t *rdataset) {
266 * Move the rdata cursor to the first rdata in the rdataset (if any).
269 REQUIRE(DNS_RDATASET_VALID(rdataset));
270 REQUIRE(rdataset->methods != NULL);
272 return ((rdataset->methods->first)(rdataset));
275 isc_result_t
276 dns_rdataset_next(dns_rdataset_t *rdataset) {
279 * Move the rdata cursor to the next rdata in the rdataset (if any).
282 REQUIRE(DNS_RDATASET_VALID(rdataset));
283 REQUIRE(rdataset->methods != NULL);
285 return ((rdataset->methods->next)(rdataset));
288 void
289 dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
292 * Make 'rdata' refer to the current rdata.
295 REQUIRE(DNS_RDATASET_VALID(rdataset));
296 REQUIRE(rdataset->methods != NULL);
298 (rdataset->methods->current)(rdataset, rdata);
301 #define MAX_SHUFFLE 32
302 #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
303 #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
305 struct towire_sort {
306 int key;
307 dns_rdata_t *rdata;
310 static int
311 towire_compare(const void *av, const void *bv) {
312 const struct towire_sort *a = (const struct towire_sort *) av;
313 const struct towire_sort *b = (const struct towire_sort *) bv;
314 return (a->key - b->key);
317 static isc_result_t
318 towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
319 dns_compress_t *cctx, isc_buffer_t *target,
320 dns_rdatasetorderfunc_t order, const void *order_arg,
321 isc_boolean_t partial, unsigned int options,
322 unsigned int *countp, void **state)
324 dns_rdata_t rdata = DNS_RDATA_INIT;
325 isc_region_t r;
326 isc_result_t result;
327 unsigned int i, count = 0, added, choice;
328 isc_buffer_t savedbuffer, rdlen, rrbuffer;
329 unsigned int headlen;
330 isc_boolean_t question = ISC_FALSE;
331 isc_boolean_t shuffle = ISC_FALSE;
332 dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
333 struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
335 UNUSED(state);
338 * Convert 'rdataset' to wire format, compressing names as specified
339 * in cctx, and storing the result in 'target'.
342 REQUIRE(DNS_RDATASET_VALID(rdataset));
343 REQUIRE(countp != NULL);
344 REQUIRE((order == NULL) == (order_arg == NULL));
345 REQUIRE(cctx != NULL && cctx->mctx != NULL);
347 if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
348 question = ISC_TRUE;
349 count = 1;
350 result = dns_rdataset_first(rdataset);
351 INSIST(result == ISC_R_NOMORE);
352 } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
354 * This is a negative caching rdataset.
356 unsigned int ncache_opts = 0;
357 if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
358 ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
359 return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
360 countp));
361 } else {
362 count = (rdataset->methods->count)(rdataset);
363 result = dns_rdataset_first(rdataset);
364 if (result == ISC_R_NOMORE)
365 return (ISC_R_SUCCESS);
366 if (result != ISC_R_SUCCESS)
367 return (result);
371 * Do we want to shuffle this answer?
373 if (!question && count > 1 &&
374 (!WANT_FIXED(rdataset) || order != NULL) &&
375 rdataset->type != dns_rdatatype_rrsig)
376 shuffle = ISC_TRUE;
378 if (shuffle && count > MAX_SHUFFLE) {
379 shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
380 sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
381 if (shuffled == NULL || sorted == NULL)
382 shuffle = ISC_FALSE;
383 } else {
384 shuffled = shuffled_fixed;
385 sorted = sorted_fixed;
388 if (shuffle) {
390 * First we get handles to all of the rdata.
392 i = 0;
393 do {
394 INSIST(i < count);
395 dns_rdata_init(&shuffled[i]);
396 dns_rdataset_current(rdataset, &shuffled[i]);
397 i++;
398 result = dns_rdataset_next(rdataset);
399 } while (result == ISC_R_SUCCESS);
400 if (result != ISC_R_NOMORE)
401 goto cleanup;
402 INSIST(i == count);
405 * Now we shuffle.
407 if (WANT_FIXED(rdataset)) {
409 * 'Fixed' order.
411 INSIST(order != NULL);
412 for (i = 0; i < count; i++) {
413 sorted[i].key = (*order)(&shuffled[i],
414 order_arg);
415 sorted[i].rdata = &shuffled[i];
417 } else if (WANT_RANDOM(rdataset)) {
419 * 'Random' order.
421 for (i = 0; i < count; i++) {
422 isc_uint32_t val;
424 isc_random_get(&val);
425 choice = i + (val % (count - i));
426 rdata = shuffled[i];
427 shuffled[i] = shuffled[choice];
428 shuffled[choice] = rdata;
429 if (order != NULL)
430 sorted[i].key = (*order)(&shuffled[i],
431 order_arg);
432 else
433 sorted[i].key = 0; /* Unused */
434 sorted[i].rdata = &shuffled[i];
436 } else {
438 * "Cyclic" order.
440 isc_uint32_t val;
441 unsigned int j;
443 val = rdataset->count;
444 if (val == ISC_UINT32_MAX)
445 isc_random_get(&val);
446 j = val % count;
447 for (i = 0; i < count; i++) {
448 if (order != NULL)
449 sorted[i].key = (*order)(&shuffled[j],
450 order_arg);
451 else
452 sorted[i].key = 0; /* Unused */
453 sorted[i].rdata = &shuffled[j];
454 j++;
455 if (j == count)
456 j = 0; /* Wrap around. */
461 * Sorted order.
463 if (order != NULL)
464 qsort(sorted, count, sizeof(sorted[0]),
465 towire_compare);
468 savedbuffer = *target;
469 i = 0;
470 added = 0;
472 do {
474 * Copy out the name, type, class, ttl.
477 rrbuffer = *target;
478 dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
479 result = dns_name_towire(owner_name, cctx, target);
480 if (result != ISC_R_SUCCESS)
481 goto rollback;
482 headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
483 if (!question)
484 headlen += sizeof(dns_ttl_t)
485 + 2; /* XXX 2 for rdata len */
486 isc_buffer_availableregion(target, &r);
487 if (r.length < headlen) {
488 result = ISC_R_NOSPACE;
489 goto rollback;
491 isc_buffer_putuint16(target, rdataset->type);
492 isc_buffer_putuint16(target, rdataset->rdclass);
493 if (!question) {
494 isc_buffer_putuint32(target, rdataset->ttl);
497 * Save space for rdlen.
499 rdlen = *target;
500 isc_buffer_add(target, 2);
503 * Copy out the rdata
505 if (shuffle)
506 rdata = *(sorted[i].rdata);
507 else {
508 dns_rdata_reset(&rdata);
509 dns_rdataset_current(rdataset, &rdata);
511 result = dns_rdata_towire(&rdata, cctx, target);
512 if (result != ISC_R_SUCCESS)
513 goto rollback;
514 INSIST((target->used >= rdlen.used + 2) &&
515 (target->used - rdlen.used - 2 < 65536));
516 isc_buffer_putuint16(&rdlen,
517 (isc_uint16_t)(target->used -
518 rdlen.used - 2));
519 added++;
522 if (shuffle) {
523 i++;
524 if (i == count)
525 result = ISC_R_NOMORE;
526 else
527 result = ISC_R_SUCCESS;
528 } else {
529 result = dns_rdataset_next(rdataset);
531 } while (result == ISC_R_SUCCESS);
533 if (result != ISC_R_NOMORE)
534 goto rollback;
536 *countp += count;
538 result = ISC_R_SUCCESS;
539 goto cleanup;
541 rollback:
542 if (partial && result == ISC_R_NOSPACE) {
543 INSIST(rrbuffer.used < 65536);
544 dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
545 *countp += added;
546 *target = rrbuffer;
547 goto cleanup;
549 INSIST(savedbuffer.used < 65536);
550 dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
551 *countp = 0;
552 *target = savedbuffer;
554 cleanup:
555 if (sorted != NULL && sorted != sorted_fixed)
556 isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
557 if (shuffled != NULL && shuffled != shuffled_fixed)
558 isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
559 return (result);
562 isc_result_t
563 dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
564 const dns_name_t *owner_name,
565 dns_compress_t *cctx,
566 isc_buffer_t *target,
567 dns_rdatasetorderfunc_t order,
568 const void *order_arg,
569 unsigned int options,
570 unsigned int *countp)
572 return (towiresorted(rdataset, owner_name, cctx, target,
573 order, order_arg, ISC_FALSE, options,
574 countp, NULL));
577 isc_result_t
578 dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
579 const dns_name_t *owner_name,
580 dns_compress_t *cctx,
581 isc_buffer_t *target,
582 dns_rdatasetorderfunc_t order,
583 const void *order_arg,
584 unsigned int options,
585 unsigned int *countp,
586 void **state)
588 REQUIRE(state == NULL); /* XXX remove when implemented */
589 return (towiresorted(rdataset, owner_name, cctx, target,
590 order, order_arg, ISC_TRUE, options,
591 countp, state));
594 isc_result_t
595 dns_rdataset_towire(dns_rdataset_t *rdataset,
596 dns_name_t *owner_name,
597 dns_compress_t *cctx,
598 isc_buffer_t *target,
599 unsigned int options,
600 unsigned int *countp)
602 return (towiresorted(rdataset, owner_name, cctx, target,
603 NULL, NULL, ISC_FALSE, options, countp, NULL));
606 isc_result_t
607 dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
608 dns_additionaldatafunc_t add, void *arg)
610 dns_rdata_t rdata = DNS_RDATA_INIT;
611 isc_result_t result;
614 * For each rdata in rdataset, call 'add' for each name and type in the
615 * rdata which is subject to additional section processing.
618 REQUIRE(DNS_RDATASET_VALID(rdataset));
619 REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
621 result = dns_rdataset_first(rdataset);
622 if (result != ISC_R_SUCCESS)
623 return (result);
625 do {
626 dns_rdataset_current(rdataset, &rdata);
627 result = dns_rdata_additionaldata(&rdata, add, arg);
628 if (result == ISC_R_SUCCESS)
629 result = dns_rdataset_next(rdataset);
630 dns_rdata_reset(&rdata);
631 } while (result == ISC_R_SUCCESS);
633 if (result != ISC_R_NOMORE)
634 return (result);
636 return (ISC_R_SUCCESS);
639 isc_result_t
640 dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
642 REQUIRE(DNS_RDATASET_VALID(rdataset));
643 REQUIRE(rdataset->methods != NULL);
644 if (rdataset->methods->addnoqname == NULL)
645 return (ISC_R_NOTIMPLEMENTED);
646 return((rdataset->methods->addnoqname)(rdataset, name));
649 isc_result_t
650 dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
651 dns_rdataset_t *neg, dns_rdataset_t *negsig)
653 REQUIRE(DNS_RDATASET_VALID(rdataset));
654 REQUIRE(rdataset->methods != NULL);
656 if (rdataset->methods->getnoqname == NULL)
657 return (ISC_R_NOTIMPLEMENTED);
658 return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
661 isc_result_t
662 dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
664 REQUIRE(DNS_RDATASET_VALID(rdataset));
665 REQUIRE(rdataset->methods != NULL);
666 if (rdataset->methods->addclosest == NULL)
667 return (ISC_R_NOTIMPLEMENTED);
668 return((rdataset->methods->addclosest)(rdataset, name));
671 isc_result_t
672 dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
673 dns_rdataset_t *neg, dns_rdataset_t *negsig)
675 REQUIRE(DNS_RDATASET_VALID(rdataset));
676 REQUIRE(rdataset->methods != NULL);
678 if (rdataset->methods->getclosest == NULL)
679 return (ISC_R_NOTIMPLEMENTED);
680 return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
684 * Additional cache stuff
686 isc_result_t
687 dns_rdataset_getadditional(dns_rdataset_t *rdataset,
688 dns_rdatasetadditional_t type,
689 dns_rdatatype_t qtype,
690 dns_acache_t *acache,
691 dns_zone_t **zonep,
692 dns_db_t **dbp,
693 dns_dbversion_t **versionp,
694 dns_dbnode_t **nodep,
695 dns_name_t *fname,
696 dns_message_t *msg,
697 isc_stdtime_t now)
699 REQUIRE(DNS_RDATASET_VALID(rdataset));
700 REQUIRE(rdataset->methods != NULL);
701 REQUIRE(zonep == NULL || *zonep == NULL);
702 REQUIRE(dbp != NULL && *dbp == NULL);
703 REQUIRE(versionp != NULL && *versionp == NULL);
704 REQUIRE(nodep != NULL && *nodep == NULL);
705 REQUIRE(fname != NULL);
706 REQUIRE(msg != NULL);
708 if (acache != NULL && rdataset->methods->getadditional != NULL) {
709 return ((rdataset->methods->getadditional)(rdataset, type,
710 qtype, acache,
711 zonep, dbp,
712 versionp, nodep,
713 fname, msg, now));
716 return (ISC_R_FAILURE);
719 isc_result_t
720 dns_rdataset_setadditional(dns_rdataset_t *rdataset,
721 dns_rdatasetadditional_t type,
722 dns_rdatatype_t qtype,
723 dns_acache_t *acache,
724 dns_zone_t *zone,
725 dns_db_t *db,
726 dns_dbversion_t *version,
727 dns_dbnode_t *node,
728 dns_name_t *fname)
730 REQUIRE(DNS_RDATASET_VALID(rdataset));
731 REQUIRE(rdataset->methods != NULL);
733 if (acache != NULL && rdataset->methods->setadditional != NULL) {
734 return ((rdataset->methods->setadditional)(rdataset, type,
735 qtype, acache, zone,
736 db, version,
737 node, fname));
740 return (ISC_R_FAILURE);
743 isc_result_t
744 dns_rdataset_putadditional(dns_acache_t *acache,
745 dns_rdataset_t *rdataset,
746 dns_rdatasetadditional_t type,
747 dns_rdatatype_t qtype)
749 REQUIRE(DNS_RDATASET_VALID(rdataset));
750 REQUIRE(rdataset->methods != NULL);
752 if (acache != NULL && rdataset->methods->putadditional != NULL) {
753 return ((rdataset->methods->putadditional)(acache, rdataset,
754 type, qtype));
757 return (ISC_R_FAILURE);
760 void
761 dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
762 REQUIRE(DNS_RDATASET_VALID(rdataset));
763 REQUIRE(rdataset->methods != NULL);
765 if (rdataset->methods->settrust != NULL)
766 (rdataset->methods->settrust)(rdataset, trust);
767 else
768 rdataset->trust = trust;
771 void
772 dns_rdataset_expire(dns_rdataset_t *rdataset) {
773 REQUIRE(DNS_RDATASET_VALID(rdataset));
774 REQUIRE(rdataset->methods != NULL);
776 if (rdataset->methods->expire != NULL)
777 (rdataset->methods->expire)(rdataset);
780 void
781 dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
782 REQUIRE(DNS_RDATASET_VALID(rdataset));
783 REQUIRE(rdataset->methods != NULL);
785 if (rdataset->methods->clearprefetch != NULL)
786 (rdataset->methods->clearprefetch)(rdataset);
789 void
790 dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
791 dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
792 isc_boolean_t acceptexpired)
794 isc_uint32_t ttl = 0;
796 REQUIRE(DNS_RDATASET_VALID(rdataset));
797 REQUIRE(DNS_RDATASET_VALID(sigrdataset));
798 REQUIRE(rrsig != NULL);
801 * If we accept expired RRsets keep them for no more than 120 seconds.
803 if (acceptexpired &&
804 (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
805 isc_serial_le(rrsig->timeexpire, now)))
806 ttl = 120;
807 else if (isc_serial_ge(rrsig->timeexpire, now))
808 ttl = rrsig->timeexpire - now;
810 ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
811 ISC_MIN(rrsig->originalttl, ttl));
812 rdataset->ttl = ttl;
813 sigrdataset->ttl = ttl;