Annotation of src/external/mpl/bind/dist/lib/dns/rdataset.c, Revision 1.1.1.1
1.1 christos 1: /* $NetBSD$ */
2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
8: * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14: /*! \file */
15:
16: #include <config.h>
17:
18: #include <stdlib.h>
19:
20: #include <isc/buffer.h>
21: #include <isc/mem.h>
22: #include <isc/random.h>
23: #include <isc/serial.h>
24: #include <isc/util.h>
25:
26: #include <dns/compress.h>
27: #include <dns/fixedname.h>
28: #include <dns/name.h>
29: #include <dns/ncache.h>
30: #include <dns/rdata.h>
31: #include <dns/rdataset.h>
32:
33: static const char *trustnames[] = {
34: "none",
35: "pending-additional",
36: "pending-answer",
37: "additional",
38: "glue",
39: "answer",
40: "authauthority",
41: "authanswer",
42: "secure",
43: "local" /* aka ultimate */
44: };
45:
46: const char *
47: dns_trust_totext(dns_trust_t trust) {
48: if (trust >= sizeof(trustnames)/sizeof(*trustnames))
49: return ("bad");
50: return (trustnames[trust]);
51: }
52:
53: void
54: dns_rdataset_init(dns_rdataset_t *rdataset) {
55:
56: /*
57: * Make 'rdataset' a valid, disassociated rdataset.
58: */
59:
60: REQUIRE(rdataset != NULL);
61:
62: rdataset->magic = DNS_RDATASET_MAGIC;
63: rdataset->methods = NULL;
64: ISC_LINK_INIT(rdataset, link);
65: rdataset->rdclass = 0;
66: rdataset->type = 0;
67: rdataset->ttl = 0;
68: rdataset->trust = 0;
69: rdataset->covers = 0;
70: rdataset->attributes = 0;
71: rdataset->count = ISC_UINT32_MAX;
72: rdataset->private1 = NULL;
73: rdataset->private2 = NULL;
74: rdataset->private3 = NULL;
75: rdataset->privateuint4 = 0;
76: rdataset->private5 = NULL;
77: rdataset->private6 = NULL;
78: rdataset->private7 = NULL;
79: rdataset->resign = 0;
80: }
81:
82: void
83: dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
84:
85: /*
86: * Invalidate 'rdataset'.
87: */
88:
89: REQUIRE(DNS_RDATASET_VALID(rdataset));
90: REQUIRE(rdataset->methods == NULL);
91:
92: rdataset->magic = 0;
93: ISC_LINK_INIT(rdataset, link);
94: rdataset->rdclass = 0;
95: rdataset->type = 0;
96: rdataset->ttl = 0;
97: rdataset->trust = 0;
98: rdataset->covers = 0;
99: rdataset->attributes = 0;
100: rdataset->count = ISC_UINT32_MAX;
101: rdataset->private1 = NULL;
102: rdataset->private2 = NULL;
103: rdataset->private3 = NULL;
104: rdataset->privateuint4 = 0;
105: rdataset->private5 = NULL;
106: }
107:
108: void
109: dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
110:
111: /*
112: * Disassociate 'rdataset' from its rdata, allowing it to be reused.
113: */
114:
115: REQUIRE(DNS_RDATASET_VALID(rdataset));
116: REQUIRE(rdataset->methods != NULL);
117:
118: (rdataset->methods->disassociate)(rdataset);
119: rdataset->methods = NULL;
120: ISC_LINK_INIT(rdataset, link);
121: rdataset->rdclass = 0;
122: rdataset->type = 0;
123: rdataset->ttl = 0;
124: rdataset->trust = 0;
125: rdataset->covers = 0;
126: rdataset->attributes = 0;
127: rdataset->count = ISC_UINT32_MAX;
128: rdataset->private1 = NULL;
129: rdataset->private2 = NULL;
130: rdataset->private3 = NULL;
131: rdataset->privateuint4 = 0;
132: rdataset->private5 = NULL;
133: rdataset->private6 = NULL;
134: }
135:
136: isc_boolean_t
137: dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
138: /*
139: * Is 'rdataset' associated?
140: */
141:
142: REQUIRE(DNS_RDATASET_VALID(rdataset));
143:
144: if (rdataset->methods != NULL)
145: return (ISC_TRUE);
146:
147: return (ISC_FALSE);
148: }
149:
150: static void
151: question_disassociate(dns_rdataset_t *rdataset) {
152: UNUSED(rdataset);
153: }
154:
155: static isc_result_t
156: question_cursor(dns_rdataset_t *rdataset) {
157: UNUSED(rdataset);
158:
159: return (ISC_R_NOMORE);
160: }
161:
162: static void
163: question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
164: /*
165: * This routine should never be called.
166: */
167: UNUSED(rdataset);
168: UNUSED(rdata);
169:
170: REQUIRE(0);
171: }
172:
173: static void
174: question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
175: *target = *source;
176: }
177:
178: static unsigned int
179: question_count(dns_rdataset_t *rdataset) {
180: /*
181: * This routine should never be called.
182: */
183: UNUSED(rdataset);
184: REQUIRE(0);
185:
186: return (0);
187: }
188:
189: static dns_rdatasetmethods_t question_methods = {
190: question_disassociate,
191: question_cursor,
192: question_cursor,
193: question_current,
194: question_clone,
195: question_count,
196: NULL, /* addnoqname */
197: NULL, /* getnoqname */
198: NULL, /* addclosest */
199: NULL, /* getclosest */
200: NULL, /* settrust */
201: NULL, /* expire */
202: NULL, /* clearprefetch */
203: NULL, /* setownercase */
204: NULL, /* getownercase */
205: NULL /* addglue */
206: };
207:
208: void
209: dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
210: dns_rdatatype_t type)
211: {
212:
213: /*
214: * Make 'rdataset' a valid, associated, question rdataset, with a
215: * question class of 'rdclass' and type 'type'.
216: */
217:
218: REQUIRE(DNS_RDATASET_VALID(rdataset));
219: REQUIRE(rdataset->methods == NULL);
220:
221: rdataset->methods = &question_methods;
222: rdataset->rdclass = rdclass;
223: rdataset->type = type;
224: rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
225: }
226:
227: unsigned int
228: dns_rdataset_count(dns_rdataset_t *rdataset) {
229:
230: /*
231: * Return the number of records in 'rdataset'.
232: */
233:
234: REQUIRE(DNS_RDATASET_VALID(rdataset));
235: REQUIRE(rdataset->methods != NULL);
236:
237: return ((rdataset->methods->count)(rdataset));
238: }
239:
240: void
241: dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
242:
243: /*
244: * Make 'target' refer to the same rdataset as 'source'.
245: */
246:
247: REQUIRE(DNS_RDATASET_VALID(source));
248: REQUIRE(source->methods != NULL);
249: REQUIRE(DNS_RDATASET_VALID(target));
250: REQUIRE(target->methods == NULL);
251:
252: (source->methods->clone)(source, target);
253: }
254:
255: isc_result_t
256: dns_rdataset_first(dns_rdataset_t *rdataset) {
257:
258: /*
259: * Move the rdata cursor to the first rdata in the rdataset (if any).
260: */
261:
262: REQUIRE(DNS_RDATASET_VALID(rdataset));
263: REQUIRE(rdataset->methods != NULL);
264:
265: return ((rdataset->methods->first)(rdataset));
266: }
267:
268: isc_result_t
269: dns_rdataset_next(dns_rdataset_t *rdataset) {
270:
271: /*
272: * Move the rdata cursor to the next rdata in the rdataset (if any).
273: */
274:
275: REQUIRE(DNS_RDATASET_VALID(rdataset));
276: REQUIRE(rdataset->methods != NULL);
277:
278: return ((rdataset->methods->next)(rdataset));
279: }
280:
281: void
282: dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
283:
284: /*
285: * Make 'rdata' refer to the current rdata.
286: */
287:
288: REQUIRE(DNS_RDATASET_VALID(rdataset));
289: REQUIRE(rdataset->methods != NULL);
290:
291: (rdataset->methods->current)(rdataset, rdata);
292: }
293:
294: #define MAX_SHUFFLE 32
295: #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
296: #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
297: #define WANT_CYCLIC(r) (((r)->attributes & DNS_RDATASETATTR_CYCLIC) != 0)
298:
299: struct towire_sort {
300: int key;
301: dns_rdata_t *rdata;
302: };
303:
304: static int
305: towire_compare(const void *av, const void *bv) {
306: const struct towire_sort *a = (const struct towire_sort *) av;
307: const struct towire_sort *b = (const struct towire_sort *) bv;
308: return (a->key - b->key);
309: }
310:
311: static isc_result_t
312: towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
313: dns_compress_t *cctx, isc_buffer_t *target,
314: dns_rdatasetorderfunc_t order, const void *order_arg,
315: isc_boolean_t partial, unsigned int options,
316: unsigned int *countp, void **state)
317: {
318: dns_rdata_t rdata = DNS_RDATA_INIT;
319: isc_region_t r;
320: isc_result_t result;
321: unsigned int i, count = 0, added, choice;
322: isc_buffer_t savedbuffer, rdlen, rrbuffer;
323: unsigned int headlen;
324: isc_boolean_t question = ISC_FALSE;
325: isc_boolean_t shuffle = ISC_FALSE, sort = ISC_FALSE;
326: isc_boolean_t want_random, want_cyclic;
327: dns_rdata_t in_fixed[MAX_SHUFFLE];
328: dns_rdata_t *in = in_fixed;
329: struct towire_sort out_fixed[MAX_SHUFFLE];
330: struct towire_sort *out = out_fixed;
331: dns_fixedname_t fixed;
332: dns_name_t *name;
333: isc_uint16_t offset;
334:
335: UNUSED(state);
336:
337: /*
338: * Convert 'rdataset' to wire format, compressing names as specified
339: * in cctx, and storing the result in 'target'.
340: */
341:
342: REQUIRE(DNS_RDATASET_VALID(rdataset));
343: REQUIRE(rdataset->methods != NULL);
344: REQUIRE(countp != NULL);
345: REQUIRE(cctx != NULL && cctx->mctx != NULL);
346:
347: want_random = WANT_RANDOM(rdataset);
348: want_cyclic = WANT_CYCLIC(rdataset);
349:
350: if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
351: question = ISC_TRUE;
352: count = 1;
353: result = dns_rdataset_first(rdataset);
354: INSIST(result == ISC_R_NOMORE);
355: } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
356: /*
357: * This is a negative caching rdataset.
358: */
359: unsigned int ncache_opts = 0;
360: if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
361: ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
362: return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
363: countp));
364: } else {
365: count = (rdataset->methods->count)(rdataset);
366: result = dns_rdataset_first(rdataset);
367: if (result == ISC_R_NOMORE)
368: return (ISC_R_SUCCESS);
369: if (result != ISC_R_SUCCESS)
370: return (result);
371: }
372:
373: /*
374: * Do we want to sort and/or shuffle this answer?
375: */
376: if (!question && count > 1 && rdataset->type != dns_rdatatype_rrsig) {
377: if (order != NULL) {
378: sort = ISC_TRUE;
379: }
380: if (want_random || want_cyclic) {
381: shuffle = ISC_TRUE;
382: }
383: }
384:
385: if ((shuffle || sort) && count > MAX_SHUFFLE) {
386: in = isc_mem_get(cctx->mctx, count * sizeof(*in));
387: out = isc_mem_get(cctx->mctx, count * sizeof(*out));
388: if (in == NULL || out == NULL)
389: shuffle = sort = ISC_FALSE;
390: }
391:
392: if (shuffle || sort) {
393: /*
394: * First we get handles to all of the rdata.
395: */
396: i = 0;
397: do {
398: INSIST(i < count);
399: dns_rdata_init(&in[i]);
400: dns_rdataset_current(rdataset, &in[i]);
401: i++;
402: result = dns_rdataset_next(rdataset);
403: } while (result == ISC_R_SUCCESS);
404: if (result != ISC_R_NOMORE)
405: goto cleanup;
406: INSIST(i == count);
407: }
408:
409: if (shuffle) {
410: if (want_random) {
411: /*
412: * 'Random' order.
413: */
414: for (i = 0; i < count; i++) {
415: isc_uint32_t val;
416:
417: isc_random_get(&val);
418: choice = i + (val % (count - i));
419: rdata = in[i];
420: in[i] = in[choice];
421: in[choice] = rdata;
422: if (order != NULL)
423: out[i].key = (*order)(&in[i],
424: order_arg);
425: else
426: out[i].key = 0; /* Unused */
427: out[i].rdata = &in[i];
428: }
429: } else if (want_cyclic) {
430: /*
431: * 'Cyclic' order.
432: */
433: isc_uint32_t val;
434: unsigned int j;
435:
436: val = rdataset->count;
437: if (val == ISC_UINT32_MAX)
438: isc_random_get(&val);
439: j = val % count;
440: for (i = 0; i < count; i++) {
441: if (order != NULL)
442: out[i].key = (*order)(&in[j],
443: order_arg);
444: else
445: out[i].key = 0; /* Unused */
446: out[i].rdata = &in[j];
447: j++;
448: if (j == count)
449: j = 0; /* Wrap around. */
450: }
451: }
452: } else if (sort) {
453: for (i = 0; i < count; i++) {
454: if (order != NULL)
455: out[i].key = (*order)(&in[i], order_arg);
456: else
457: out[i].key = 0; /* Unused */
458: out[i].rdata = &in[i];
459: }
460: }
461:
462: /*
463: * Sortlist order.
464: */
465: if (sort) {
466: qsort(out, count, sizeof(out[0]), towire_compare);
467: }
468:
469: savedbuffer = *target;
470: i = 0;
471: added = 0;
472:
473: name = dns_fixedname_initname(&fixed);
474: dns_name_copy(owner_name, name, NULL);
475: dns_rdataset_getownercase(rdataset, name);
476: offset = 0xffff;
477:
478: name->attributes |= owner_name->attributes &
479: DNS_NAMEATTR_NOCOMPRESS;
480:
481: do {
482: /*
483: * Copy out the name, type, class, ttl.
484: */
485:
486: rrbuffer = *target;
487: dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
488: result = dns_name_towire2(name, cctx, target, &offset);
489: if (result != ISC_R_SUCCESS)
490: goto rollback;
491: headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
492: if (!question)
493: headlen += sizeof(dns_ttl_t)
494: + 2; /* XXX 2 for rdata len */
495: isc_buffer_availableregion(target, &r);
496: if (r.length < headlen) {
497: result = ISC_R_NOSPACE;
498: goto rollback;
499: }
500: isc_buffer_putuint16(target, rdataset->type);
501: isc_buffer_putuint16(target, rdataset->rdclass);
502: if (!question) {
503: isc_buffer_putuint32(target, rdataset->ttl);
504:
505: /*
506: * Save space for rdlen.
507: */
508: rdlen = *target;
509: isc_buffer_add(target, 2);
510:
511: /*
512: * Copy out the rdata
513: */
514: if (shuffle || sort) {
515: rdata = *(out[i].rdata);
516: } else {
517: dns_rdata_reset(&rdata);
518: dns_rdataset_current(rdataset, &rdata);
519: }
520: result = dns_rdata_towire(&rdata, cctx, target);
521: if (result != ISC_R_SUCCESS)
522: goto rollback;
523: INSIST((target->used >= rdlen.used + 2) &&
524: (target->used - rdlen.used - 2 < 65536));
525: isc_buffer_putuint16(&rdlen,
526: (isc_uint16_t)(target->used -
527: rdlen.used - 2));
528: added++;
529: }
530:
531: if (shuffle || sort) {
532: i++;
533: if (i == count)
534: result = ISC_R_NOMORE;
535: else
536: result = ISC_R_SUCCESS;
537: } else {
538: result = dns_rdataset_next(rdataset);
539: }
540: } while (result == ISC_R_SUCCESS);
541:
542: if (result != ISC_R_NOMORE)
543: goto rollback;
544:
545: *countp += count;
546:
547: result = ISC_R_SUCCESS;
548: goto cleanup;
549:
550: rollback:
551: if (partial && result == ISC_R_NOSPACE) {
552: INSIST(rrbuffer.used < 65536);
553: dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
554: *countp += added;
555: *target = rrbuffer;
556: goto cleanup;
557: }
558: INSIST(savedbuffer.used < 65536);
559: dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
560: *countp = 0;
561: *target = savedbuffer;
562:
563: cleanup:
564: if (out != NULL && out != out_fixed)
565: isc_mem_put(cctx->mctx, out, count * sizeof(*out));
566: if (in != NULL && in != in_fixed)
567: isc_mem_put(cctx->mctx, in, count * sizeof(*in));
568: return (result);
569: }
570:
571: isc_result_t
572: dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
573: const dns_name_t *owner_name,
574: dns_compress_t *cctx,
575: isc_buffer_t *target,
576: dns_rdatasetorderfunc_t order,
577: const void *order_arg,
578: unsigned int options,
579: unsigned int *countp)
580: {
581: return (towiresorted(rdataset, owner_name, cctx, target,
582: order, order_arg, ISC_FALSE, options,
583: countp, NULL));
584: }
585:
586: isc_result_t
587: dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
588: const dns_name_t *owner_name,
589: dns_compress_t *cctx,
590: isc_buffer_t *target,
591: dns_rdatasetorderfunc_t order,
592: const void *order_arg,
593: unsigned int options,
594: unsigned int *countp,
595: void **state)
596: {
597: REQUIRE(state == NULL); /* XXX remove when implemented */
598: return (towiresorted(rdataset, owner_name, cctx, target,
599: order, order_arg, ISC_TRUE, options,
600: countp, state));
601: }
602:
603: isc_result_t
604: dns_rdataset_towire(dns_rdataset_t *rdataset,
605: const dns_name_t *owner_name,
606: dns_compress_t *cctx,
607: isc_buffer_t *target,
608: unsigned int options,
609: unsigned int *countp)
610: {
611: return (towiresorted(rdataset, owner_name, cctx, target,
612: NULL, NULL, ISC_FALSE, options, countp, NULL));
613: }
614:
615: isc_result_t
616: dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
617: dns_additionaldatafunc_t add, void *arg)
618: {
619: dns_rdata_t rdata = DNS_RDATA_INIT;
620: isc_result_t result;
621:
622: /*
623: * For each rdata in rdataset, call 'add' for each name and type in the
624: * rdata which is subject to additional section processing.
625: */
626:
627: REQUIRE(DNS_RDATASET_VALID(rdataset));
628: REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
629:
630: result = dns_rdataset_first(rdataset);
631: if (result != ISC_R_SUCCESS)
632: return (result);
633:
634: do {
635: dns_rdataset_current(rdataset, &rdata);
636: result = dns_rdata_additionaldata(&rdata, add, arg);
637: if (result == ISC_R_SUCCESS)
638: result = dns_rdataset_next(rdataset);
639: dns_rdata_reset(&rdata);
640: } while (result == ISC_R_SUCCESS);
641:
642: if (result != ISC_R_NOMORE)
643: return (result);
644:
645: return (ISC_R_SUCCESS);
646: }
647:
648: isc_result_t
649: dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
650:
651: REQUIRE(DNS_RDATASET_VALID(rdataset));
652: REQUIRE(rdataset->methods != NULL);
653: if (rdataset->methods->addnoqname == NULL)
654: return (ISC_R_NOTIMPLEMENTED);
655: return((rdataset->methods->addnoqname)(rdataset, name));
656: }
657:
658: isc_result_t
659: dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
660: dns_rdataset_t *neg, dns_rdataset_t *negsig)
661: {
662: REQUIRE(DNS_RDATASET_VALID(rdataset));
663: REQUIRE(rdataset->methods != NULL);
664:
665: if (rdataset->methods->getnoqname == NULL)
666: return (ISC_R_NOTIMPLEMENTED);
667: return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
668: }
669:
670: isc_result_t
671: dns_rdataset_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
672:
673: REQUIRE(DNS_RDATASET_VALID(rdataset));
674: REQUIRE(rdataset->methods != NULL);
675: if (rdataset->methods->addclosest == NULL)
676: return (ISC_R_NOTIMPLEMENTED);
677: return((rdataset->methods->addclosest)(rdataset, name));
678: }
679:
680: isc_result_t
681: dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
682: dns_rdataset_t *neg, dns_rdataset_t *negsig)
683: {
684: REQUIRE(DNS_RDATASET_VALID(rdataset));
685: REQUIRE(rdataset->methods != NULL);
686:
687: if (rdataset->methods->getclosest == NULL)
688: return (ISC_R_NOTIMPLEMENTED);
689: return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
690: }
691:
692: void
693: dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
694: REQUIRE(DNS_RDATASET_VALID(rdataset));
695: REQUIRE(rdataset->methods != NULL);
696:
697: if (rdataset->methods->settrust != NULL)
698: (rdataset->methods->settrust)(rdataset, trust);
699: else
700: rdataset->trust = trust;
701: }
702:
703: void
704: dns_rdataset_expire(dns_rdataset_t *rdataset) {
705: REQUIRE(DNS_RDATASET_VALID(rdataset));
706: REQUIRE(rdataset->methods != NULL);
707:
708: if (rdataset->methods->expire != NULL)
709: (rdataset->methods->expire)(rdataset);
710: }
711:
712: void
713: dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
714: REQUIRE(DNS_RDATASET_VALID(rdataset));
715: REQUIRE(rdataset->methods != NULL);
716:
717: if (rdataset->methods->clearprefetch != NULL)
718: (rdataset->methods->clearprefetch)(rdataset);
719: }
720:
721: void
722: dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
723: REQUIRE(DNS_RDATASET_VALID(rdataset));
724: REQUIRE(rdataset->methods != NULL);
725:
726: if (rdataset->methods->setownercase != NULL)
727: (rdataset->methods->setownercase)(rdataset, name);
728: }
729:
730: void
731: dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
732: REQUIRE(DNS_RDATASET_VALID(rdataset));
733: REQUIRE(rdataset->methods != NULL);
734:
735: if (rdataset->methods->getownercase != NULL)
736: (rdataset->methods->getownercase)(rdataset, name);
737: }
738:
739: void
740: dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
741: dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
742: isc_boolean_t acceptexpired)
743: {
744: isc_uint32_t ttl = 0;
745:
746: REQUIRE(DNS_RDATASET_VALID(rdataset));
747: REQUIRE(DNS_RDATASET_VALID(sigrdataset));
748: REQUIRE(rrsig != NULL);
749:
750: /*
751: * If we accept expired RRsets keep them for no more than 120 seconds.
752: */
753: if (acceptexpired &&
754: (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
755: isc_serial_le(rrsig->timeexpire, now)))
756: ttl = 120;
757: else if (isc_serial_ge(rrsig->timeexpire, now))
758: ttl = rrsig->timeexpire - now;
759:
760: ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
761: ISC_MIN(rrsig->originalttl, ttl));
762: rdataset->ttl = ttl;
763: sigrdataset->ttl = ttl;
764: }
765:
766: isc_result_t
767: dns_rdataset_addglue(dns_rdataset_t *rdataset,
768: dns_dbversion_t *version,
769: unsigned int options,
770: dns_message_t *msg)
771: {
772: REQUIRE(DNS_RDATASET_VALID(rdataset));
773: REQUIRE(rdataset->methods != NULL);
774: REQUIRE(rdataset->type == dns_rdatatype_ns);
775:
776: if (rdataset->methods->addglue == NULL)
777: return (ISC_R_NOTIMPLEMENTED);
778:
779: return ((rdataset->methods->addglue)(rdataset, version,
780: options, msg));
781: }
CVSweb <webmaster@jp.NetBSD.org>